Linux中字符设备的打开、写入
一个内核模块应该由以下几部分组成。
第一部分,头文件部分。一般的内核模块,都需要 include 下面两个头文件:
#include <linux/module.h>
#include <linux/init.h>
第二部分,定义一些函数,用于处理内核模块的主要逻辑。例如打开、关闭、读取、写入设备的函数或者响应中断的函数。
例如,logibm.c 里面就定义了 logibm_open。logibm_close 就是处理打开和关闭的,定义了 logibm_interrupt 就是用来响应中断的。再如,lp.c 里面就定义了 lp_read,lp_write 就是处理读写的。
第三部分,定义一个 file_operations 结构。设备是可以通过文件系统的接口进行访问的。对于某种文件系统的操作,都是放在 file_operations 里面的。例如 ext4 就定义了这么一个结构,里面都是 ext4_xxx 之类的函数。设备要想被文件系统的接口操作,也需要定义这样一个结构。
例如,lp.c 里面就定义了这样一个结构。
static const struct file_operations lp_fops = {.owner = THIS_MODULE,.write = lp_write,.unlocked_ioctl = lp_ioctl,
#ifdef CONFIG_COMPAT.compat_ioctl = lp_compat_ioctl,
#endif.open = lp_open,.release = lp_release,
#ifdef CONFIG_PARPORT_1284.read = lp_read,
#endif.llseek = noop_llseek,
};
在 logibm.c 里面,我们找不到这样的结构,是因为它属于众多输入设备的一种,而输入设备的操作被统一定义在 drivers/input/input.c 里面,logibm.c 只是定义了一些自己独有的操作。
static const struct file_operations input_devices_fileops = {.owner = THIS_MODULE,.open = input_proc_devices_open,.poll = input_proc_devices_poll,.read = seq_read,.llseek = seq_lseek,.release = seq_release,
};
第四部分,定义整个模块的初始化函数和退出函数,用于加载和卸载这个 ko 的时候调用。
例如 lp.c 就定义了 lp_init_module 和 lp_cleanup_module,logibm.c 就定义了 logibm_init 和 logibm_exit。
第五部分,调用 module_init 和 module_exit,分别指向上面两个初始化函数和退出函数。
第六部分,声明一下 lisense,调用 MODULE_LICENSE。有了这六部分,一个内核模块就基本合格了,可以工作了。
打开字符设备

在字符设备驱动的内核模块加载的时候,最重要的一件事情就是,注册这个字符设备。注册的方式是调用 __register_chrdev_region,注册字符设备的主次设备号和名称,然后分配一个 struct cdev 结构,将 cdev 的 ops 成员变量指向这个模块声明的 file_operations。然后,cdev_add 会将这个字符设备添加到内核中一个叫作 struct kobj_map *cdev_map 的结构,来统一管理所有字符设备。
写入字符设备

写入一个字符设备,就是用文件系统的标准接口 write,参数文件描述符 fd,在内核里面调用的 sys_write,在 sys_write 里面根据文件描述符 fd 得到 struct file 结构。
一个字符设备要能够工作,需要三部分配合。
第一,有一个设备驱动程序的 ko 模块,里面有模块初始化函数、中断处理函数、设备操作函数。这里面封装了对于外部设备的操作。加载设备驱动程序模块的时候,模块初始化函数会被调用。在内核维护所有字符设备驱动的数据结构 cdev_map 里面注册,我们就可以很容易根据设备号,找到相应的设备驱动程序。
第二,在 /dev 目录下有一个文件表示这个设备,这个文件在特殊的 devtmpfs 文件系统上,因而也有相应的 dentry 和 inode。这里的 inode 是一个特殊的 inode,里面有设备号。通过它,我们可以在 cdev_map 中找到设备驱动程序,里面还有针对字符设备文件的默认操作 def_chr_fops。
第三,打开一个字符设备文件和打开一个普通的文件有类似的数据结构,有文件描述符、有 struct file、指向字符设备文件的 dentry 和 inode。字符设备文件的相关操作 file_operations 一开始指向 def_chr_fops,在调用 def_chr_fops 里面的 chrdev_open 函数的时候,修改为指向设备操作函数,从而读写一个字符设备文件就会直接变成读写外部设备了。

