当前课程知识点:Linux 内核分析与应用 >  第9章 设备驱动 >  9.9 工程实践-块设备驱动程序实现(下) >  Video

返回《Linux 内核分析与应用》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《Linux 内核分析与应用》慕课在线视频列表

Video课程教案、知识点、字幕

大家好我们在上一期视频节目中给大家介绍了块

设备子系统它

常用的数据结构和常用的接口的API函数

那我们在那次视频节目中和

给大家留了一个实验

这个实验里我们要求大家

写一个

内核驱动

在这个内核驱动里面

里我们使用ramdisk

就是系统的内存

来构造一个虚拟的块设备

那在这个块设备里我们做一些

读写操作和对

这个request的一些简单操作

这个实验

对大家理解块设备是非常有帮助的

那我们这期节目中

就和大家简单过一遍实验的我们一个

示例的代码

我们首先打开ramdisk_

driver.c这个文件

那这个文件一共155行其实这个

也不长我们来看下第

151行这里module_init

这里面就指示了驱动的入口

它的入口函数是my_init

那我们来看下my_init这个函数

第97行这里

我们首先简单给这个

ramdisk

设定一个大小这里我们

定义了ramdisk 256M

接下来在第100行这里我们使用这个

vmalloc这个内核的

分配内存的接口函数来给

ramdisk块设备来

分配存储空间

那104行这里我们使用这个

blk_init_queue这个函数

来为我们这个

块设备来创造一个

请求队列

request_queue

这个blk_init_queue

这里面有两个参数

第一个参数是一个函数指针my_request

这是一个函数我们一会分析

那第二个参数是lock

是一个锁所以我们在第98行里面我们去

初始化了一个spin_lock_init的锁

那这个函数会返回一个请求队列

那这个请求队列我们定义在哪里呢

这个函数我们初始化在

第19行它实际上是struct

request_queue这样一个数据结构

这个数据结构我们在上期节目中

和大家介绍过了

那我们来看

109行这里我们给这个

request_queue来设置它的sector_size

那它的sector_size我们这里

简单把它定义到512个字节

那我们再看一下第111行这里

register_blkdev这个函数去

注册一个

块设备那我们这里第一个参数

等于0的话就是让系统主动去分配一个

主设备号

那第二个参数是

这个设备它的名称

这个注册成功以后它会返回一个

主设备号那这个主设备号我们在这里

把它写成mybdrv

_ma_no

那我们看下第119行这里

我们这里用一个alloc_disk

来去分配一个gendisk

一个通用的

disk的一个描述符

我们看下my_gd它是

定义在第16行它是一个

struct gendisk这么一个数据结构

那这个数据结构

分配完之后我们要对他的一些

主要成员做一些初始化

看126行这里

它的major这里就指

指向我们刚才用register

blkdev这个函数它去成功分配出来的这个

块设备的这个主设备号

然后first minor我们就设成零

然后fops我们就

指向我们驱动里面我们自己定义的一个

fopsfops实现在哪实际在90行这里

它实际上是一个block_device_operations

那这个block_device_operations

它是非常类似我们之前讲的

字符设备它的一个

file_opereations的一个方法集

那在这个

驱动里面我们这个方法集

只实现了一个ioctl的这么一个

一个方法

第129行就是

来给这个

gendisk来起一个名字

然后第130行这里就是把我们刚才

分配的my_request_queue

就是这个gendisk的queue这个成员

要指向我们刚才

分配的这个

请求队列第131行这里就是设置这个

块设备它的一个capacity

它的容量是多少

那这些

主要成员都

配置好了之后我们就可以使用

add_disk这个函数来

把gendisk给

像Linux内核去注册就是说把gendisk

添加到Linux系统的块设备子系统里面

这些做完之后我们会在这里加一个打印

会把我们这个块设备它的主设备号给打出来

然后把我们ram disk它的容量也打出来

这个就是驱动的init函数

它所做的工作那

接下来我们来看一下另外一个非常重要的一个操作就是我们刚才讲了

块设备它有一个非常重要的一个处理就是去处理

这个请求队列里面的这些请求

