当前课程知识点:Linux 内核分析与应用 > 第9章 设备驱动 > 9.6 动手实践-编写字符设备驱动程序 > Video
大家好
本节视频来给大家分享一下
字符设备驱动程序的编写
参考资料是张天飞老师的《奔跑吧Linux内核》
在Linux内核中
字符设备是由dev结构体来描述的
它位于
include/linux/cdev.h中
使用
list字段来将所有的字符设备组织成一个链表
在之前的课程中可以了解到
每一个设备由主设备号和次设备号共同确定
dev
就是字符设备的设备号
包括主设备号和次设备号
count字段是同一个主设备号
中次设备号的个数
Linux的设备驱动程序
可以由两种方式来定义
一种是全局静态变量
另一种就是使用内核提供的API
这里采用第二种方式来实现一个简单的虚拟设备的驱动
并且实现它的读写功能 我们来看代码
首先看内核态代码
看内核模块初始化函数
执行alloc_chrdev_region()函数
进入源代码
位于fs文件夹下chardev.c中
之后会执行
_register_chrdev_region()函数
第一个参数为0
进入 可以看到0的意思实际上是
自动分配主设备号
之后使用cdev_alloc()函数来分配空间
在这里定义的是
struct cdev *类型
这一个函数就是分配空间
接下来会执行cdev_init()
并执行fops的赋值操作
进入源代码 首先是cdev_alloc()函数
它会分配空间并返回一个cdev
结构体的指针
接下来是cdev_init()函数
也是初始化cdev
但是多了一步是赋值fops
这里使用的是memset()函数
也就是如果定义的是
struct cdev结构体
而不是指针类型 只需要执行cdev_init()就可以了
接下来执行cdev_add()
把这个设备添加到系统中
在实现的方法中 我们在
open操作中打印主次设备号
这是linux内核提供读设备的
主设备号和次设备号的方法
func__宏
宏获取当前的函数名
在read和write方法中 仅打印函数名
看一下MAJOR和MINOR两个方法在内核中的定义
它位于include/linux目录下K
dev_t.h文件中
可以看到次设备号的位数是20
在这里读取它的主设备号
在这里读取次设备号
这个MKDEV是生成设备号的
在给设备的操作中
是定义在这里的
实现open read和write
注意它是struct file_operations
和在文件系统中使用的是相同的结构体
接下来编译内核模块
使用dmesg查看内核消息
在这里看到已经成功地注册了字符设备
这是设备名
主设备号是243 次设备号是0
另外生成的设备需要在/dev目录下生成对应的节点
这里需要手动生成 使用mknod命令
c代表字符设备
主设备号是243 次设备号是0
之后查看/dev目录的情况
在这里
接下来使用用户空间的测试程序
来测试这个字符设备驱动
在这个测试文件中定义设备的路径
只进行一个open操作
来编译用户态测试程序
执行
打印内核消息
打印出了open和read的方法
字符设备驱动也可采用misc机制来进行注册
也就是Linux将一些不符合预先确定的
字符设备划分为杂项设备
这类设备的主设备号是10
内核中使用miscdevice结构体来描述
如果使用misc机制来创建设备
就需要定义miscdevice结构体
来看一下第二个实验
来看内核模块初始化函数
首先使用内核API:misc_register()
函数来注册
可以自动创建设备节点
不需要使用mknod来手动创建设备节点
传入的参数是定义的miscdevice结构体的地址
是在这里进行定义的
设备的名称是my_demo_dev
最后一个是设备相应的操作
来看一下misc_register()的源码
在drives/char/misc.c文件中
可以看到动态分配次设备号的过程
之后生成设备号dev 也就是之前的MKDEV宏
最后添加进链表
设备操作
也是open read和write
在读写操作中
我们使用和文件系统一样的KFIFO机制
来编译内核模块
插入内核模块
查看内核消息
来查看/dev目录
可以看到生成的设备文件主设备号为10的misc
次设备号为53
来执行用户态测试代码
这是设备路径
执行一次open write
和read操作
使用gcc来编译
执行
可以看到读取了hello 是6个字节
查看内核消息
也打印出了相应的信息
在这里可以体会一下
linux中一切皆文件的概念
在写文件系统的时候 使用的read和write方法
在设备文件中也可以使用
这就是给大家分享的简单的字符设备驱动程序
谢谢大家
-1.1 Linux操作系统概述
-1.2 Linux内核结构以及内核模块编程
--Video
-1.3 Linux内核源码中的双链表结构
--Video
-1.4 源码分析-内核中的哈希表
--Video
-1.5 动手实践-Linux内核模块的插入和删除
--Video
-第1章 概述--章节测验
-2.1 内存管理之内存寻址
--Video
-2.2 段机制
--Video
-2.3分页机制
--Video
-2.4 动手实践-把虚拟地址转换成物理地址
--Video
-第2章 内存寻址--章节测验
-3.1 进程概述
--Video
-3.2 Linux进程创建
--Video
-3.3 Linux进程调度
--Video
-3.4 动手实践-打印进程描述符task_struct中的字段
--Video
-3.5工程实践-基于内核模块的负载监控
--Video
-第3章 进程管理--章节测验
-4.1 Linux内存管理机制
--Video
-4.2 进程用户空间管理机制
--Video
-4.3 物理内存分配与回收机制(上)
--Video
-4.4 物理内存分配与回收机制(下)
--Video
-4.5 动手实践-Linux内存映射基础(上)
--Video
-4.6 动手实践-Linux内存映射实现(中)
--Video
-4.7 动手实践-Linux内存映射测试(下)
--Video
-4.8 初学者对内存管理的常见疑惑
-第4章 内存管理--章节测验
-5.1 中断机制概述
--Video
-5.2 中断处理机制
--Video
-5.3 中断下半部处理机制
--Video
-5.4 时钟中断机制
--Video
-5.5 动手实践-中断上半部的代码分析及应用
--Video
-5.6 动手实践-中断下半部的代码分析及应用
--Video
-第5章 中断--章节测验
-6.1 Linux中的各种API
--Video
-6.2 系统调用机制
--Video
-6.3 动手实践-添加系统调用(系统调用日志收集系统)
--Video
-第6章 系统调用--章节测验
-7.1 内核同步概述
--Video
-7.2 内核同步机制
--Video
-7.3 动手实践-内核多任务并发实例(上)
--Video
-7.4 动手实践-内核多任务并发实例(下)
--Video
-第7章 内核同步--章节测验
-8.1 虚拟文件系统的引入
--Video
-8.2 虚拟文件系统的主要数据结构
--Video
-8.3 文件系统中的各种缓存
--Video
-8.4 页高速缓存机制以及读写
--Video
-8.5 动手实践-编写一个文件系统(上)
--Video
-8.6 动手实践-编写一个文件系统(中)
--Video
-8.7 动手实践-编写一个文件系统(下)
--Video
-第8章 文件系统--章节测验
-9.1 设备驱动概述
--Video
-9.2 I/O空间管理
--Video
-9.3 设备驱动模型
--Video
-9.4 字符设备驱动程序简介
--Video
-9.5 块设备驱动程序简介
--Video
-9.6 动手实践-编写字符设备驱动程序
--Video
-9.7工程实践-编写块设备驱动的基础(上)
--Video
-9.8 工程实践-块设备驱动程序分析(中)
--Video
-9.9 工程实践-块设备驱动程序实现(下)
--Video
-第9章 设备驱动--章节测验
-致谢与说明
--Video