第六章 字符设备驱动

6.1 Linux字符设备驱动结构

  1. cdev结构体
    1. Linux中用cdev结构体描述字符设备,主要成员变量:所属模块、file_operations结构体、dev_t 类型的设备号

    2. 成员变量:
      1. 设备号dev_t为u32类型,前12位为主设备号,后20位为次设备号,以下宏定义可获取:
        1. MAJOR(dev_t dev)
        2. MINOR(dev_t dev)
        3. MKDEV(int major, int minor)
      2. file_operations:字符设备驱动提供给虚拟文件系统的接口
    3. 对cdev的操作:
      1. void cdev_init(struct cdev *, struct file_operations *); 初始化cdev成员,与file_operations建立连接
      2.  struct cdev *cdev_alloc(void); 动态申请一个cdev内存
      3. void cdev_put(struct cdev *p); 
      4. int cdev_add(struct cdev *, dev_t, unsigned);
      5.  void cdev_del(struct cdev *);

  2. 分配和释放设备号
    1. cdev_add()之前应该向系统申请设备号;在cdev_del()之后应该释放设备号

    2. 设备号申请:

      1. 静态申请:register_chrdev_region();

      2. 动态申请:alloc_chrdev_region();

    3. 设备号释放:unregister_chrdev_region();
  3. file_operations结构体(主要成员分析)
    1. llseek()修改一个文件的当前读写位置,返回新位置

    2. read()函数用来从设备中读取数据,成功时函数返回读取的字节数

    3. write()函数向设备发送数据,成功时该函数返回写入的字节数。

    4. unlocked_ioctl()提供设备相关控制命令的实现

    5. mmap()函数将设备内存映射到进程的虚拟地址空间中

    6. 驱动程序可以不实现open(),在这种情况下,设备的打开操作永远成功。与open()函数对应的是release()函数。

    7. poll()函数一般用于询问设备是否可被非阻塞地立即读写。当询问的条件未触发时,用户空间进行select()和poll()系统调用将引起进程的阻塞。

    8. aio_read()和aio_write()函数分别对与文件描述符对应的设备进行异步读、写操作。

  4. Linux字符设备驱动的组成
    1. 字符设备驱动模块加载与卸载函数
      1. 设备号的申请与释放
      2. cdev结构体的注册与注销
      3. Linux习惯定义一个设备结构体,包含设备信息
    2. 字符设备驱动的file_operations结构体中成员函数

  5. 用户空间不能直接访问内核空间内存
    1. copy_from_user();
    2. copy_to_user();
    3. 若是简单类型,可以使用:put_user()和get_user()
    4. 在访问用户空间缓冲区时,必须检查合法性,使用access_ok()函数进行判断,上述四个函数已经进行了合法性检查。
       

6.2 globalmem虚拟设备实例描述

  1. ioctl()命令生成可防止命令码污染
  2. I/O控制命令的组成

    设备类型

    序列号

    方向

    数据尺寸

    8位“幻数”8位2位(无、读、写、双向)13/14位
  3. 用宏定义生成I/O命令:

    1. _IO、_IOR、_IOW、_IORW

    2. eg: #define     MEM_CLEAR     _IO('g', 0x1)    其中’g‘为幻数,0x1为序号

    3. 内核中预定义了一些I/O控制命令,如果某设备驱动中包含了与预定义命令一样的命令码,这些命令会作为预定义命令被内核处理而不是被设备驱动处理

  4. 使用文件私有数据:
    1. 将文件私有数据private_data指向设备结构体,再用其他函数通过private_data访问设备结构体。
    2. container_of()可以通过结构体成员的指针找到对应结构体的指针,形式参数分别为第1个参数是结构体成员的指针,第2个参数为整个结构体的类型,第3个参数为传入的第1个参数即结构体成员的类型,返回值为整个结构体的指针
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值