Linux2.6PCI驱动加载原理 (2008-09-13 15:19)
Linux2.6PCI驱动加载原理 所有PCI设备都有至少256字节的地址空间。前64字节是标准化的,每种设备都有且意义相同,其余字节是设备相关的。 在内核中有三个主要的数据结构与PCI接口有关,在开发PCI设备驱动程序时要用到,分别是:
#define PCI_ANY_ID (~0) 这个pci_device_id结构体需要被导出到用户空间,使热插拔和模块装载系统知道什么模块针对什么硬件设备。宏MODULE_DEVICE_TABLE完成这个工作。例如上面的 MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); 该语句创建一个名为__mod_pci_device_table的局部变量,只想struct
pci_device_id数组。在稍后的内核构建过程中,depmod程序在所有的模块中搜索符号__mod_pci_device_table。如果找到了该符号,它把数据从该模块中抽出,添加到文件
/lib/module/KERNEL_VERSION/module.pcimap中。当depmod结束之后,内核模块支持的所有PCI设备连同他们的模块名都在改文件中被列出。当内核告知热插拔系统一个新的PCI设备已经被发现时,热插拔系统使用module.pcimap文件来寻找要加载的适当的驱动程序。 使用这种方式编写的kernel modules,使用modinfo查看的结果如下: root@dell-desktop:/lib/modules/2.6.24-16-generic# modinfo 8139too /lib/modules/KERNEL_VERSION/modules.pcimap文件列出内核所支持的所有PCI设备和它们的模块名。 debian:/lib/modules/2.6.24-16-generic# cat modules.pcimap | grep
8139too 8139too 0x000010ec 0x00008138 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001113 0x00001211 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001500 0x00001360 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00004033 0x00001360 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001186 0x00001300 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001186 0x00001340 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x000013d1 0x0000ab06 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001259 0x0000a117 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001259 0x0000a11e 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x000014ea 0x0000ab06 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x000014ea 0x0000ab07 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x000011db 0x00001234 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001432 0x00009130 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x000002ac 0x00001012 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x0000018a 0x00000106 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x0000126c 0x00001211 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x00001743 0x00008139 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x0000021b 0x00008139 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0x000010ec 0x00008129 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 8139too 0xffffffff 0x00008139 0x000010ec 0x00008139 0x00000000 0x00000000 0x0 8139too 0xffffffff 0x00008139 0x00001186 0x00001300 0x00000000 0x00000000 0x0 8139too 0xffffffff 0x00008139 0x000013d1 0x0000ab06 0x00000000 0x00000000 0x0 目录 /lib/modules/`uname -r`/下的modules.*map文件都是由depmod命令生成的。depmod通过查找目录 /lib/modules/`uname -r`/下的核心模块中的数据建立的。里面包含的是各个核心模块和它所支持的具体硬件设备的对应关系。而这些对应关系是硬件驱动的作者在核心模块时候确定的。这种机制一般不会出现什么问题:没有人能够比驱动作者更清楚它要支持那些硬件。 利用这些映射文件,各种硬件管理程序就可以对硬件作出智能化的判断,即使他们本身对自己所处理的硬件设备并不熟悉。比如,kudzu通过探测系统总线,发现PCI设备,其vendorID和diviceID分别为1057:0003。kudzu通过查找/lib/modules /`uname -r`/modules.pcimap文件,根据如下行: snd-mixart 0x00001057 0x00000003 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0就可以确定该设备的驱动为snd-mixart,然后就可以写modprobe.conf文件,加载核心模块 snd-mixart,而不需要对该设备有更多的了解。 /lib/modules/`uname -r`/modules.*map文件格式说明下面是 modules.pcimap中的一部分,现在对其进行说明:
/lib/modules/`uname -r`/modules.pcimap文件的部分内容: # pci module vendor device subvendor subdevice class class_mask driver_data 比较要注意的是 modules.pcimap,如果你详细看modules.pcimap这个文件的话,会发现一些相同的 vendor:device,但是却对应这两种不同的 modules。例如使用 10ec:8139 去寻找,会同时找到 8139cp 和 8139too。诸如这样的情况还有很多,在比较modules.pcimap文件时候应该遵循下面的原则: 比较的优先顺序应该是: 1.寻找vendor:device 和 subvendor:subdevice 相同的专用module 2.寻找device 和 subvendor:subdevice 相同的通用module 3.寻找device建议module 4.寻找 vendor:device 标准module
内核通过pci_register_driver和pci_unregister_driver函数来注册和注消PCI设备驱动程序。这两个函数在drivers/pci/pci.c源码中定义。pci_register_driver函数需要使用 pci_driver数据结构作为参数。通过注册,PCI设备就与PCI设备驱动程序关联起来了。 PCI设备最大的优点是可以自动探测每个设备所需的IRQ和其它资源。有两种探测方式,一种是静态探测,一种是动态探测。静态探测是通过设备驱动程序自动选择相关资源,动态探测是指支持热插拔设备的功能。 PCI设备通过pci_driver结构中的suspend和resume函数指针支持电源管理。可实现暂停和重新启动PCI设备的功能。 参考:Linux设备驱动第12章 MODULE_DEVICE_TABLE小节 http://hi.baidu.com/xdebian/blog/item/c27cb503eb4304763812bbd9.html http://fred-zone./2007/11/linux-pci.html http://203.208.39.99/search?q=cache:T7HcgoDIx9wJ:wiki.os-drive.com/bin/view/Main/LinuxDriver+modules.pcimap&hl=zh-CN&ct=clnk&cd=10&gl=cn&st_usg=ALhdy28wKf_dSuMGEoQOPYvbjvS6_oUReQ http://www./note/opensource/kernel/kernel.htm#id2810163
|
|