趣谈 Linux 操作系统
刘超
前网易杭州研究院云计算技术部首席架构师
85459 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 72 讲
趣谈 Linux 操作系统
15
15
1.0x
00:00/00:00
登录|注册

32 | 字符设备(上):如何建立直销模式?

设想自己写一个字符设备驱动程序应该实现哪些函数
三部分配合:设备驱动程序的ko模块、/dev目录下的文件、打开字符设备文件的数据结构
调用设备驱动程序的ioctl函数
调用ioctl系统调用
调用设备驱动程序的write函数
调用vfs_write
打开设备文件
创建设备文件
注册字符设备
声明lisense,调用MODULE_LICENSE
调用module_init和module_exit
定义模块的初始化函数和退出函数
定义file_operations结构
定义处理内核模块的主要逻辑的函数
头文件部分
课堂练习
总结时刻
使用IOCTL控制设备
写入字符设备
打开字符设备
内核模块
字符设备驱动程序

该思维导图由 AI 生成,仅供参考

上一节,我们讲了输入输出设备的层次模型,还是比较复杂的,块设备尤其复杂。这一节为了让你更清晰地了解设备驱动程序的架构,我们先来讲稍微简单一点的字符设备驱动。
这一节,我找了两个比较简单的字符设备驱动来解析一下。一个是输入字符设备,鼠标。代码在 drivers/input/mouse/logibm.c 这里。
/*
* Logitech Bus Mouse Driver for Linux
*/
module_init(logibm_init);
module_exit(logibm_exit);
另外一个是输出字符设备,打印机,代码 drivers/char/lp.c 这里。
/*
* Generic parallel printer driver
*/
module_init(lp_init_module);
module_exit(lp_cleanup_module);

内核模块

