设备驱动之UIO机制

UIO(User-space I/O)机制允许用户空间直接处理设备内存和中断,简化了设备驱动的编写。在内核中,UIO驱动通过uio_register_device()注册,用户态则通过mmap()和read()操作设备。UIO适用于处理简单中断和内存访问的设备,如在DPDK中,igb_uio模块展示了如何注册和操作PCI设备。
摘要由CSDN通过智能技术生成

一个设备驱动的主要任务有两个:

  • 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框架以及内核内部函数的关系。

​二:UIO驱动注册

首先来看一个简单的UIO驱动代码

内核部分:

/*

* This is simple demon of uio driver.

* Version 1

*Compile:
*    Save this file name it simple.c
*    #echo "obj -m := simple.o" > Makefile
*    #make -Wall -C /lib/modules/'uname -r'/build M='pwd' modules
*Load the module:
*    #modprobe uio
*    #insmod simple.ko
*/



#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/uio_driver.h>
#include <linux/slab.h>


/*struct uio_info { 
    struct uio_device   *uio_dev; // 在__uio_register_device中初始化
    const char      *name; // 调用__uio_register_device之前必须初始化
    const char      *version; //调用__uio_register_device之前必须初始化
    struct uio_mem      mem[MAX_UIO_MAPS];
    struct uio_port     port[MAX_UIO_PORT_REGIONS];
    long            irq; //分配给uio设备的中断号,调用__uio_register_device之前必须初始化
    unsigned long       irq_flags;// 调用__uio_register_device之前必须初始化
    void            *priv; //
    irqreturn_t (*handler)(int irq, struct uio_info *dev_info); //uio_interrupt中调用,用于中断处理
                                                                // 调用__uio_register_device之前必须初始化
    int (*mmap)(struct uio_info *info, struct vm_area_struct *vma); //在uio_mmap中被调用,
                                                                // 执行设备打开特定操作
    int (*open)(struct uio_info *info, struct inode *inode);//在uio_open中被调用,执行设备打开特定操作
    int (*release)(struct uio_info *info, struct inode *inode);//在uio_device中被调用,执行设备打开特定操作
    int (*irqcontrol)(struct uio_info *
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值