리눅스마스터1급 : 매커니즘 모듈(Modules)-커널모듈의 개요
작성자 정보
- 관리자 작성
- 작성일
컨텐츠 정보
- 1,182 조회
- 0 추천
- 목록
본문
리눅스마스터1급 : 매커니즘 모듈(Modules)-커널모듈의 개요
모듈의 개요
리눅스는 단일(monolithic) 커널이다.
즉, 커널의 모든 기능적인 요소들이 자신의 내부 자료 구조와 함수들에 모두 접근할 수 있는 하나의 거대한 프로그램이다.
운영체제 설계의 다른 방법으로는 커널의 각 기능적인 부분들이 별도의 단위로 쪼개지고, 그 사이에 엄격한 통신 매커니즘으로 연결되는 마이크로커널(micro-kernel) 구조가 있다.
이는 시간이 소모되는 프로세스가 아닌 환경 설정 프로세스를 통하여 새로운 컴포넌트를 커널에 추가할 수 있다.
커널에 새로운 컴포넌트를 추가하기 위한 방법으로는 크게 둘로 나누어진다.
첫째로, 커널 설정을 바꾸고 다시 컴파일하는 것이다.
예를 들면 사용자가 NCR 810 SCSI용 드라이버를 사용하려고 하는데, 이것이 커널에 포함되어 있지 않을 경우 커널의 설정을 바꾸고 다시 컴파일함으로써 NCR 810 SCSI를 사용할 수 있다.
두 번째 방법으로는 운영체제를 구성하는 컴포넌트들을 필요로 할 때마다 동적으로 로드 또는 언로드하는 것이다.
리눅스 모듈은 시스템이 부팅이 된 후 언제라도 커널에 동적으로 링크될 수 있는 코드 덩어리이다.
또한 모듈이 더 이상 필요하지 않을 때는 커널과의 연결을 해제하고 제거할 수 있다.
리눅스 커널의 상당수는 디바이스 드라이버와 네트워크 드라이버나 파일 시스템 같은 유사 디바이스 드라이버(pseudo device driver)이다.
사용자는 insmod, modprobe 및 rmmod와 같은 명령으로 리눅스 커널 모듈을 명확하게 로드 또는 언로드를 할 수 있으며, 커널 자신이 필요로 할 때 커널 데몬(kernel daemon)에게 모듈을 로드 또는 언로드할 것을 요구할 수 있다.
필요로 할 때 코드를 동적으로 로드하는 것은 커널 크기를 최소화할 수 있고, 커널을 매우 유연하게 할 수 있어 매력적이다.
모듈은 또한 새로운 커널 코드를 다시 컴파일하고 커널을 재부팅하지 않고 테스트를 해 보고자 할 때 유용하다.
물론 커널 모듈과 관련하여 성능과 메모리에서 약간의 손해가 있기는 하지만, 이것은 모듈을 로드할 수 있도록 모듈이 제공해야 하는 약간의 코드가 있고 별도의 자료 구조가 메모리를 조금 차지하기 때문이다.
또한 커널 자원에 접근할 때 한 단계를 거쳐야 하므로 모듈의 효율성이 아주 조금 떨어지게 된다.
로드된 리눅스 모듈은 다른 보통 커널 코드처럼 커널의 한 부분이 된다.
모듈은 커널 코드와 똑같은 권한과 책임을 진다.
다르게 말하면, 리눅스 커널 모듈은 모든 커널 코드나 디바이스 드라이버처럼 커널을 망가뜨릴 수도 있다.
모듈이 자신이 필요로 할 때 커널의 자원을 사용할 수 있으려면, 그것이 어디 있는지 찾을 수 있어야 한다.
가령 모듈이 커널 메모리를 할당하는 함수인 kmalloc()을 호출해야 한다고 하자. 모듈을 컴파일할 때에는 메모리의 어느 위치에 kmalloc()이 있는지 모르므로 모듈이 로드될 때 커널은 모듈이 제대로 작동할 수 있도록 kmalloc()에 대한 참조를 맞춰주어야 한다.
커널은 커널의 모든 자원의 목록을 커널의 심볼 테이블(symbol table)로 관리하며, 이를 이용해 모듈이 로드될 때 이들 자원에 대한 참조를 해결할 수 있다.
리눅스는 한 모듈이 다른 모듈의 서비스를 필요로 하는 경우, 모듈이 층층이 쌓아질 수 있도록 한다.
예를 들어 VFAT 파일 시스템 모듈은 FAT 파일 시스템 모듈의 서비스를 필요로 한다.
이는 VFAT 파일 시스템이 FAT 파일 시스템을 다소 확장한 것이기 때문이다.
이렇게 한 모듈이 다른 모듈이 제공하는 서비스나 자원을 필요로 하는 것은 모듈이 커널 자체의 서비스와 자원을 필요로 하는 경우와 매우 비슷하다.
단지 여기서 필요로 하는 서비스가 다른 이전에 로드된 모듈에 있는 것일 뿐이다.
각 모듈이 로드될 때, 커널은 새로 로드되는 모듈에서 외부로 보여주는 자원과 심볼을 모두 커널 심볼 테이블에 추가한다.
이는 다음에 로드되는 모듈이 이미 로드된 모듈의 서비스를 이용할 수 있도록 하기 위한 것이다.
모듈을 언로드하려 할 때 커널은 모듈이 현재 사용되고 있는지 아니면 그렇지 않은지 알아야 하며, 모듈에게 자신이 언로드되려고 한다는 것을 알려줄 수 있어야 한다.
이렇게 해서 모듈은 커널에서 제거될 때, 자신이 할당받은 커널 메모리나 인터럽트같은 시스템 자원을 해제할 수 있다.
모듈이 언로드될 때 커널은 모듈이 커널 심볼 테이블에 추가한 심볼들을 모두 제거한다.
로드된 모듈이 잘못 만들어진 것이어서 운영체제를 망가뜨릴 가능성과는 별도로, 다른 위험 가능성이 있다.
만약 지금 실행하고 있는 커널보다 이전 버전이나 이후 버전용으로 컴파일 된 모듈을 로드하려고 한다면 어떻게 될까? 모듈이 커널 루틴을 호출할 때 잘못된 인자를 넘겨준다면 문제가 생길 수 있을 것이다.
커널은 모듈을 로드할 때 엄격한 버전 검사를 하여 이런 문제를 선택적으로 막을 수 있다.
관련자료
-
이전
-
다음