linux内核特别庞大,linux中使用模块(Module)这种机制可以使内核模块动态的加载到内核而不是直接编译至内核映像从而控制了linux内核的大小。
linux内核的编程框架如下所示,这里以简单的helllo word示例模块进行说明
#include "linux/init.h"
#include "linux/module.h"
static int hello_init()
{
printk(KERN_WARNING"HELLO WORLD!\n");
return 0;
}
static void hello_exit()
{
printk(KERN_WARNING"hello exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
对应的Makefile文件代码
obj-m := helloworld.o
KDIR := /home/s3_arm/Part9/lesson3/linux-mini2440
all:
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
clean:
rm -f *.o *.ko *.order *.symvers *.bak *mod.c
编译该驱动后将会产生helloword.ko 文件,将此文件复制到嵌入式开发板的文件系统中,可通过insmod命令动态加载该模块,加载成功后,模块的加载函数也就是 module_init() 指定的函数即hello_init() 将会自动执行。 ps:模块加载函数必须有返回值,若无将导致内核错误。rmmod命令是内核模块的卸载命令,同样该命令对应执行模块的卸载函数也就是module_exit()指定的hello_exit()函数,模块卸载函数无返回值。
此外模块程序中还包含一些其他信息,在这里做简要介绍。
模块许可证声明 MOUDLE_LICENSE("license") 可接受的license有 “GPL” "GPL v2" "Dual BSD/GPL" 等等
模块作者 MOUDLE_AUTHOR("author")
模块描述 MOUDLE_DESRIPTON("description")
模块版本 MOUDLE_VERSION(version)
模块设备表 MOUDLE_DEVICE_TABLE(table_info) //对于 usb pci 等设备往往会去创建一个设备表去表明可支持的设备
模块参数 可以在模块中定义一个参数用于接收用户在加载模块是传递的参数。
使用说明 :程序中 module_param(参数名, 参数类型,S_IRUGO)
用户加载时,insmod 模块名 参数名 = 参数值
导出符号,导出符号可以使本模块建立与其他模块的连接,也就是本模块导出的符号可以供其他模块使用
模块使用以下宏导出符号到内核符号表中
EXPORT_SYMBOL(符号名)
EXPORT_SYMBOL_GPL(符号名) //只适用于包含GPL 的模块中