[임베디드 시스템] Module programming
이번 시간에는 kernel 의 뉴런같은 존재라고도 할 수 있는 module 에 대해서 정리해보고자한다. module은 kernel을 dynamic 하게 기능을 추가할 수 있게 해준다.
Module
Module
- 기존 커널의 문제점
- kernel은 기능을 추가하거나, 제거할 때 recompile + 재부팅해야한다는 귀찮음이 존재함
- 또, 거의 쓰이지 않는 기능이 다닥다닥 붙어서 전체 퍼포먼스에 악영향을 끼친다.
- 이 문제를 해결하고자 dynamic 하게 runtime때 기능을 할당해보자! 라는 컨셉이 module programming!
- What is Module?
- functional unit such as file system or driver!
- 필요에 따라 kernel에 dynamic linking 할 수 있다.(마치 dll(dynamic linking library)
- 커널에 load된 module은 커널로 간주함!~
- insmod / rmmod 명령어를 통해 커널에 linking / unlinking한다.
그림1 module |
- module 구조(그림1을 보자!)
- static
- static이 선언된 variable은 다른 module이 접근할 수 없다.
- default상태는 global상태로, 다른 모듈에서 이 variable을 접근할 수 있다.
- 예를 들어 a.c(testA(), testD() )와 b.c(testB(), testC) 모듈이 있다고 하자, 링킹시 testA, testD에서 testB()를 접근할 수 있는게 원칙이나, static이 선언되었다면 call할 수 없다.
- 추가로, a.c와 b.c가 동일한 네이밍의 testD()함수를 가진다고 하자, linking시 이 함수를 구분할 수 없어 에러가 발생하게 된다.
- module_init, module_exit
- module_init은 insmod시 호출되는 녀석이다. 최초 실행되는 녀석
- module_exit은 rmmod시 호출되는 녀석이다. 최후에 실행되는 녀석
그림2 module compile |
- module compile
- 기회가 될때 makefile문법 제대로 배워서 정리하자
- 모듈을 컴파일할때에는 사용하는 커널 위에서 컴파일해야 한다.(에러방지)
- 모듈 버전 = 커널 버전이어야.
- .ko
- .c의 모듈은 컴파일되면 .o가 아닌 .ko라는 것 잘 기억하자
- .ko가 모듈의 obj 파일임!!
- Loading module
- Manual loading
- insmod, rmmod로 사용
- On-demand loading
- 커널이 자동적으로 로딩함
- 데몬이 이 역할을 수행함
- 그림 3을 보자.
- fat.ko라는 파일시스템 모듈을 manual하게 했을 때와 on-demand하게 했을 때의 구성이다.
- on-demand에서, mount명령어를 통해서 msdos의 file system을 가지는 파일구조를 mounting시켰기 때문에 해당하는 모듈인 msdos, fat이 당연히 호출되어야함. 이 과정은 데몬이 수행함.
그림3 /proc/modules |
- Exporting Symbols
- kernel symbol table에는 kernel 내 module의 정보가 저장되어 있다.
- 이 symbol table을 통해 module을 읽어와서 사용하는 것이다.
- EXPORT_SYMBOL(name) 명령어를 통해 모듈에서는 모듈을 symbol table에 업로드한다.
- EXPORT_SYMBOL_GPL(name)
- EXPORT_NO_SYMBOLS ->모듈을 모조리 가린다.
그림4 /proc/kallsyms |
- GPL license
- MODULE_LICENSE("GPL") 을 통해 라이센스 선언한다. 사실상 insmod된 모듈이 kernel의 모듈들을 사용하기 위해선, 본인 역시 사용당할 수 있게 선언해야 하는 것이다.
- EXPORT_SYMBOL_GPL(name)으로 export시 선언하지 않은 모듈들에게 가려진다.
- Module Dependency
- AA 모듈에 있는 함수를 BB 모듈에서 call한다고 생각해보자. 이 경우 AA와 BB는 module dependency가 있다고 한다.
- AA는 BB위에서 loading되어야 한다. 즉, AA가 insmod되기 전에 BB를 insmod할 수 없다. 또, BB를 rmmod하기 전에 AA를 rmmod 할 수 없다.
- usage_counter을 통해 이를 제어한다. 즉 BB가 AA를 사용시, AA의 usage_counter이 증가하고, AA는 rmmod가 불가능하다. BB가 사라지면, AA의 usage_counter이 0으로 바뀌고, 그때서야 AA는 rmmod가 가능하다.
댓글
댓글 쓰기