<리눅스 커널 2. 6 기준>
static 변수 선언하고, 함수들도 static 함수를 선언한다. 그래서, 외부 커널모둘에서 해당 모듈에 영향을 주지 못하게 할 수 있다.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int hello_init(void) {
printk("hello init\n");
return 0;
}
static void hello_exit(void) {
printk("hello exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");
1) 커널 디렉토리 밑으로 가야 컴파일 된다.
그냥 컴파일하면 에러 발생
[root@linux2 hello_mod]# gcc hello_mod.c
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../crt1.o(.text+0x18): In function `_start':: undefined reference to `main'
/tmp/cceO6qIX.o(.text+0xf): In function `hello_init':
hello_mod.c: undefined reference to `printk'
/tmp/cceO6qIX.o(.text+0x2c): In function `hello_exit':
hello_mod.c: undefined reference to `printk'
collect2: ld returned 1 exit status
makeFile 파일를 만들자.
PWD := $(shell pwd)
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.ko
rm -rf *.mod.*
rm -rf .*.cmd
rm -rf *.o
<참고 사항>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_LICENSE 삭제하면.. 에러가 발생한다.
[root@linux2 test]# make
make -C /lib/modules/2.6.11-1.1369_FC4/build SUBDIRS=/mnt/hgfs/shared/Module_2426_new_st/test modules
make[1]: Entering directory `/usr/src/kernels/2.6.11-1.1369_FC4-i686'
CC [M] /mnt/hgfs/shared/Module_2426_new_st/test/test.o
/mnt/hgfs/shared/Module_2426_new_st/test/test.c:17:2: error: invalid preprocessing directive #MODULE_LICENSE
make[2]: *** [/mnt/hgfs/shared/Module_2426_new_st/test/test.o] 오류 1
make[1]: *** [_module_/mnt/hgfs/shared/Module_2426_new_st/test] 오류 2
make[1]: Leaving directory `/usr/src/kernels/2.6.11-1.1369_FC4-i686'
make: *** [default] 오류 2
관련 내용은 아래 참조 : http://askville.amazon.com/MODULE_LICENSE-work-Linux-kernel/AnswerViewer.do?requestId=2639289
2) 컴파일하면, o 파일과 ko 파일이 발생하고, insmod써서 올린다.
[root@linux2 hello_mod]# make
make -C /lib/modules/2.6.11-1.1369_FC4/build SUBDIRS=/mnt/hgfs/shared/Module_2426_new_st/v26_host/hello_mod modules
make[1]: Entering directory `/usr/src/kernels/2.6.11-1.1369_FC4-i686'
CC [M] /mnt/hgfs/shared/Module_2426_new_st/v26_host/hello_mod/hello_mod.o
/mnt/hgfs/shared/Module_2426_new_st/v26_host/hello_mod/hello_mod.c:20: warning: function declaration isn’t a prototype
/mnt/hgfs/shared/Module_2426_new_st/v26_host/hello_mod/hello_mod.c:26: warning: function declaration isn’t a prototype
Building modules, stage 2.
MODPOST
CC /mnt/hgfs/shared/Module_2426_new_st/v26_host/hello_mod/hello_mod.mod.o
LD [M] /mnt/hgfs/shared/Module_2426_new_st/v26_host/hello_mod/hello_mod.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.11-1.1369_FC4-i686'
[root@linux2 hello_mod]# insmod hello_mod.ko
반드시 ko 파일명을 써야 한다.
3) 커널 모듈이 정상적으로 리눅스 커널로 확인하는 법
[root@linux2 hello_mod]# dmesg | tail -n 1
Hello Module id Loaded ....
[root@linux2 hello_mod]# lsmod | grep hello
hello_mod 1664 0
제거하기
[root@linux2 hello_mod]# rmmod hello_mod.ko
[root@linux2 hello_mod]# dmesg | tail -n 1
Hello Module is Unloaded ....
[root@linux2 hello_mod]# lsmod | grep hello
결과 없음
ko 확장자 없이 rmod hello_mod 해도 결과는 동일하다.
4) 커널 심볼 정보에서 리눅스에 올린 커널 모듈 확인하는 방법
[root@linux2 proc]# cat kallsyms | grep hello
00000000 a hello_mod.c [hello_mod]
caad50a0 ? __mod_license33 [hello_mod]
00000000 a hello_mod.mod.c [hello_mod]
caad50c0 ? __mod_vermagic5 [hello_mod]
ca97d080 r ____versions [hello_mod]
caad50f8 ? __module_depends [hello_mod]
caad5120 ? __mod_srcversion30 [hello_mod]
ca97d480 d __this_module [hello_mod]
ca97d015 t cleanup_module [hello_mod]
ca97d000 t init_module [hello_mod]
ca97d000 t hello_init [hello_mod]
c012172d U printk [hello_mod]
ca97d015 t hello_exit [hello_mod]
의미..
hello_init 의 메모리 주소
ca97d000
hello_exit 의 메모리 주소
ca97d015
타입정보에서 소문자이면, 내부에서만 사용된다는 의미이다.
d : 내부 전역 (static)
t : 내부 함수 (static)
만약 전역변수로 되게 하려면. 어떻게 해야 하지?
int num = 5;
EXPORT_SYMBOL(num);
kallsyms를 보면 확인가능
D : 전역 변수 (static 제외)
* 기타
값 초기화 하면, data 영역으로
값 초기화 안하면, bss 영역으로
'c or linux' 카테고리의 다른 글
minicom을 이용하여 이미지 굽기(fusing) (0) | 2011.04.19 |
---|---|
리눅스 커널 컴파일시 타켓 커널 위치를 넣는 게 중요 (0) | 2011.04.19 |
c header 파일 (0) | 2011.04.18 |
표준 출력을 fwrite, write로 구현하기 (0) | 2011.04.18 |
cpulimit - cpu 사용량을 정한다. (0) | 2011.03.29 |