窥探Linux的PCI驱动背后的奥秘(linux的pci驱动)
Linux的PCI驱动程序让计算机的各个部件配合得十分融洽,但看似简单的操作背后却藏有无法从表面上获知的奥秘。揭开这一惊天神秘,我们就可以了解Linux下PCI驱动能够完美实现的过程。
PCI驱动是由处理器和硬件设备之间进行“沟通”的中介,一旦映射完毕,硬件设备就可以与处理器进行“正确”的通信。而其中涉及到的核心就是设备树,它是一种设备模型,旨在揭开处理器和硬件设备之间的知识面研究,它也是实现PCI驱动的基础。
设备树的关键部分包括节点、属性、缩写。每一个设备都以节点的形式存在,而每个节点可以拥有多个属性。缩写是指一些常用驱动,比如驱动PCI地址,它会告诉内核去加载相关的PCI驱动。
既然我们揭开了设备树的神秘面纱,那么接下来就是如何实现PCI驱动的具体操作了。我们首先要判断当前的系统中有没有可以自动加载的PCI驱动,如果有,就会将其自动加载到内核中;如果没有,就需要通过加载一个新的内核模块来实现。为此,我们可以以下代码来完成:
#include
#include
#include
static struct pci_device_id mypci_device_tbl[] = {
{PCI_DEVICE(0x1172, 0x5629)}, {PCI_DEVICE(0x1172, 0x5929)},
{PCI_DEVICE(0x14f2, 0x1172)}, {PCI_DEVICE(0x14f2, 0x1372)},
{0, }};
static int mypci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{ printk(KERN_INFO"Found device, vendor id: %X device id: %X\n",
dev->vendor, dev->device);
return 0;}
static void mypci_remove(struct pci_dev *dev)
{ printk(KERN_INFO"Removing device, vendor id: %X device id: %X\n",
dev->vendor, dev->device);}
static struct pci_driver mypci_driver = {
.name = "MyPCI", .id_table = mypci_device_tbl,
.probe = mypci_probe, .remove = mypci_remove,
};
static int __init mypci_init(void){
int retval;
retval = pci_register_driver(&mypci_driver);
return retval;}
static void __exit mypci_exit(void)
{ pci_unregister_driver(&mypci_driver);
}
module_init(mypci_init);module_exit(mypci_exit);
MODULE_LICENSE("GPL");
从以上代码可以看出,首先使用pci_device_id一天定义设备,然后通过pci_register_driver()函数加载PCI驱动,最后再调用pci_unregister_driver()函数注销PCI驱动。
来源于上述内容,我们可以看出,深入研究Linux下的PCI驱动,不仅要理解内核对外设的定义方式及设备的控制,还要认真学习已有的驱动代码。总而言之,掌握PCI驱动背后的奥秘可不是件容易之事,只有充分了解相关技术,才能有效地实现一个良好的PCI驱动。