출처 : 리눅스 커널 프로그래밍 저 한동훈,원일용, 하홍준 / 한빛 미디어
callee 모듈에서 add()와 sub() 함수를 제공하고, caller 모듈에서 add()와 sub() 함수를 호출하는 예제를 작성해보겠습니다.
2.4 커널과 2.6 커널 프로그램의 차이점을 이미 설명했기 떄문에 여기서는 2.6 소스코드만 설명하겟습니다. 2.4.20 이후의 커널이라면 2.6 커널 모듈과 같은 방식을 사용할 수 있기 때문에 2.6 커널 모듈의 소스 코드를 그대로 컴파일해도 됩니다.
- 참고 -
2.4.20 이후 버전은 module_init(), module_exit() 매크로를 사용할 수 있으며, init.h 파일도 모듈에 선언할 수 있습니다. 2.4.20 이후 버전과 2.6 버전 모듈의 차이점은 사용할 수 있는 커널 API와 빌드 과정이 다르다는 점 뿐입니다. 다만 대부분의 커널 관련 도서나 자료들이 2.4.18 이전 버전, 심지어 2.2.나 2.0시절에 작성된것을 그대로 답습하다보니 2.4.20 이후 버전의 커널 소스에서도 사용하지 않는 init_moudule()과 cleanup_module()에 대해 설명하며 2.6과의 차이라고 잘못 설명하고 있는 겁니다.-
--
calle 모듈 작성
callee.c
caller.c
2.4 컴파일은 다음과 같습니다.
2.6 커널에서 callee와 caller 모듈을 컴파일 하기 위한 Makefile은 다음과 같습니다.
callee와 caller 빌드용 Makefile
# lsmod
callee 모듈에서 add()와 sub() 함수를 제공하고, caller 모듈에서 add()와 sub() 함수를 호출하는 예제를 작성해보겠습니다.
2.4 커널과 2.6 커널 프로그램의 차이점을 이미 설명했기 떄문에 여기서는 2.6 소스코드만 설명하겟습니다. 2.4.20 이후의 커널이라면 2.6 커널 모듈과 같은 방식을 사용할 수 있기 때문에 2.6 커널 모듈의 소스 코드를 그대로 컴파일해도 됩니다.
- 참고 -
2.4.20 이후 버전은 module_init(), module_exit() 매크로를 사용할 수 있으며, init.h 파일도 모듈에 선언할 수 있습니다. 2.4.20 이후 버전과 2.6 버전 모듈의 차이점은 사용할 수 있는 커널 API와 빌드 과정이 다르다는 점 뿐입니다. 다만 대부분의 커널 관련 도서나 자료들이 2.4.18 이전 버전, 심지어 2.2.나 2.0시절에 작성된것을 그대로 답습하다보니 2.4.20 이후 버전의 커널 소스에서도 사용하지 않는 init_moudule()과 cleanup_module()에 대해 설명하며 2.6과의 차이라고 잘못 설명하고 있는 겁니다.-
--
calle 모듈 작성
callee.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
//모듈 초기화 루틴
int __init init_callee(void)
{
return 0;
}
//모듈 종료 루틴
void __exit exit_callee(void)
{
}
int add( int a, int b) //-> 커널 심볼로 공개시킬 함수입니다.
{
printk(KERN_ALERT "[callee Module] add called...\n");
return a + b;
}
int sub(int a, int b) // -> 커널 심볼로 공개시킬 함수입니다.
{
printk(KERN_ALERT "[callee Module] sub called...\n");
return a - b;
}
EXPORT_SYMBOL(add); //
EXPORT_SYMBOL(sub); // => 심볼로 공개 2.6 커널에만 해당, 2.4 커널에서는 제거합니다.
module_init(init_callee);
module_exit(exit_calle);
MODULE_LICENSE("GPL");
#include <linux/kernel.h>
#include <linux/module.h>
//모듈 초기화 루틴
int __init init_callee(void)
{
return 0;
}
//모듈 종료 루틴
void __exit exit_callee(void)
{
}
int add( int a, int b) //-> 커널 심볼로 공개시킬 함수입니다.
{
printk(KERN_ALERT "[callee Module] add called...\n");
return a + b;
}
int sub(int a, int b) // -> 커널 심볼로 공개시킬 함수입니다.
{
printk(KERN_ALERT "[callee Module] sub called...\n");
return a - b;
}
EXPORT_SYMBOL(add); //
EXPORT_SYMBOL(sub); // => 심볼로 공개 2.6 커널에만 해당, 2.4 커널에서는 제거합니다.
module_init(init_callee);
module_exit(exit_calle);
MODULE_LICENSE("GPL");
2.6 커널에서는 커널 심볼로 공개하기 위해 반드시 EXPORT_SYMBOL()을 사용해야 합니다. 2.4 커널에서 위 모듈을 빌드라하면 EXPORT_SYMBOL() 부분만 제거하면 됩니다.
2.4.20 이후 버전의 커널,2.4.32 버전의 커널을 사용하고 있다면 다음과 같이 빌드 할 수 있다. 2.6 에서는 kbuild 시스템을 사용해야 합니다.
2.4.20 이후 버전의 커널,2.4.32 버전의 커널을 사용하고 있다면 다음과 같이 빌드 할 수 있다. 2.6 에서는 kbuild 시스템을 사용해야 합니다.
gcc -D__KERNEL__ -DMODULE -I/usr/src/linux-2.4.32/include -c callee.c -o callee.o
caller.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
int add(int, int);
int sub(int, int);
int __init init_caller(void)
{
printk(KERN_ALERT "[caller Module] I'll call add(), sub() from caller. \n");
┌callee 모듈의 add를 호출합니다.
printk(KERN_ALERT "[caller Module] I'll call add: %d\n", add(3,2) );
printk(KERN_ALERT "[caller Module] I'll call sub: %d\n", sub(3,2) );
└callee 모듈의 sub를 호출합니다.
return 0;
}
void __exit exit_caller(void)
{
}
module_init(init_caller);
module_exit(exit_caller);
MOUDLE_LICENSE("GPL");
#include <linux/kernel.h>
#include <linux/module.h>
int add(int, int);
int sub(int, int);
int __init init_caller(void)
{
printk(KERN_ALERT "[caller Module] I'll call add(), sub() from caller. \n");
┌callee 모듈의 add를 호출합니다.
printk(KERN_ALERT "[caller Module] I'll call add: %d\n", add(3,2) );
printk(KERN_ALERT "[caller Module] I'll call sub: %d\n", sub(3,2) );
└callee 모듈의 sub를 호출합니다.
return 0;
}
void __exit exit_caller(void)
{
}
module_init(init_caller);
module_exit(exit_caller);
MOUDLE_LICENSE("GPL");
2.4 컴파일은 다음과 같습니다.
gcc -D__KERNEL__ -DMODULE -I/usr/src/linux-2.4.32/include -c caller.c -o caller.o
2.6 커널에서 callee와 caller 모듈을 컴파일 하기 위한 Makefile은 다음과 같습니다.
callee와 caller 빌드용 Makefile
KERNELDIR = /lib/modules/$ (shell uname -r) /build
obj-m = calle.o caller.o ->컴파일할 모듈을 지정합니다.
KDIR := /lib/modules/$ (shell uname -r) /build
PWD := $(shell pwd)
default :
obj-m = calle.o caller.o ->컴파일할 모듈을 지정합니다.
KDIR := /lib/modules/$ (shell uname -r) /build
PWD := $(shell pwd)
default :
$ (MAKE) -C $ (KDIR) SUBDIRS=$(PWD) modules
모듈 빌드가 끝낫으면 모듈을 커널 영역에 로드하겠습니다.
# insmod callee.ko
# insmod caller.ko
[caller Module] I'll call add(), sub() from caller.
[caller Module] add called ...
[caller Module] add: 5
[caller Module] sub called ...
[caller Module] sub: 1
[caller Module] I'll call add(), sub() from caller.
[caller Module] add called ...
[caller Module] add: 5
[caller Module] sub called ...
[caller Module] sub: 1
결과에서 처럼 볼 수 있는 것처럼 callee 모듈을 로드하고, caller 모듈에서 caller 모듈 함수를 참조하는 것을 알 수 있습니다. [lsmod]명령을 사용하면 모듈이 사용되고 있음을 확인할 수 있습니다
# lsmod
'linux' 카테고리의 다른 글
프로세스 이미지 대체하기 (0) | 2010.08.15 |
---|---|
새 프로세스 시작하기 (0) | 2010.08.15 |
프로세스 일정 관리 (0) | 2010.08.14 |
프로세스와 신호 (0) | 2010.08.13 |
vim 설정 (0) | 2010.06.30 |
모듈에 대해 알아야 할것들 (0) | 2010.06.03 |
Hello 커널 모듈 작성 예제 (0) | 2010.06.02 |
모듈 개발. (0) | 2010.06.01 |
운영체제 커널 분류에대해... (0) | 2010.06.01 |
커널 소스 컴파일 (0) | 2010.06.01 |