linux 遍历设备,linux下遍历所有pci设备

本文介绍了如何在Linux中遍历pci_dev结构体,通过pci总线和pci_bus结构体的层级关系,利用全局变量pci_root_buses和递归搜索算法实现对所有PCI设备的遍历。关键概念包括pci总线、pci_dev、pci_bus的层次关系和搜索策略。

在linux中,每一个pci设备都有一个相应的结构体叫pci_dev,它用来记录pci设备的一些总线,配置信息等等。所以要遍历所有的pci设备就相当于遍历pci_dev结构体,程序只是遍历pci的一种手段,而pci在计算机中是如何架构的,pci和pci之间有什么关联,才是遍历所有pci设备的精髓。

很多个pci设备都是串在pci总线上,而这些总线又分为一级总线,二级总线,等等。二级总线是所属一级总线的,也就是说总线下有若干个pci设备和若干个pci总线,它之下总线又有pci设备,pci总线在linux下对应的结构体是pci_bus,对应关系大概如下如

0_13302576118Az3.gif

这样的话,如果遍历所有的pci_dev只需要找到根总线,然后运用搜索算法就可以遍历所有的pci设备了。

在#include 文件里有一个全局变量pci_root_buses,它就是我们要找的全局变量,有了它,基本就没有问题了,下面给出一张我在百度文库里找到一张很经典的pci的图:

0_1330257938dDIQ.gif

这副图包含所有说明,pci_root_buses是一个list结构体(相关list结构体,可以找一些linux方面的书了解),所有的pci_bus都挂在pci_root_buses上,这样就能遍历所有一级总线,而pci_bus结构体中的children字段又可以访问下层总线,dev字段访问所有的pci_dev结构体,这样就完全解决了遍历所有pci设备的方法。(ps.这里还涉及一些pci桥的东西,由于我没有深入了解,所以可能没有遍历所有,但是通过这两个结构体的一些其他字段,用这个方法就可以解决)。下面是经过我测试的代码:

static void searchPciBus(struct list_head *tobus) { struct pci_dev *pci; struct list_head *list,*list_pci_dev; struct pci_bus *subbus,*bus; if(tobus==NULL) { return ; } if(tobus->next==&tobus) { return ; } list_for_each(list,tobus) { bus=list_entry(list,struct pci_bus,node); if(bus->devices.next==&bus->devices) { return ; } list_for_each(list_pci_dev,&bus->devices) { pci=list_entry(list_pci_dev,struct pci_dev,bus_list); count++; } if(bus->children.next!=&bus->children) { list_for_each(list_pci_dev,&bus->children) { subbus=list_entry(list_pci_dev,struct pci_bus,node); searchPciBus(list_pci_dev); } } } }

在程序中,只要searchPciBus(&pci_root_buses);就可以了。程序中我是用递归来实现搜索,思想就是上面那张图,很容易理解。

ps.  对linux和硬件了解不多,如果上面有什么错误的地方,大家不要见怪,向大家多学习了

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值