모듈 예제
//Makefile
CC := gcc # Compiler 'gcc'
obj-m := mod_score.o mod_man.o # Make moduler object file
KDIR := /usr/src/linux-headers-3.11.0-15-generic # Set Kernel dir
PWD := $(shell pwd) # Set Source dir
#default target
default :
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean :
rm -f *.ko # kernel src
rm -f *.o # obj src
rm -f *.mod.* # mod src
rm -f .*.cmd # hidden src
~
// mod.score.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
int score_value;
void score_kor(void){
printk(KERN_INFO "Korea Score = %d\n", score_value);
}
int score_init(void){
printk(KERN_INFO "Hello Score\n");
score_value = 100;
return 0;
}
void score_exit(void){
printk(KERN_INFO "Bye Score\n");
}
module_init(score_init);
module_exit(score_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jeong Been Kim");
// mod_man.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
int man_init(void){
printk(KERN_INFO "Hello Man\n");
score_kor();
score_value = 80;
score_kor();
return 0;
}
void man_exit(void){
printk(KERN_INFO "Bye Man\n");
}
module_init(man_init);
module_exit(man_exit);
MODULE_LICENSE("GPL");
MODULE_AHTHOR("Kim");
// 합친걸 올림
root@KMU-UBUNTU:/work/mod_student# make
make -C /usr/src/linux-headers-3.11.0-15-generic SUBDIRS=/work/mod_student modules
make[1]: Entering directory `/usr/src/linux-headers-3.11.0-15-generic'
CC [M] /work/mod_student/mod_man.o
Building modules, stage 2.
MODPOST 2 modules
WARNING: "score_kor" [/work/mod_student/mod_man.ko] undefined!
CC /work/mod_student/mod_man.mod.o
LD [M] /work/mod_student/mod_man.ko
CC /work/mod_student/mod_score.mod.o
LD [M] /work/mod_student/mod_score.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.11.0-15-generic'
// 커널 2.4 버전에서는 프로토타입으로 정의만하면 심볼이 공유가 가능
// 커널 2.6 버전에서는 EXPORT_SYMBOL이라는 매크로를 사용
// mod_score.c:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
int score_value;
void score_kor(void){
printk(KERN_INFO "Korea Score = %d\n", score_value);
}
int score_init(void){
printk(KERN_INFO "Hello Score\n");
score_value = 100;
return 0;
}
void score_exit(void){
printk(KERN_INFO "Bye Score\n");
}
module_init(score_init);
module_exit(score_exit);
EXPORT_SYMBOL(score_value);
EXPORT_SYMBOL(score_kor);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jeong Been Kim");
// mod_man.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
extern void score_kor(); // using extern function method
extern int score_value; // using extern value
int man_init(void){
printk(KERN_INFO "Hello Man\n");
score_kor(); // 100
score_value = 80;
score_kor(); // 80
return 0;
}
void man_exit(void){
printk(KERN_INFO "Bye Man\n");
}
module_init(man_init);
module_exit(man_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kim");
// 결과
root@KMU-UBUNTU:/work/mod_student# insmod mod_man.ko
insmod: error inserting 'mod_man.ko': -1 Unknown symbol in module
// 외부에 공개된 소스를 사용해야하는데 mod_score.ko가 없기 때문에 그것을 먼저 올려야함
root@KMU-UBUNTU:/work/mod_student# insmod mod_score.ko
insmod: error inserting 'mod_score.ko': -1 File exists // rmmod 로 제거해야함
root@KMU-UBUNTU:/work/mod_student# rmmod mod_score
root@KMU-UBUNTU:/work/mod_student# insmod mod_score.ko
//
root@KMU-UBUNTU:/work/mod_student# dmesg
[ 5977.432061] Bye Score
[ 5980.116531] Hello Score
[ 6198.229196] Bye Score
[ 6214.525143] Hello Score
[ 6219.532929] Hello Man
[ 6219.532939] Korea Score = 100
[ 6219.532942] Korea Score = 80
root@KMU-UBUNTU:/work/mod_student# rmmod mod_score
ERROR: Module mod_score is in use by mod_man
root@KMU-UBUNTU:/work/mod_student# rmmod mod_man
root@KMU-UBUNTU:/work/mod_student# rmmod mod_score