声明:此文档只做学习交流使用,请勿用作其他商业用途
author:朝阳_tonyE-mail : linzhaolover@gmail.com
Create Date: 2013-7-17 17:17:14 Wednesday
Last Change: 2013-7-19 16:46:00 Friday
转载请注明出处:http://blog.csdn.net/linzhaolove
此文中源码可以去http://dpdk.org/dev 网页中下载;更多官方文档请访问http://dpdk.org
1、函数用途
rte_eal_pci_init() 函数负责pci设备的早期初始化,涉及到pci设备的查询扫描,初始化pci设备列表等;
函数在dpdk/lib/librte_eal/linuxapp/eal/eal_pci.c 文件中定义
2、函数详解
rte_eal_pci_init() 函数会在早期的rte_eal_init()函数调用;
TAILQ_INIT(&driver_list);
TAILQ_INIT(&device_list);
uio_res_list = RTE_TAILQ_RESERVE_BY_IDX(RTE_TAILQ_PCI, uio_res_list);
首先初始化下面struct rte_pci_device , struct rte_pci_driver两个结构体相关的链表,分别是pci 驱动和pci的设备;用来保存查询到的设备相关信息;还要预留一个uio相关结构体的列表;
TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */
extern struct pci_driver_list driver_list; /**< Global list of PCI drivers. */
extern struct pci_device_list device_list; /**< Global list of PCI devices. */
/* for debug purposes, PCI can be disabled */
if (internal_config.no_pci)
return 0;
在一些调试的场合,或者不需要pci的场合,其实我们是不需要初始化pci设备的;
if (pci_scan() < 0)
调用pci_scan() 去查询相应的pci设备;
下面详细介绍一下pci_scan()函数;
dir = opendir(SYSFS_PCI_DEVICES);
去打开/sys/bus/pci/devices目录,查询所有的pci设备;我可以用查看一下这个目录
# ls /sys/bus/pci/devices
0000:00:00.0 0000:00:11.0 0000:00:16.2 0000:00:1c.0 0000:00:1f.3 0000:1a:00.0
这里有很多设备,我只是摘录了一些;
在pci_scan()中调用,parse_pci_addr_format()函数,将每个设备的目录信息分离出来;
if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &domain,
&bus, &devid, &function) != 0)
continue;
函数正确返回后,会分别存储的到 domain bus devid function 中, 如 0000:00:16.2 就分别是 domain=0000 bus =00 devid =16 function =2
然后pci_scan 再调用pci_scan_one()函数,一个设备一个设备的读写每个设备的信息;
if (pci_scan_one(dirname, domain, bus, devid, function) < 0)
在pci_scan_one函数中主要取了设备目录中的vendo,device,subsystem_vendor,subsystem_device,resource;
这要注意的是取的resource,在这会取出设备的硬件资源空间,将其赋值到
dev->mem_resource.phys_addr = phys_addr;
dev->mem_resource.len = end_addr - phys_addr + 1;
dev->mem_resource.addr = NULL; /* not mapped for now */
/* device is valid, add in list */
TAILQ_INSERT_TAIL(&device_list, dev, next);
技术水平有待提高,如果文章有错误的地方希望读者指正,相互交流,互相学习;O(∩_∩)O~