那这个请求队列里面的请求

他是怎么处理的呢

我们刚才在104行里面讲了这里我们去

初始化一个请求队列的时候 我们

的第一个参数是一个函数指针也就是

对这个request的一个实际处理的一个函数

也就是我们这里的my_request这个函数

它实现在第22行这里

我们来分析一下这个函数在28行这里我们会

加一个打印

告诉我告诉大家我们现在已经进来这里要处理这个request

那第30行这里

blk_fetch_request

就是从这个请求队列里面去拉一个请求出来

拉一个request出来

然后第31行就是要去

处理这些请求

我们第32行这里

nr_sectors

其实说这个请求我们需要多少个sector

第33行这里blk_rq_

pos也就说这个请求它是在相对于这个

块设备他是在哪个opposite里面pos

s代表opposite的意思

所以第35行因为我们的块设备是一个简单的一个

连续内存作为存储的一个虚拟的一个块设备 那所以

我们就可以通过一个简单的一个

计算能算出当前这个request

他的请求它的存储地址是在哪里

然后能够简单地算出来request它的

size是多少

我们第38行做一个简单的一个判断

你请求的这个

大小不能超过ram disk

的最大对吧然后第43行这里我们就

因为这个请求它有分是读还是写

那第43到46行这里我们处理它是一个

写的一个请求这里我们也加了一个打印

这里会把sector和nr_sectors会打印出来 然后

第46行这里我们做一个拷贝因为我们这个是

以系统内存作为存储介质的所以我们

简单做个拷贝把我们的请求的数据

这里数据用bio_data请求的数据

直接拷贝到我们ptr指针里面

那接下来这个48到50行也是类似的这里我们

处理read请求同样也是用memcpy

做一个简单的一个操作

这个整个流程就是对一个

从文件系统来的一个请求

对于我们一个块设备驱动它是怎么做的

当然这个请求是非常简单了

这个处理非常简单接下来我们看一下另外一个操作就是

我们在block_device_operations里面

在这个方法集里面我们定义一个ioctl

我们这里实现了一个my_ioctl

那我们看一下my_ioctl里面根据我们的实验的要求我们需要

实现HDIO_GETGEO

.这么一个ioctl的请求

在ioctl请求里面

其实我们就是去把这个

块设备的一些参数你比如说他有多少个

磁头多少个扇区然后有多少柱面这些信息打印出来

在我们这个实验里面我们只是

简单的做一个假的这么一个数据

然后最终是通过copy_to_user

这么一个API把这些数据信息

传到用户空间里面这个就是我们整个的

实验的代码其实我们

最重要的还是要去理解我们

上一次视频讲了一些这个块设备驱动里面核心的这些API的一些使用

接下来我们来编译一下这个驱动

我现在是在ubuntu 18.04的

系统里面去编译驱动模块

我使用的内核版本是4.15的内核

我们要编译首先可以写一个简单的Makefile

这个是简单的Makefile

我们直接使用make的命令

就可以去编译内核模块

编译完之后我们发现在这里面一个ramdisk_driver.ko

这时候我们可以使用

sudo insmod

ramdisk_driver.ko来加载驱动

他说这里已经加载过了我们先把它卸载了

我们使用sudo insmod

ramdisk_driver.ko来加载这个模块大家看到我们已经加载了

这时候我们可以用

dmesg来看一下

那dmesg看到这里面

它会打印这个

device successfully

然后我们可以看到它的主设备号是252

然后它的ram disk的容量是256MB

对吧 那接下来我们来看一下这个

我们创建的设备是在哪里

我们可以用ls /dev/

大家可以看到这里面有一个myramdisk

这个myramdisk就是我们创建的块设备

我们可以看一下我们的driver是怎么写的

您看到我们这里有一个我们的MY_DEVICE_NAME

起的名字就是myramdisk

这时候我们可以

ramdisk给格式化了

我们用sodo mkfs

ext4

然后dev/myramdisk

大家看到我们

对它格式化的时候我们可以看到我们的一些信息 对不对

格式化完之后我们可以对它进行mount操作

