intel dpdk api rte_eal_pci_init() 函数介绍

来源:互联网 发布:电脑配色软件 编辑:程序博客网 时间:2024/06/15 04:49

声明:此文档只做学习交流使用,请勿用作其他商业用途

author:朝阳_tony
E-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/devices0000: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 */


在pci_scan_one函数中,将获取的信息,最后存储在 device_list 这个链表中;就是文章开始rte_eal_pci_init()中初始化的列表;
    /* device is valid, add in list */    TAILQ_INSERT_TAIL(&device_list, dev, next);

技术水平有待提高,如果文章有错误的地方希望读者指正,相互交流,互相学习;O(∩_∩)O~


原创粉丝点击