linux 2.4的動(dòng)態(tài)模塊是.o結尾,不是.ko
1.1 example1
#define MODULE
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
MODULE_LICENSE("GPL");
static int __initlkp_init(void)
{
printk("<1>helloworld from the kernel space.. \n");
return 0;
}
static void __exitlkp_cleanup(void)
{
printk("<2>goodbyeworld, leaving kernel space.. \n");
}
module_init(lkp_init);
module_exit(lkp_cleanup);
以上是源代碼,在2.4內核中動(dòng)態(tài)可加載模塊文件開(kāi)始出一定要有一個(gè)MODULE宏定義,不然會(huì )出現版本不匹配等錯誤,
宏__init告知編譯程序相關(guān)的函數和變量只用于初始化,編譯程序將標有__init的所有代碼存儲到特殊的內存中,初始化結束后就釋放這段內存,同樣宏__exit和__exitdata僅用于退出和關(guān)閉例程,
代碼中的最后兩行module_init(lkp_init);module_exit(lkp_cleanup);可以不用加入,但這樣的話(huà)模塊在加入和移除時(shí)將不會(huì )調用lkp_init, lkp_cleanup,則文件/var/log/message中將不包含提示信息,如果不想使用這種方法,可以使用下面的代碼
1.2 example2
#define MODULE
#include<linux/module.h>
MODULE_LICENSE("MYGPL");
int init_module(void)
{
printk("<1>Hello,world\n");
return 0;
}
void cleanup_module(void)
{
printk("<1>Goodbye cruelworld\n");
}
在此代碼中可以直接將example1中的初始化和退出函數名字直接改為init_module和cleanup_module,這樣內核在加載和移除該模塊時(shí)自動(dòng)調動(dòng)初始化和清除函數.
1.3 example3
#define MODULE
#include<linux/kernel.h>
#include<linux/module.h>
MODULE_LICENSE("GPL");
int init_module(void)
{
printk("<1>hello\n");
return 0;
}
voidcleanup_module(void)
{
printk("<1>bye\n");
}
1.4 makefile文件
#Makefile for linuxloadable kernel module
CC=gcc
CFLAG := -I/usr/src/linux-
OBJ=test
$(OBJ).o:$(OBJ).c
-rm $@ -f
$(CC) $(CFLAG) -c $(OBJ).c -o test.o
注意其中的gcc選項一定要包含D_KERNEL__和D__MODULE這兩個(gè)選項,不管對于什么的架構,一定要使gcc在編譯時(shí)的環(huán)境版本和運行時(shí)的環(huán)境版本相匹配,也即在運行環(huán)境中,假如你使用ARM或者
MODULE_LICENSE("GPL");本句代碼可以不要,但不要的話(huà),運行時(shí)會(huì )出現"hello:module license 'unspecified' taints kernel.",詞典上對taints的解釋是"感染,污點(diǎn)".
1.5 編譯過(guò)程
在命令行輸入make命令編譯生成ELF文件,
insmod hellomod來(lái)加載模塊
rmmod hellomod移除hellomod模塊
lsmod查看當前已加載模塊
hellomod向模塊發(fā)出的信息可以在/var/log/message文件中查看到,
可用dmesg命令來(lái)查看
readelf和ojbdump用于查看目標文件的信息
聯(lián)系客服