DPDK uio 分析 丨DPDK的优势及学习总结

通常这些非标准设备的驱动被实现为字符驱动。这些驱动使用了很多内核内部函数和宏。而这些内部函数和宏是变化的。这样驱动的编写者必须编写一个完全的内核驱动,而且一直维护这些代码。

而且这些驱动进不了主内核源码。于是就出现了用户空间I/O框架(Userspace I/O framework)。

UIO 怎样实现一个设备驱动的基本任务

一个设备驱动的主要任务有两个: 1. 存取设备的内存 2. 处理设备产生的中断

  • 对于第一个任务,UIO 核心实现了mmap()可以处理物理内存(physical memory),逻辑内存(logical memory), 虚拟内存(virtual memory)。UIO驱动的编写是就不需要再考虑这些繁琐的细节。

  • 第二个任务,对于设备中断的应答必须在内核空间进行。所以在内核空间有一小部分代码用来应答中断和禁止中断,但是其余的工作全部留给用户空间处理。

如果用户空间要等待一个设备中断,它只需要简单的阻塞在对 /dev/uioX的read()操作上。 当设备产生中断时,read()操作立即返回。UIO 也实现了poll()系统调用,你可以使用 select()来等待中断的发生。

select()有一个超时参数可以用来实现有限时间内等待中断。对设备的控制还可以通过/sys/class/uio下的各个文件的读写来完成。你注册的uio设备将会出现在该目录下。

假如你的uio设备是uio0那么映射的设备内存文件出现在 /sys/class/uio/uio0/maps/mapX,对该文件的读写就是 对设备内存的读写。

  如下的图描述了uio驱动的内核部分,用户空间部分,和uio 框架以及内核内部函数的关系

编辑切换为居中

添加图片注释,不超过 140 字(可选)

/**
 * A structure describing the private information for a uio device.
 */
struct rte_uio_pci_dev {
    struct uio_info info;//uio 通用结构
    struct pci_dev *pdev;//pci设备描述结构
    enum rte_intr_mode mode;//中断模式
    atomic_t refcnt;
};
/**来自内核 uio_driver.h 文件
 * struct uio_info - UIO device capabilities
 * @uio_dev:        the UIO device this info belongs to
 * @name:        device name
 * @version:        device driver version
 * @mem:        list of mappable memory regions, size==0 for end of list
 * @port:        list of port regions, size==0 for end of list
 * @irq:        interrupt number or UIO_IRQ_CUSTOM
 * @irq_flags:        flags for request_irq()
 * @priv:        optional private data
 * @handler:        the device's irq handler
 * @mmap:        mmap operation for this uio device
 * @open:        open operation for this uio device
 * @release:        release operation for this uio device
 * @irqcontrol:        disable/enable irqs when 0/1 is written to /dev/uioX
 */
struct uio_info {
    struct uio_device    *uio_dev;//uio设备 在 uio_register_device中初始化
    const char        *name;//名称 调用__uio_register_device之前必须初始化
    const char        *version;//版本号 //调用__uio_register_device之前必须初始化
    struct uio_mem        mem[MAX_UIO_MAPS];//可映射的内存区域列表,size == 0表示列表结束
    struct uio_port        port[MAX_UIO_PORT_REGIONS];//网口区域列表
    long            irq;//UIO_IRQ_CUSTOM 中断号 //分配给uio设备的中断号,调用__uio_register_device之前必须初始化
    unsigned long        irq_flags;//请求中断号的标志
    void            *priv; //可选的私有数据
    irqreturn_t (*handler)(int irq, struct uio_info *dev_info);//中断信息处理
    int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);//内存映射操作
    int (*open)(struct uio_info *info, struct inode *inode);//打开
    int (*release)(struct uio_info *info, struct inode *inode);//释放
    int (*irqcontrol)(struct uio_info *info, s32 irq_on);//中断控制操作 关闭/打开 当向/dev/uioX中写入值时
};

  uio核心部分是一个名为"uio"的字符设备(下文称为“uio核心字符设备“)。用户驱动的内核部分使用uio_register_device向uio核心部分 注册uio设备。uio 核心的任务就是管理好这些注册的uio设备。这些uio设备使用的数据结构是 uio_device。而这些设备属性,比如name, open(), release()等操作都放在了uio_info结构中,用户使用 uio_register_device注册这些驱动之前 要设置好uio_info

文章推荐:DPDK的学习资料及学习路线总结图点击:DPDK学习资料 获取及学习路线总结图

igb_uio.ko初始化主要是做了两件事:

  1. 第一件事是配置中断模式;

  2. 第二种模式便是注册驱动

static struct pci_dri
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值