本文基于DPDK-17.05.2分析总结
一、DPDK的可执行程序运行步骤:
1、分配大页内存:
mkdir -p /mnt/huge-dpdk
mount -t hugetlbfs nodev /mnt/huge-dpdk
echo 640 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
2、解压编译好的python解释器:
cp python.tar.gz /usr/local/
cd /usr/local/
tar zxvf python.tar.gz
ln -s /usr/local/bin/python2.7 /usr/bin/python
3、运行igb_uio.ko:
insmod /fw_dat/igb_uio.ko
4、绑定网卡:
./dpdk-devbind.py --bind=igb_uio 0000:01:00.0
./dpdk-devbind.py --bind=igb_uio 0000:01:00.1
5、运行二层转发程序:
./l2fwd -c f -n 2 – -q 1 -p 0x3
二、DPDK运行步骤与源代码执行关系:
uio代码相关的可以分为三个部分:内核uio框架及内核内部函数,uio用户驱动内核部分,uio用户驱动用户部分。
1、内核启动初始化:
内核uio框架通过配置内核选项CONFIG_UIO=y使能Userspace I/O drivers,在内核初始化时会调用uio_init创建uio_class; -----内核uio.c中完成,纯内核操作;
module_init(uio_init)----uio_init----init_uio_class----uio_major_init----class_register(&uio_class)
| |------>创建“/sys/class/uio”设备目录或文件系统,此时该目录为空,在insmod igb_uio.ko后且运行python脚本绑定网卡后此目录下才有内容;
|---->申请字符设备号(alloc_chrdev_region),分配字符设备(cdev_alloc),uio字符设备操作函数挂载(cdev->ops = &uio_fops;)并将字符设备"uio"注册到系统中(cdev_add);
uio核心的任务就是管理好调用uio_register_device向它注册的uio设备。
两个重要数据结构:uio_device----uio设备使用的数据结构;
uio_info----保存设备属性,比如name, open(), release()等操作都放在了uio_info结构中,注册驱动之前要设置好。
2、insmod igb_uio.ko 加载igb_uio驱动(含igb、ixgbe等):
igb_uio内核驱动通过编译运行igb_uio.ko加载并注册一个pci设备驱动,但是igbuio_pci_driver对应的保存pci设备信息的 -----dpdk igb_uio.c中完成,编译时依赖内核开发包kernel-devel,纯内核操作;
id_table指针为空,这样在内核注册此pci设备驱动时,会找不到匹配的设备,就不会调用igb_uio驱动中的探测probe函数,只会在/sys/bus/pci/drivers/目录下创建Igb_uio相应的目录;在运行dpdk提供的Python脚本dpdk-devbind.py绑定网卡设备后才会执行其probe函数;
static struct pci_driver igbuio_pci_driver = {
.name = "igb_uio",
.id_table = NULL, -----id_table指针为空(即deviceid为空,类似内核igb_pci_tbl,dpdk的pci_id_igb_map),找不到驱动能匹配的设备,不会调用.probe钩子函数初始化;----可以试试增加id_table,去掉Python脚本dpdk-devbind网卡操作;
.probe = igbuio_pci_probe,
.remove = igbuio_pci_remove,
};
module_init----igbuio_pci_init_module----pci_register_driver(&igbuio_pci_driver)---->igbuio_pci_probe----uio_register_device(__uio_register_device)|----uio_get_minor
|此之前都是在dpdk的igb_uio.c中调用内核接口函数<-----|---->此之后都是在内核的uio.c中调用内核接口函数 |---->利用idr机制(idr_alloc)建立了次设备号(整数ID)和uio_device类型指针之间的联系,idev->minor = retval
|---->注册igbuio设备驱动,在/sys/bus/pci/drivers/目录下创建Igb_uio相应的目录 |----device_create(&uio_class, parent,MKDEV(uio_major, idev->minor), idev,"uio%d", idev->minor);
|---->创建设备并关联uio_class,调用完毕后在 /sys/class/uio/下就会出现代表uio设备的uioX文件夹,其中X为uio设备的次设备号idev->minor。
|----request_irq
|---->初始化设备中断(uio_interrupt),每个uio设备的硬件中断处理函数都是单独注册的,非


5082

被折叠的 条评论
为什么被折叠?



