Linux 系统一直在不断地发展,而相应地她的代码量也在不断的增大,直接导致的结果就是她的可执行镜像就变得越来越庞大。那么问题来了,如果将所有的镜像文件一次性地复制到内存中,那么所需的空间就非常大。但是有些服务是暂时或者很长时间内是不会被使用到的,那么就造成了空间的极大浪费。内核模块化就是为了解决这一个问题而被提出的一种解决方案。它通过一种机制,允许程序员将内核的一部分服务通过模块的方式进行编译,当用户需要这些服务的时候由系统自动地将这部分代码动态的安装到系统中运行。当不再需要这些服务时就可以动态地卸载这些服务。
使用内核模块的方式如下:
安装内核模块:insmod modulename.ko
卸载呢和模块:rmmod modulename
查看内核模块: lsmod
从编写代码的角度来看,创建一个简单的的内核模块可以分3步走:
1. 添加头文件(linux/init.h 和linux/module.h);
2. 加载内核(函数module_init);
3. 卸载内核(函数module_exit)
如一个简单的内核模块如下:
#include <linux/init.h> #include <linux/module.h> static int hello_init() { printk(KERN_WARNING"hello my module!\n"); return 0; } static void hello_exit() { printk(KERN_WARNING"module exit!\n"); } module_init(hello_init); module_exit(hello_exit);
事实上,关键部分是两个宏 module_init() 和module_exit(),这两个宏分别完成了内核模块安装和内核模块卸载,他们的代码都是内核实现的,用户程序只要调用即可。当然,一个内核模块的组成部分还有其他可选的选项,但是这里的是必须的,也是最简单的一个部分。
写完代码部分,接着完成Makefile的编写如下:
obj-m := hello.o KDIR :=/home/win/myfiles/linux-mini2440 all: make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm clean: rm -f *.o *.ko *.order
这是内核模块只有一个源文件的Makefile,如果源文件有多个,则采用如下版本:
obj-m := modulename.o modulename-objs := file1.o file2.o file3.o ...... KDIR :=/home/win/myfiles/linux-mini2440 all: make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm clean: rm -f *.o *.ko *.order
然后回到代码所在目录执行make 命令,即可产生 .ko 文件。