在Linux种有一个很好的特性:内核提供的特性可在运行时拓展。
这就意味着当系统启动并运行时,我们可以向内核添加功能,当然也可以移除功能。可在运行时添加到内核中的代码称为"模块"。每个模块由目标代码组成,可以使用insmod程序将模块连接到正在运行的内核,也可以使用rmmod程序移除连接。
一个简单的例程:#include#include static int __init hello_init(void) { printk(KERN_alert "Hello World !"); return 0; } static void __exit hello_exit(void) { printk(KERN_alert "Goodbye, cruel World !"); } MODULE_LICENSE("GPL"); module_init(hello_init); module_exit(hello_exit);
- 这个模块定义了两个函数,其中一个是在模块加载时被调用(hello_init),另一个是在模块卸载时被调用(hello_exit)。
- module_init() 和 module_exit(),两特殊的宏表述加载和卸载两函数。
- MODULE_LICENSE 这个是申明该模块采用自由许可证,如果未如此声明,会引起不必要的麻烦。
- 函数printk是内核定义的函数,类似标准c库的printf,在内核运行中不能使用c库,所以内核需要自己单独的打印函数。代码中的 KERN_alert 字符串是表示打印级别。
第一步,首先,需要确保具备正确的版本编译器、模块工具、和其他的必要的工具。
1、内核源码,干净的内核源码可以在官网下载,或者可以访问国内的镜像网站,比如网易镜像站The Linux Kernel Archiveshttps://www.kernel.org/
Index of /kernel/http://mirrors.163.com/kernel/2、编译工具,编译工取决于运行环境(arm、x86),或由厂商定制。
第二步,是配置及编译内核,使其运行环境保持一致;以linux-3.18.24内核版本,使用arm-histbv310-linux-交叉编译工具链为例:
配置内核方法,在内核根目录下执行make menuconfig,或者直接指定配置文件
make -C <内核源码路径> ARCH=arm CROSS_COMPILE=arm-histbv310-linux- <指定的配置文件>
注:使用的是Android环境,所以习惯使用"-C"项,亦可在内核源码直接执行。
最终会在源码根目录下生成一个隐藏文件".config",执行make进行编译
make -C linux-3.18.y/ ARCH=arm CROSS_COMPILE=arm-histbv310-linux- -j 4 uImage
第三步,编写Makefile
KERNELDIR ?= /home/dengcaixiang/other/linux-3.18.y ARCH ?= arm CROSS_COMPILE ?= arm-histbv310-linux- PWD := $(shell pwd) obj-m += hello.o .PHONY: all clean all: make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules V=1 clean: make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) clean
第四步,编写好Makefile后,执行make,最终会生成一个动态模块hello.ko,在此过程中,可能会遇到各种报错,一个一个解决即可
运行模块
可通过insmod将模块加载到正在运行的内核中,lsmod可以查看模块,rmmod可以卸载模块,运行结果如下:
至此简单的一个内核模块就完成了。



