文档介绍:Linux内核可装载模块对设备驱动的影响
从 到 ,Linux 内核在可装载模块机制、设备模型、一些核心 API 等方面发生较大改变,设备驱动开发人员面临着将驱动从 移植到 内核, 与 内核的任务。站在设备驱动开发人员的角度,驱动由一个或几个外部可加载内核模块组成,本文针对 内核里模块机制的改变对编写设备驱动程序的影响,从内核模块的编译、装载时的版本检查、初始化与退出、模块使用计数、输出内核符号、命令行输入参数、许可证声明等方面比较了 与 内核的区别;并总结了使设备驱动同时支持 与 内核的一系列模板。
当设备驱动需要同时支持不同版本内核时,在编译阶段,内核模块需要知道当前使用的内核源码的版本,从而使用相应的内核 API。 与 内核下,源码头文件 linux/ 定义有:
LINUX_VERSION_CODE ―内核版本的二进制表示,主、从、修订版本号各对应一个字节;
KERNEL_VERSION(major, minor, release) - 由主、从、修订版本号构造二进制版本号。
内核的设备驱动程序中,经常可以看到以下代码段:
清单1:判断内核版本的代码段。
/*code in kernel*/ /*code in kernel */
,外部可装载内核模块的编译、连接过程以及Makefile的书写都发生了改变。
,模块的编译只需内核源码头文件;需要在包含linux/;编译、。
,模块的编译需要配置过的内核源码;编译、;编译过程首先会到内核源码目录下,读取顶层的Makefile文件,然后再返回模块源码所在目录。
清单2: 内核模块的Makefile模板
# KVER=$(shell uname -r) KDIR=/lib/modules/$(KVER)/build OBJS= CFLAGS=-DKERNEL -I$(KDIR)/include -DMODULE -DKERNEL_SYSCALLS -DEXPORT_SYMTAB -O2 -fomit--pointer -Wall -DMODVERSIONS -include $(KDIR)/include/linux/
all: $(OBJS) : ld -r -o $@ $^ clean: rm -f *.o
内核下,内核模块的Makefile与普通用户程序的Makefile在结构和语法上都相同,但是必须在CFLAGS中定义-DKERNEL- DMODULE,指定内核头文件目录-I$(KDIR)/include。有一点需注意,之所以在CFLAGS中定义变量,而不是在模块源码文件中定义, 一方面这些预定义变量可以被模块中所有源码文件可见,另一方面等价于将这