上一节,我们讲过,设备驱动程序是一个内核模块,以 ko 的文件形式存在,可以通过 insmod 加载到内核中。那我们首先来看一下,怎么样才能构建一个内核模块呢?
一个内核模块应该由以下几部分组成。
第一部分,头文件部分。一般的内核模块,都需要 include 下面两个头文件:
#include <linux/module.h>
#include <linux/init.h>
如果你去看上面两个驱动程序,都能找到这两个头文件。当然如果需要的话,我们还可以引入更多的头文件。
第二部分,定义一些函数,用于处理内核模块的主要逻辑。例如打开、关闭、读取、写入设备的函数或者响应中断的函数。
例如,logibm.c 里面就定义了 logibm_open。logibm_close 就是处理打开和关闭的,定义了 logibm_interrupt 就是用来响应中断的。再如,lp.c 里面就定义了 lp_read,lp_write 就是处理读写的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入分析了字符设备驱动程序的架构和内核模块的构建,通过两个简单的字符设备驱动程序,即鼠标和打印机的驱动程序,为读者详细介绍了字符设备的打开、写入和ioctl等最常见的操作。文章首先介绍了内核模块的基本组成部分,包括头文件部分、处理内核模块主要逻辑的函数定义、file_operations结构的定义、模块的初始化和退出函数的定义以及lisense的声明。通过具体的代码示例和解释,帮助读者更清晰地了解了设备驱动程序的架构和内核模块的构建过程。在加载字符设备驱动的过程中,注册字符设备是重要的一步,而后通过mknod在/dev下创建设备文件,最终打开设备文件。通过对字符设备的打开过程进行详细解析,读者可以了解设备驱动程序的内部工作原理。此外,文章还介绍了写入字符设备和使用IOCTL控制设备的过程,以及对应的代码实现和解析。这份技术资料对于想要深入了解操作系统内核开发的读者来说具有重要的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《趣谈 Linux 操作系统》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • geraltlaush
    另外贴上一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各设备。

    作者回复: 赞

    2019-06-10
    2
    7
  • 有铭
    问一下老师你的这些图是用啥工具画的?

    作者回复: draw.io

    2019-06-10
    4
  • geraltlaush
    还有个收获就是程序设计的面向对象的思想,之前开发一个音视频推流服务器,一个音视频类型的操作编码解码都是类中完成,现在看来可以把操作单独设计成一个基类,各种类型的音视频操作都可以继承这个类,代码可以设计的更为优雅

    作者回复: 是的

    2019-06-10
    3
  • ezra.xu
    除了open,close,read,write等,是不是可以加入些异常捕获,异步操作,多线程的函数……

    作者回复: 这就太复杂啦,每一篇文章都找到一本书

    2019-06-11
  • 西山薄凉
    课代表不在了,我来当课代表。 ## 字符设备 ### 内核模块 - 驱动程序的内核模块,以 ko 的文件形式存在,可以通过 insmod 加载到内核中 - 一个内核模块应该由以下几部分组成 - 头文件部分:include <linux/module.h> 及 <linux/init.h> - 定义以内科模块处理逻辑的函数,如开、关、读写及响应中断。 - 定义一个 file_operations 接口,使得对上层接口统一 - 定义整个模块的初始化和退出函数 - 调用 module_init 和 module_exit,分别指向上面两个初始化函数和退出函数 - 声明一下 lisense,调用 MODULE_LICENSE ### 打开字符设备 - 打开字符设备 - 注册字符设备:通过 insmod 加载进内核 - 调用 __register_chrdev_region - 注册设备的主次设备号和名称 - 初始化 cdev 结构体,将其 ops 成员指向设备定义的 file_operations - 调用 cdev_add 将设备添加到内核中的 cdev_map,统一管理字符设备 - 创建设备文件:通过 mknod 在 /dev 下面创建一个设备文件 - 找到设备文件所在的文件夹,然后为这个新创建的设备文件创建一个 dentry,用于关联文件和 inode - 创建特殊 inode,用于关联设备(还可关联FIFO文件、socket等) - 打开设备文件:调用 inode 的 open 函数 - 如果 cdev 还没有关联,从 cdev_map 中找到 cdev 并关联 - 找到 cdev 的 file_operations,将其设置给文件描述符 - 调用设备驱动程序的 file_operations 的 open 函数,真正打开设备 ### 写入字符设备 - 写入字符设备 - 调用文件系统标准接口 write,参数为设备的文件描述符 - 由于已经将 file_operations 替换成了设备的,所以会直接调用设备定义的 write(多态) ### IOCTL控制设备 - 发送 IOCTL 信令控制设备 - cmd 组成(32位): - 最低 8 位为 NR,是命令号; - 然后 8 位是 TYPE,是类型; - 然后 14 位是参数的大小; - 最高 2 位是 DIR,是方向,表示写入、读出,还是读写。 - 有对应的宏方便操作 cmd - 调用 do_vfs_ioctl,分支判断 cmd 执行对应操作,分为以下几种 - 默认定义好的 cmd,执行系统默认操作 - 普通文件,调用 file_ioctl - 其他文件调用 vfs_ioctl - vfs_ioctl 内部还是会直接调用设备定义的 cmd 对应的接收函数,里面对不同 cmd 执行不同操作
    2020-03-01
    2
    31
  • 小鳄鱼
    虚拟文件系统,统一所有设备操作。而这个设计,看起来只是使用多态,但是实际上这是抽象出来的统一操作层。有这个想法,要实现对各种各样的设备,繁杂的功能而言,并不简单!而抽象本身,就很复杂了,值得继续深入!!!
    2022-05-19
    1
  • 功夫熊猫
    老师,能不能把源代码传一份
    2023-05-10归属地:江苏
  • 浩仔是程序员
    驱动程序里面的write方法是怎么操作打印机的?是不是要把数据写到指定io端口中?
    2022-11-25归属地:广东
  • 核桃
    字符设备驱动程序没有了解过,但是在github上面找到过实现自定义文件系统的hellofs,这个可以核心关键还是自定义的file operations和注册这些,大同小异的
    2021-05-05
  • 耿长学
    /proc文件系统的原理是实现是基于什么?/proc里面这些文件使用的是内存存放还是磁盘存放的,当命令终止后这些文件又去了哪里,怎么销毁的,谢谢,之前买了网络协议的学了不去网络原理
    2019-12-11
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部