『分享』从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响! (转载)解决方法
发布时间:2011-06-27 17:47:32 文章来源:www.iduyao.cn 采编人员:星星草
『分享』从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响!!! (转载)
从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响!!! 收藏
从 2.4 到 2.6,Linux 内核在可装载模块机制、设备模型、一些核心 API 等方面发生较大改变,设备驱动开发人员面临着将驱动从 2.4 移植到 2.6 内核,或是使驱动同时支持2.4 与 2.6 内核的任务。站在设备驱动开发人员的角度,驱动由一个或几个外部可加载内核模块组成,本文针对 2.6 内核里模块机制的改变对编写设备驱动程序的影响,从内核模块的编译、装载时的版本检查、初始化与退出、模块使用计数、输出内核符号、命令行输入参数、许可证声明等方面比较了 2.4 与 2.6 内核的区别;并总结了使设备驱动同时支持 2.4 与 2.6 内核的一系列模板。
1. 获取内核版本
当设备驱动需要同时支持不同版本内核时,在编译阶段,内核模块需要知道当前使用的内核源码的版本,从而使用相应的内核 API。2.4 与 2.6 内核下,源码头文件 linux/version.h 定义有:
LINUX_VERSION_CODE ― 内核版本的二进制表示,主、从、修订版本号各对应一个字节;
KERNEL_VERSION(major, minor, release) - 由主、从、修订版本号构造二进制版本号。
在同时支持2.4与2.6 内核的设备驱动程序中,经常可以看到以下代码段:
清单1:判断内核版本的代码段。
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
#define LINUX26
#endif
#ifdef LINUX26
#else
#endif
回页首
2.内核模块机制的改变
2.1模块编译
从2.4到2.6,外部可装载内核模块的编译、连接过程以及Makefile的书写都发生了改变。
2.4内核中,模块的编译只需内核源码头文件;需要在包含linux/modules.h之前定义MODULE;编译、连接后生成的内核模块后缀为.o。
2.6内核中,模块的编译需要配置过的内核源码;编译、连接后生成的内核模块后缀为.ko;编译过程首先会到内核源码目录下,读取顶层的Makefile文件,然后再返回模块源码所在目录。
清单2:2.4 内核模块的Makefile模板
#Makefile2.4
KVER=$(shell uname -r)
KDIR=/lib/modules/$(KVER)/build
OBJS=mymodule.o
CFLAGS=-D__KERNEL__ -I$(KDIR)/include -DMODULE -D__KERNEL_SYSCALLS__ -DEXPORT_SYMTAB
-O2 -fomit-frame-pointer -Wall -DMODVERSIONS -include $(KDIR)/include/linux/modversions.h
all: $(OBJS)
mymodule.o: file1.o file2.o
ld -r -o $@ $^
clean:
rm -f *.o
在2.4 内核下,内核模块的Makefile与普通用户程序的Makefile在结构和语法上都相同,但是必须在CFLAGS中定义-D__KERNEL__-DMODULE,指定内核头文件目录-I$(KDIR)/include。有一点需注意,之所以在CFLAGS中定义变量,而不是在模块源码文件中定义,一方面这些预定义变量可以被模块中所有源码文件可见,另一方面等价于将这些预定义变量定义在源码文件的起始位置。在模块编译中,对于这些全局的预定义变量,一般在CFLAGS中定义。
清单3:2.6 内核模块的Makefile模板
# Makefile2.6
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationshsip of files and target modules are listed here.
mymodule-objs := file1.o file2.o
obj-m := mymodule.o
else
PWD := $(shell pwd)
KVER ?= $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
endif
KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容。如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,-C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD) 表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。else之前的内容为kbuild语法的语句, 指明模块源码中各文件的依赖关系,以及要生成的目标模块名。mymodule-objs := file1.o file2.o表示mymoudule.o 由file1.o与file2.o 连接生成。obj-m := mymodule.o表示编译连接后将生成mymodule.o模块。
补充一点,"$(MAKE) -C $(KDIR) M=$(PWD)"与"$(MAKE) -C $(KDIR) SUBDIRS =$(PWD)"的作用是等效的,后者是较老的使用方法。推荐使用M而不是SUBDIRS,前者更明确。
通过以上比较可以看到,从Makefile编写来看,在2.6内核下,内核模块编译不必定义复杂的CFLAGS,而且模块中各文件依赖关系的表示简洁清晰。
清单4: 可同时在2.4 与 2.6 内核下工作的Makefile
#Makefile for 2.4 & 2.6
VERS26=$(findstring 2.6,$(shell uname -r))
MAKEDIR?=$(shell pwd)
ifeq ($(VERS26),2.6)
include $(MAKEDIR)/Makefile2.6
else
include $(MAKEDIR)/Makefile2.4
endif
2.2模块装载时的版本检查
Linux内核一直在更新、完善,在a版本内核源码下编译的模块在b版本内核下通常不能运行,所以必须有一种机制,限制在a版本内核下编译生成的模块在b版本内核下被加载。
2.4与2.6内核在可装载内核模块的版本检查机制方面发生了根本性的改变,不过这些改变对设备驱动开发人员而言基本是透明的。为了使模块装载时的版本检查机制生效,2.4 内核下,只需在CFLAGS中定义
-DMODVERSIONS -include $(KDIR)/include/linux/modversions.h;
2.6内核下,开发人员无须采用任何操作。
不过,在此仍有必要阐明2.4与2.6内核对可加载模块的版本检查机制。
2.4内核下, 执行`cat /proc/ksyms`可看到内核符号在名字后还跟随着一串校验字符串,此校验字符串与内核版本有关。在内核源码头文件linux/modules 目录下存在许多*.ver文件,这些文件起着为内核符号添加校验后缀的作用,如ksyms.ver 文件里有一行 #define printk _set_ver(printk)。linux/modversions.h 文件会包含全部的 ver文件。所以当模块包含linux/modversions.h文件后,编译时,模块里使用的内核符号实质是带有校验后缀的内核符号。在加载模块时,如果模块中所使用内核符号的校验字符串与当前运行内核所导出的相应的内核符号的校验字符串不一致,即当前内核空间并不存在模块所使用的内核符号,就会出现"Invalid module format "的错误。
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。
其他相似内容:
-
在ubuntu下怎么播放swf 和csf 文件?
虽然,firefox 可以播放swf文件,但是没有托动条。
在ubuntu下怎么播放swf和 csf文件?
哪个高...
-
2011年最新录制的Linux(CentOS)视频教程
电驴地址:http://www.verycd.com/topics/2875873/
------解决方案--------------------
l...
-
求《操作系统:设计与实现》pdf
A.S.Tanenbaum写的《操作系统设计与实现》,有上下册,谁有的,帮个忙,非常感谢。qifeifei@live.cn
----...
-
linux用户态内存的物理地址问题?
小弟我看linux内存管理一段时间了。有一个问题一直不解。 linux用户态进程使用0—3G的线性地址...
-
安装linux chm阅读器 xchm
[root@localhost ~]# yum install chmlib
[root@localhost ~]# yum install wxGTK
[root@localhost ~]...
-
都说Linux是开源的,在哪可以找到Linux的源码?
都说Linux是开源的,在哪可以找到Linux的源码?
烦请各位高手指点一二,谢谢。
------解决...
-
求解2个概念,书上没找到,急用,谢谢大家
1.Unix中磁盘文件和设备文件的异同点。
2.Unix中原子和竞争的概念。
求正解,因为考试可能会考...
-
有人在fedora 10下安装 oracle database 11g,没有呀?提供个安装步骤
有人在fedora 10下安装 oracle database 11g,没有呀?提供个安装...
-
用什么学习函数库?
我们现在学习LINUX 编程,读程序时候有很多头文件,代码中有许多库函数。
#include <sys/types.h>
#include <wait....
-
linux下c语言写的shell,花了不少时间写得 有兴趣的可以看看,本人linux初学者
http://download.csdn.net/source/2799757
------解...