详解Linux操作系统设备驱动兼容性
2008-02-23 07:26:21来源:互联网 阅读 ()
最新进展
Linux一直在迅速地发展着,开发人员总是迫切希望改善核心内部,它们并不考虑向后兼容性。这种自由开发导致了不同版本核心提供的设备驱动程序接口之间一定程度的不兼容。不过,在应用级还保持着兼容,除了个别需要与核心特征进行低级交互的应用(象ps)。
另一方面,设备驱动程序是直接链接到核心映象上的,因此必须与数据结构、全局变量、以及由内系统引出的函数发生的改变保持一致。在开发过程中,随着新特征的加入,内部被修改;新的实现取代了就的实现,因为实践证明它们更快,更清晰。尽管不兼容性要求程序员在写模块时要做一些额外的工作,我认为连续的开发是Linux社区的成功点:严格的先后兼容性最终证明是有害的。
这一章讲述2.0.x和2.1.43之间的不同,这些将会与即将推出的2.2发布类似。Linus在前几个2.1版本中引入了最重要的改变,这样核心就可以多经历几个2.1版本,使得驱动程序的作者有足够的时间在开发被锁定以发布稳定的2.2之前来稳定驱动程序。下面的小节介绍驱动程序是如何处理2.0和2.1.43之间的不同的。我已经修改了本书介绍的所有示例代码,使得它们可以同时在2.0和2.1.43上编译和运行,以及这之间的大多数版本。驱动程序的新版本可以从O’Reilly的FTP站点上在线例子的v2.1目录下得到。2.0和2.1之间的兼容性通过头文件sysdep-2.1.h获得,它可以与你自己的模块集成。我选择不把兼容性扩展到1.2避免了给C代码加载太多的条件,而且1.2-2.0的不同已经在前面的章节解释过了。在我将要写完这本书时,我了解到从2.1.43起又引入了一些小的不兼容性;我不打算对之加以评述,因为我不能保证对这些最新版本的完全支持。
注意在本章我不会讲述2.1开发系列引入的所有新东西。我要做的只是移植2.0模块,使之可以在2.0和2.1核心上运行。利用2.1的特征意味着放弃对不具有这些特征的2.0发布的支持。2.0版本仍是本书的重点。在写sysdep-2.1.h时,我已努力使你熟悉新的API,我引入的宏用来使2.1的代码可以在2.0上跑,而不是相反。
本章以重要性逐渐降低的顺序介绍不兼容性;最重要的不同首先被介绍,次要的细节则在后面介绍。
模块化
在Linux社区中,模块化变的越来越重要,开发人员决定用一个更清晰的实现取代旧的。头文件在2.1.18中完全重写了,一个新的API被引入。如你所期望的,新的实现比旧的要容易使用。为了加载你的模块,你将需要包modutils-2.1.34甚至更新版本(细节见Documentation/
Changes)。当与旧的核心一起使用时,这个包可以回到兼容模式,因此你可以用这个新包替换modules-2.0.0,即使你经常在2.0和2.1之间切换。
引出符号
符号表的新接口比以前的要容易多了,它依赖于下面的宏:
EXPORT_NO_SYMBOLS;这个宏与register_symtab(NULL)等价;它可以出现在一个函数的内部或外部,因为它只是指导汇编器,而不产生实际代码。如果你想在Linux2.0上编译模块,这个宏应该在init_module中被使用。
EXPORT_SYMTAB;如果你打算引出一些符号,那么模块必须在包含之前定义这个宏。
EXPORT_SYMBOL(name);这个宏表明你想引出这个符号名。它必须在任何函数之外使用。
EXPORT_SYMBOL_NOVERS(name)使用这个宏而不是EXPORT_SYMBOL()强制丢弃版本信息,即使是编译带有版本支持的代码。这对避免一些不必要的重编译很有用。例如,memset函数将总以同样的方式工作;引出符号而不带版本信息允许开发者改变实现(甚至使用的数据类型)而不需insmod标出不兼容性。在模块化的代码中不大可能需要这个宏。
如果这些宏都没有在你的源码中使用,那么所有的非静态符号都被引出;这与在2.0中一如果这些宏都没有在你的源码中使用,那么所有的非静态符号都被引出;这与在2.0中一样。如果这个模块是从几个源文件生成的,你可以从任何源文件引出符号,而且还可以在模块的范围中共享任何符号。如你所看到的,引出符号表的新方法解决了一些问题,但这个创新也引入了一个重要的不兼容性:一个引出了一些符号的模块,如果想同时在2.0和2.1上编译运行,则必须用条件编译来包含两个实现。下面是export模块(v2.1/misc-modules/export.c)如何处理这个问题的当使用2.1.18或更新的核心时,REGISTER_SYMTAB扩展为什么都不做,因为init_module中没有什么需要做的;在函数外使用EXPORT_SYMBOL是引出模块符号唯一需要做的。
核心模块的新的实现利用了ELF二进制格式的特征以获得更好的灵活性。更特别地,当构核心模块的新的实现利用了ELF二进制格式的特征以获得更好的灵活性。更特别地,当构造一个ELF目标文件时,你可以声明除“正文”、“数据”和“bss”之外的节。一个“节”是一个连续的数据区域,与“段”的概念类似。
对于2.1,核心模块必须使用ELF二进制格式编译。事实上,2.1核心利用了ELF的节(见“处理核心空间错误”),只能编译为ELF。因此模块的限制并不是个真正限制。使用ELF允许信息域被存在目标文件中。好奇的读者可以使用objdump –section-headers来观察节头,用objdump –section=.modinfo –full-contents来查看模块特定的信息。实际上,.modinfo一节是用来存储模块信息的节,包含被称做“参数”的值,可以在加载时修改。
当在2.1上编译时,一个参数可以用宏如下声明:MODULE_PARM(variable, type-description);当你在源文件中使用这个宏时,编译器被告知在目标文件中插入一个描述串;这个描述表明variable是个参数,它的类型对应于type-description。insmod和modprobe查看目标文件,保证你被允许修改variable,同时检查参数的实际类型。类型检查对防止不愉快的错误非常重要,例如用一个串覆盖了一个整数,或错把长整数当成了短整数。按我的观点,讲述宏的最好办法时给出几行示例代码。下面的代码属于一个想象的网卡type-description串在头文件中被非常详细地介绍,并且为了你的方便,它可以在整个核心源码中找到。值得给出的一个技巧是如何参数化一个数组的长度,象上面的io。例如,设想网络驱动程序支持的外围板子的数目有宏MAX_DEVICES表示,而不是硬写入的数字4。出于这个目的,头文件定义了一个宏(__MODULE_STRING),它用C预处理器将一个宏“字符串化”。这个宏可以如下使用:
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash