<리눅스 커널 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 파일를 만들자.

obj-m   := hello_mod.o
KDIR    := /lib/modules/$(shell uname -r)/build
PWD     := $(shell pwd)
default:
        $(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 영역으로

Posted by '김용환'
,