我们首先来看一下

dmesg里面打印的信息

大家看到dmesg里面打印了很多的信息

你比如说

比如说你看以这个为例

我们每一次request处理的时候我们

入口我们会打印一个start handle request

你看这里面都是writing对不对writing at

sector这是一个就是说这是一个

这是一个sector的一个 它在整个

ramdisk的一个起始的一个指针就是相当于文件的一个指针

然后这个是这次操作他操作多少个sector

接下来我们可以对它进行一个

mount的一个动作我们mount到mnt这里面OK

那我们可以进入到mnt的目录里面

大家看到我们已经mount这个了我们可以用df

我们可以用df我们可以用df命令来看一下我们系统挂载的

分区大家看到dev/myramdisk

挂载到mnt里面OK

先把这个清掉

这时候我们可以在这里创建一个文件夹

我们创一个mytest文件夹OK

mytest文件夹这时候我们再看一下

dmesg那这个dmesg的信息就是我

敲这个mkdir mytest

创建目录的时候他发起的一些

块设备的一些IO操作

大家看一下我们在这里已经创建了mytest

然后这些是他

我们这个块设备驱动里面

它处理这些

来自文件系统的请求他所做的一些

最底层的一些操作了

Linux 内核分析与应用课程列表:

第1章 概述

-1.1 Linux操作系统概述

--1.1 Linux 操作系统概述

-1.2 Linux内核结构以及内核模块编程

--Video

-1.3 Linux内核源码中的双链表结构

--Video

-1.4 源码分析-内核中的哈希表

--Video

-1.5 动手实践-Linux内核模块的插入和删除

--Video

-第1章 概述--章节测验

-第1章导学--引领你进入Linux内核的大门

第2章 内存寻址

-2.1 内存管理之内存寻址

--Video

-2.2 段机制

--Video

-2.3分页机制

--Video

-2.4 动手实践-把虚拟地址转换成物理地址

--Video

-第2章 内存寻址--章节测验

-第二章导学-从零打造自己的操作系统

第3章 进程管理

-3.1 进程概述

--Video

-3.2 Linux进程创建

--Video

-3.3 Linux进程调度

--Video

-3.4 动手实践-打印进程描述符task_struct中的字段

--Video

-3.5工程实践-基于内核模块的负载监控

--Video

-第3章 进程管理--章节测验

-第三章导学-进程背后琳琅满目的宝贝到哪里挖?

第4章 内存管理

-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章 中断

-5.1 中断机制概述

--Video

-5.2 中断处理机制

--Video

-5.3 中断下半部处理机制

--Video

-5.4 时钟中断机制

--Video

-5.5 动手实践-中断上半部的代码分析及应用

--Video

-5.6 动手实践-中断下半部的代码分析及应用

--Video

-第5章 中断--章节测验

第6章 系统调用

-6.1 Linux中的各种API

--Video

-6.2 系统调用机制

--Video

-6.3 动手实践-添加系统调用(系统调用日志收集系统)

--Video

-第6章 系统调用--章节测验

第7章 内核同步

-7.1 内核同步概述

--Video

-7.2 内核同步机制

--Video

-7.3 动手实践-内核多任务并发实例(上)

--Video

-7.4 动手实践-内核多任务并发实例(下)

--Video

-第7章 内核同步--章节测验

第8章 文件系统

-8.1 虚拟文件系统的引入

--Video

-8.2 虚拟文件系统的主要数据结构

--Video

-8.3 文件系统中的各种缓存

--Video

-8.4 页高速缓存机制以及读写

--Video

-8.5 动手实践-编写一个文件系统(上)

--Video

-8.6 动手实践-编写一个文件系统(中)

--Video

-8.7 动手实践-编写一个文件系统(下)

--Video

-第8章 文件系统--章节测验

第9章 设备驱动

-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

直播视频:从Linux内核学习到自主操作系统研发

-从Linux内核学习到自主操作系统研发

附录:实验代码、课件以及相关素材

-各章实验代码

-《Linux内核分析与应用》课件

-《Linux操作系统原理与应用》教材课堂视频

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。