当前位置: 首页 > news >正文

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中字符设备的打开、写入

一个内核模块应该由以下几部分组成。 第一部分&#xff0c;头文件部分。一般的内核模块&#xff0c;都需要 include 下面两个头文件&#xff1a; #include <linux/module.h> #include <linux/init.h> 第二部分&#xff0c;定义一些函数&#xff0c;用于处理内核…...

3d max软件中的缓存垃圾该如何清理?

使用3d max建模到渲染操作&#xff0c;来回对效果图调整的次数过多时&#xff0c;就会出现一下看不到的垃圾缓存&#xff0c;影响保存的速度&#xff0c;影响效率&#xff01; 对于这类的3d垃圾清理的有什么高效方法呢&#xff1f; 3dmax垃圾清理的常规操作如下&#xff1a; 1、…...

11.13 牛客刷题8/10

11.13 信号完整性 指针地址 的加减&#xff0c;注意 最后转为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流水线 从最初的瀑布模型&#xff0c;到后来的敏捷开发&#xff0c;再到今天的DevOps&#xff0c;这是现代开发人员构建出色产品的技术路…...

python opencv 读取文件夹下所有MP4文件并解析成jpg图像

你可以使用Python的OpenCV库来读取文件夹中的所有MP4文件&#xff0c;并将其解析为JPG图像。以下是一个示例代码&#xff0c;演示了如何实现这个功能&#xff0c;并设置解析间隔为3帧&#xff1a; import os import cv2def extract_frames(input_folder, output_folder, inter…...

MySQL binlog 日志解析后的exec_time导致表示什么时间?

1. exec_time 到底表示什么时间&#xff1f; MySQL binlog日志解析后&#xff0c;我们能看到会有 exec_time &#xff0c;从字面意思理解这个记录的是执行时间&#xff0c;那这个记录的到底是单条sql的执行时间&#xff1f;还是事务的执行时间&#xff1f;下面通过测试来解读一…...

【Linux】:git基本操作_添加文件_两种场景_查看.git文件 || git修改文件 || 版本回退

&#x1f3af;添加⽂件–场景⼀ &#x1f3af;在包含.git的⽬录下新建⼀个ReadMe⽂件&#xff0c;我们可以使⽤ git add 命令可以将⽂件添加到暂存区&#xff1a; • 添加⼀个或多个⽂件到暂存区&#xff1a; git add [file1] [file2] … • 添加指定⽬录到暂存区&#xff0c;…...

Django 基于ORM的CURD、外键关联,请求的生命周期

文章目录 基于ORM进行的CURDORM外键关联Django请求的生命周期流程图 基于ORM进行的CURD 本质上就是通过面向对象的方式&#xff0c;对数据库的数据进行增、删、改、查。 这里将会将我们之前所有内容结合到一起&#xff0c;首先确保基于上序操作已经建立好了UserInfo表&#xff…...

集合贴4——QA机器人设计与优化

基础课21——知识库管理-CSDN博客文章浏览阅读342次&#xff0c;点赞6次&#xff0c;收藏2次。知识库中有什么信息内容&#xff0c;决定了智能客服机器人在回答时可以调用哪些信息内容&#xff0c;甚至可以更简单地理解为这是智能客服机器人的话术库。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实例有什么区别&#xff1f;如何选择&#xff1f;ECS经济型e实例是共享型云服务器&#xff0c;通用算力型u实例是企业级独享型云服务器&#xff0c;e实例性价比高&#xff0c;现在2核2G3M带宽一年99元&#xff0c;云服务器u1价格相对要…...

modbus-TCP协议详解

modbus-TCP协议详解 1996年施耐德公司推出基于以太网TCP/IP的modbus协议&#xff1a;modbus-TCP。 MODBUS-TCP使MODBUS-RTU协议运行于以太网&#xff0c;MODBUS-TCP使用TCP/IP以太网在站点间传送MODBUS报文&#xff0c;MODBUS-TCP结合了以太网物理网络和网络标准TCP/IP以及以…...

爬虫项目(12):正则、多线程抓取腾讯动漫,Flask展示数据

文章目录 书籍推荐正则抓取腾讯动漫数据Flask展示数据 书籍推荐 如果你对Python网络爬虫感兴趣&#xff0c;强烈推荐你阅读《Python网络爬虫入门到实战》。这本书详细介绍了Python网络爬虫的基础知识和高级技巧&#xff0c;是每位爬虫开发者的必读之作。详细介绍见&#x1f44…...

gedit编辑文件时常用快捷键

问题&#xff1a; 最近在修改文件时提到了gedit这个工具&#xff0c;与vi一样也是一个文件编辑器。但是在命令方面又有不同&#xff0c;在快捷键方面和Windows的使用习惯非常相似。 gedit举例&#xff1a; CTRL-Z:撤销CTRL-C:复制CTRL-V:粘贴CTRL-T:缩进CTRL-Q:退出CTRL-S:保…...

【C++干货铺】剖析string | 底层实现

个人主页点击直达&#xff1a;小白不是程序媛 C专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 成员变量 成员函数 构造和拷贝构造 赋值重载 析构函数 operator[ ] size 迭代器 reserve&#xff08;扩容函数&#xff09; push_back(尾插函数&#xff09…...

nmap原理与使用

kali的命令行中可以直接使用 nmap 命令&#xff0c;打开一个「终端」&#xff0c;输入 nmap 后回车&#xff0c;可以看到 nmap 的版本&#xff0c;证明 nmap 可用。 一、端口扫描 扫描主机的「开放端口」&#xff0c;在nmap后面直接跟主机IP&#xff08;默认扫描1000个端口&am…...

AI批量剪辑矩阵托管系统----源码技术开发

AI批量剪辑矩阵托管系统----源码技术开发 抖音账号矩阵系统是基于抖音开放平台研发的用于管理和运营多个抖音账号的平台。它可以帮助用户管理账号、发布内容、营销推广、分析数据等多项任务&#xff0c;从而提高账号的曝光度和影响力。 具体来说&#xff0c;抖音账号矩阵系统可…...

Pandas数据预处理python 数据分析之4——pandas 预处理在线闯关_头歌实践教学平台

Pandas数据预处理python 数据分析之4——pandas 预处理 第1关 数据读取与合并第2关 数据清洗第3关 数据转换 第1关 数据读取与合并 任务描述 本关任务&#xff1a;加载 csv 数据集&#xff0c;实现 DataFrame 合并。 编程要求 根据提示&#xff0c;在右侧编辑器补充代码&#…...

[html] 动态炫彩渐变背景

废话不多说&#xff0c;直接上源码 <!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 想要生成高清分辨率的图片。在文生图的功能里&#xff0c;需要设置更大的宽度和高度。在图生图的功能里&#xff0c;需要设置更大的重绘尺寸或者重绘尺寸。但是设置完更大的图像分辨率&#xff0c;需要更大显存&#xff0c;1024*1024的至少要电脑的空…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...

Canal环境搭建并实现和ES数据同步

作者&#xff1a;田超凡 日期&#xff1a;2025年6月7日 Canal安装&#xff0c;启动端口11111、8082&#xff1a; 安装canal-deployer服务端&#xff1a; https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...