此文章为11月Day12学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。
相关文章:
Linux中字符设备的打开、写入
一个内核模块应该由以下几部分组成。 第一部分,头文件部分。一般的内核模块,都需要 include 下面两个头文件: #include <linux/module.h> #include <linux/init.h> 第二部分,定义一些函数,用于处理内核…...
3d max软件中的缓存垃圾该如何清理?
使用3d max建模到渲染操作,来回对效果图调整的次数过多时,就会出现一下看不到的垃圾缓存,影响保存的速度,影响效率! 对于这类的3d垃圾清理的有什么高效方法呢? 3dmax垃圾清理的常规操作如下: 1、…...
11.13 牛客刷题8/10
11.13 信号完整性 指针地址 的加减,注意 最后转为16进制...
CI/CD简介
CI/CD简介 1、CI/CD流水线2、什么是CI/CD3、CI/CD的优点4、CI/CD的工作原理5、CI/CD流水线工具6、CI/CD的应用7、CI/CD的未来趋势 1、CI/CD流水线 从最初的瀑布模型,到后来的敏捷开发,再到今天的DevOps,这是现代开发人员构建出色产品的技术路…...
python opencv 读取文件夹下所有MP4文件并解析成jpg图像
你可以使用Python的OpenCV库来读取文件夹中的所有MP4文件,并将其解析为JPG图像。以下是一个示例代码,演示了如何实现这个功能,并设置解析间隔为3帧: import os import cv2def extract_frames(input_folder, output_folder, inter…...
MySQL binlog 日志解析后的exec_time导致表示什么时间?
1. exec_time 到底表示什么时间? MySQL binlog日志解析后,我们能看到会有 exec_time ,从字面意思理解这个记录的是执行时间,那这个记录的到底是单条sql的执行时间?还是事务的执行时间?下面通过测试来解读一…...
【Linux】:git基本操作_添加文件_两种场景_查看.git文件 || git修改文件 || 版本回退
🎯添加⽂件–场景⼀ 🎯在包含.git的⽬录下新建⼀个ReadMe⽂件,我们可以使⽤ git add 命令可以将⽂件添加到暂存区: • 添加⼀个或多个⽂件到暂存区: git add [file1] [file2] … • 添加指定⽬录到暂存区,…...
Django 基于ORM的CURD、外键关联,请求的生命周期
文章目录 基于ORM进行的CURDORM外键关联Django请求的生命周期流程图 基于ORM进行的CURD 本质上就是通过面向对象的方式,对数据库的数据进行增、删、改、查。 这里将会将我们之前所有内容结合到一起,首先确保基于上序操作已经建立好了UserInfo表ÿ…...
集合贴4——QA机器人设计与优化
基础课21——知识库管理-CSDN博客文章浏览阅读342次,点赞6次,收藏2次。知识库中有什么信息内容,决定了智能客服机器人在回答时可以调用哪些信息内容,甚至可以更简单地理解为这是智能客服机器人的话术库。https://blog.csdn.net/22…...
【Verilog语法】
Verilog语法 1. Verilog语法1.1 拼接运算符1.2 运算符优先级1.3 注释1.4 关键字1.5 模块结构1.6 结构语句1.7 赋值语句1.8 条件语句1.9 状态机1.10 OSI七层模型 1. Verilog语法 1.1 拼接运算符 1.2 运算符优先级 1.3 注释 1.4 关键字 1.5 模块结构 1.6 结构语句 1.7 赋值语句 …...
阿里云通用算力型u1服务器和e实例有什么区别?选择攻略
阿里云服务器ECS经济型e实例和通用算力型u1实例有什么区别?如何选择?ECS经济型e实例是共享型云服务器,通用算力型u实例是企业级独享型云服务器,e实例性价比高,现在2核2G3M带宽一年99元,云服务器u1价格相对要…...
modbus-TCP协议详解
modbus-TCP协议详解 1996年施耐德公司推出基于以太网TCP/IP的modbus协议:modbus-TCP。 MODBUS-TCP使MODBUS-RTU协议运行于以太网,MODBUS-TCP使用TCP/IP以太网在站点间传送MODBUS报文,MODBUS-TCP结合了以太网物理网络和网络标准TCP/IP以及以…...
爬虫项目(12):正则、多线程抓取腾讯动漫,Flask展示数据
文章目录 书籍推荐正则抓取腾讯动漫数据Flask展示数据 书籍推荐 如果你对Python网络爬虫感兴趣,强烈推荐你阅读《Python网络爬虫入门到实战》。这本书详细介绍了Python网络爬虫的基础知识和高级技巧,是每位爬虫开发者的必读之作。详细介绍见ὄ…...
gedit编辑文件时常用快捷键
问题: 最近在修改文件时提到了gedit这个工具,与vi一样也是一个文件编辑器。但是在命令方面又有不同,在快捷键方面和Windows的使用习惯非常相似。 gedit举例: CTRL-Z:撤销CTRL-C:复制CTRL-V:粘贴CTRL-T:缩进CTRL-Q:退出CTRL-S:保…...
【C++干货铺】剖析string | 底层实现
个人主页点击直达:小白不是程序媛 C专栏:C干货铺 代码仓库:Gitee 目录 成员变量 成员函数 构造和拷贝构造 赋值重载 析构函数 operator[ ] size 迭代器 reserve(扩容函数) push_back(尾插函数)…...
nmap原理与使用
kali的命令行中可以直接使用 nmap 命令,打开一个「终端」,输入 nmap 后回车,可以看到 nmap 的版本,证明 nmap 可用。 一、端口扫描 扫描主机的「开放端口」,在nmap后面直接跟主机IP(默认扫描1000个端口&am…...
AI批量剪辑矩阵托管系统----源码技术开发
AI批量剪辑矩阵托管系统----源码技术开发 抖音账号矩阵系统是基于抖音开放平台研发的用于管理和运营多个抖音账号的平台。它可以帮助用户管理账号、发布内容、营销推广、分析数据等多项任务,从而提高账号的曝光度和影响力。 具体来说,抖音账号矩阵系统可…...
Pandas数据预处理python 数据分析之4——pandas 预处理在线闯关_头歌实践教学平台
Pandas数据预处理python 数据分析之4——pandas 预处理 第1关 数据读取与合并第2关 数据清洗第3关 数据转换 第1关 数据读取与合并 任务描述 本关任务:加载 csv 数据集,实现 DataFrame 合并。 编程要求 根据提示,在右侧编辑器补充代码&#…...
[html] 动态炫彩渐变背景
废话不多说,直接上源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>ZXW-NUDT: 动态炫…...
AI 绘画 | Stable Diffusion 高清修复、细节优化
前言 在 Stable Diffusion 想要生成高清分辨率的图片。在文生图的功能里,需要设置更大的宽度和高度。在图生图的功能里,需要设置更大的重绘尺寸或者重绘尺寸。但是设置完更大的图像分辨率,需要更大显存,1024*1024的至少要电脑的空…...
Godot中型项目工程化实践:目录规范、资源引用与状态管理
1. 这不是续集,而是项目落地的分水岭“Godot 游戏引擎项目(二)”——看到这个标题,很多人第一反应是:“哦,上一篇讲了环境搭建和Hello World,这篇该讲节点树和信号了?”但我在带三个…...
DeepSeek基准测试避坑手册:92%开发者忽略的4大陷阱——硬件配置偏差、tokenizer不一致、batch size幻觉、温度值污染
更多请点击: https://codechina.net 第一章:DeepSeek基准测试避坑手册:92%开发者忽略的4大陷阱——硬件配置偏差、tokenizer不一致、batch size幻觉、温度值污染 硬件配置偏差:GPU显存与计算精度的隐性干扰 在A100(8…...
[智能体-81]:工程化智能体 = 模型做脑力拆解 + 框架做流程落地。前者是决策者,后者是管理者,tools/function call是内部员工;mcp server是外部资源;
一、全角色人设 & 对应技术组件角色定位对应技术模块核心职责决策者(脑力大脑)大模型 LLM理解目标、任务拆解、逻辑判断、分支决策、内容生成,负责 “想方案、定步骤”管理者(流程总管)智能体编排框架(…...
开发转兼职DBA(二):执行计划教我做事
开发转兼职DBA(二):执行计划教我做事 查询慢了不知道为什么,加了索引还是慢,复合索引怎么建,执行计划怎么看——这些不是DBA的专利,是每个写SQL的开发者迟早要面对的事。 文章目录 开发转兼职DB…...
Burp Suite拦截与替换机制深度解析:从协议层到规则链
1. 这不是“点开就能用”的功能,而是你和目标系统之间的一道可编程闸门很多人第一次在Burp Suite里点开Proxy → Intercept,看到HTTP请求被拦下来,兴奋地改个User-Agent、删个Cookie就点Forward,以为自己已经掌握了“拦截与替换”…...
Postgresql基础实践教程(八)
⭐️⭐️⭐️⭐️⭐️ 完整数据详见 练习数据免费 ⭐️⭐️⭐️⭐️⭐️ 六十九、查找会员ID 27的向上推荐链 问题 查找会员ID 27的向上推荐链:即推荐该会员的人,以及推荐那个人的人,依此类推。返回会员ID、名字和姓氏。按会员ID降序排列。…...
Jetson Orin上TVA模型DLA精准卸载配置
重磅预告:本专栏将独家连载系列丛书《智能体视觉技术与应用》部分精华内容,该书是世界首套系统阐述“因式智能体”视觉理论与实践的专著,特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“…...
别再把大模型当搜索框了:一文讲透 LLM 的基本原理、能力边界与局限性
写在前面很多人把大语言模型当成“会聊天的搜索引擎”,结果一上线就遇到幻觉、口径不稳、上下文丢失、成本失控。真正理解 LLM,要先抓住一句话:它是基于 Transformer 的概率生成模型,核心能力来自海量预训练、上下文学习与后训练对…...
昇腾CANN cmake 实战:CANN CMake 构建系统——跨平台编译配置与模块化管理
8 个 CANN 仓库各需独立构建(ops-transformer/ops-nn/hccl/ge/…)→ 手写 8 套 CMakeLists.txt(CANN 路径判断、跨 NPU 型号编译、第三方库兼容)。cmake 仓库提供统一的 FindCANN.cmake CANNConfig.cmake 模板——任何仓库只需 f…...
机器学习赋能矩方法:破解稀薄气体强非平衡流动模拟难题
1. 项目概述:当矩方法遇见机器学习在计算流体力学领域,模拟稀薄气体动力学和强非平衡流动,一直是个让工程师和科学家们头疼的“硬骨头”。想象一下,你正在设计一架高超音速飞行器,当它以数倍音速在大气层边缘飞行时&am…...
