块设备驱动程序

合集下载

Linux设备驱动程序原理及框架-内核模块入门篇

Linux设备驱动程序原理及框架-内核模块入门篇

Linux设备驱动程序原理及框架-内核模块入门篇内核模块介绍应用层加载模块操作过程内核如何支持可安装模块内核提供的接口及作用模块实例内核模块内核模块介绍Linux采用的是整体式的内核结构,这种结构采用的是整体式的内核结构,采用的是整体式的内核结构的内核一般不能动态的增加新的功能。

为此,的内核一般不能动态的增加新的功能。

为此,Linux提供了一种全新的机制,叫(可安装) 提供了一种全新的机制,可安装) 提供了一种全新的机制模块” )。

利用这个机制“模块”(module)。

利用这个机制,可以)。

利用这个机制,根据需要,根据需要,在不必对内核重新编译链接的条件将可安装模块动态的插入运行中的内核,下,将可安装模块动态的插入运行中的内核,成为内核的一个有机组成部分;成为内核的一个有机组成部分;或者从内核移走已经安装的模块。

正是这种机制,走已经安装的模块。

正是这种机制,使得内核的内存映像保持最小,的内存映像保持最小,但却具有很大的灵活性和可扩充性。

和可扩充性。

内核模块内核模块介绍可安装模块是可以在系统运行时动态地安装和卸载的内核软件。

严格来说,卸载的内核软件。

严格来说,这种软件的作用并不限于设备驱动,并不限于设备驱动,例如有些文件系统就是以可安装模块的形式实现的。

但是,另一方面,可安装模块的形式实现的。

但是,另一方面,它主要用来实现设备驱动程序或者与设备驱动密切相关的部分(如文件系统等)。

密切相关的部分(如文件系统等)。

课程内容内核模块介绍应用层加载模块操作过程内核如何支持可安装模块内核提供的接口及作用模块实例内核模块应用层加载模块操作过程内核引导的过程中,会识别出所有已经安装的硬件设备,内核引导的过程中,会识别出所有已经安装的硬件设备,并且创建好该系统中的硬件设备的列表树:文件系统。

且创建好该系统中的硬件设备的列表树:/sys 文件系统。

(udev 服务就是通过读取该文件系统内容来创建必要的设备文件的。

)。

块设备IO流程

块设备IO流程

1. 概述系统能够随机访问固定大小数据片的设备称为块设备,这些数据片称作块。

另一种基本的设备类型是字符设备。

字符设备按照字节流的方式被有序访问,像串口和键盘都属于字符设备。

这两种类型的设备的根本区别在于它们是否可以被随机访问,换句话说,就是能否在访问设备时随意从一个位置跳到另一个位置。

字符设备仅仅需要控制一个位置--当前位置;而块设备访问的位置必须在介质的不同区间前后移动,同时块设备对执行性能的要求很高。

如何管理块设备和如何管理队块设备的请求,该部分在内核中被称为块I/O层。

2. 解剖一个块设备块设备中最小的可寻址单元式扇区。

扇区最常见大小事512字节。

软件都会用到自己的最小逻辑可寻址单元--块。

块石文件系统的一种抽象--只能基于块来访问文件系统。

虽然物理磁盘寻址是按照扇区级来进行的,但是内核执行的所有磁盘操作都是按照块进行的。

所以,块只能数倍于扇区的大小,但大小不能超过一个页面。

扇区:设备的最小寻址单元,亦称"硬扇区"或"设备块"块:文件系统的最小寻址单元,亦称"文件块"或"I/O块"3. 缓冲区和缓冲区头当一个块被调用内存时,它要存储在一个缓冲区中。

每个缓冲区与一个块对应,它相当于是磁盘块在内存中的表示。

所有这些信息都和文件系统的控制信息密切交融,文件系统的控制信息储存在超级快中,超级块是一种包含文件系统信息的数据结构。

由于内核在处理数据需要相关的控制信息,所以每个缓冲区都有一个对应的描述符。

该描述符用buffer_head结构体表示,被称为缓冲区头,在文件<linux/buffer_head.h>中定义。

结构体中h_count域表示缓冲区的使用技术。

在操作缓冲区头之前,应该增加缓冲区头的引用计数,确保该缓冲区托不会再被分配出去,当完成对缓冲区的操作后,就减少引用计数。

缓冲区头的目的在于描述磁盘块和物理内存缓冲区之间的映射关系。

Windows下设备驱动程序的开发方法

Windows下设备驱动程序的开发方法

目录一、驱动开发环境的搭建 (1)1.1 关于DDK (1)1.2 关于驱动程序的编译 (1)1.3关于驱动程序的运行 (2)二、驱动程序的结构 (3)2.1 驱动程序的头文件 (3)2.2 驱动程序的入口点 (3)2.3 创建设备例程 (4)2.4 卸载驱动例程 (5)2.5 派遣例程 (6)三、编写驱动程序的基础知识 (6)3.1 内核模式下的字符串操作 (6)3.2 内核模式下各种开头函数的区别 (8)3.3 一个示例程序 (10)3.4 补充说明 (10)四、在驱动中使用链表 (10)4.1 内存的分配与释放 (10)4.2 使用LIST_ENTRY (12)4.3 使用自旋锁 (12)五、在驱动中读写文件 (15)5.1 使用OBJECT_ATTRIBUTES (15)5.2 创建、打开文件 (16)5.3 读写文件操作 (16)5.4 文件的其它相关操作 (18)六、在驱动中操作注册表 (18)6.1 创建、打开注册表 (19)6.2 读写注册表 (20)6.3 枚举注册表 (21)七、在驱动中获取系统时间 (21)7.1 获取启动毫秒数 (21)7.2 获取系统时间 (22)八、在驱动中创建内核线程 (23)8.1 创建内核线程 (23)8.2 关于线程同步 (24)九、初探IRP (25)9.1 IRP的概念 (25)9.2 IRP的处理 (26)9.3 IRP派遣例程示例 (27)十、驱动程序与应用层的通信 (29)10.1 使用WriteFile通信 (29)10.2 使用DeviceIoControl进行通信 (32)十二、驱动程序开发实例 (33)12.1 NT驱动程序 (33)12.2 WDM驱动程序 (35)十三、参考资料 (41)一、驱动开发环境的搭建1.1 关于DDK开发驱动程序必备的一个东西就是DDK(Device Development Kit,设备驱动开发包),它跟我们在ring3常听到的SDK差不多,只不过它们分别支持开发不同的程序而已。

linux下devicedriver

linux下devicedriver

发信人: olly (剑胆琴心), 信区: Linux标题: LINUX下的设备驱动程序三、UNIX系统下的设备驱动程序3.1、UNIX下设备驱动程序的基本结构在UNIX系统里,对用户程序而言,设备驱动程序隐藏了设备的具体细节,对各种不同设备提供了一致的接口,一般来说是把设备映射为一个特殊的设备文件,用户程序可以象对其它文件一样对此设备文件进行操作。

UNIX对硬件设备支持两个标准接口:块特别设备文件和字符特别设备文件,通过块(字符)特别设备文件存取的设备称为块(字符)设备或具有块(字符)设备接口。

块设备接口仅支持面向块的I/O操作,所有I/O操作都通过在内核地址空间中的I/O缓冲区进行,它可以支持几乎任意长度和任意位置上的I/O请求,即提供随机存取的功能。

字符设备接口支持面向字符的I/O操作,它不经过系统的快速缓存,所以它们负责管理自己的缓冲区结构。

字符设备接口只支持顺序存取的功能,一般不能进行任意长度的I/O请求,而是限制I/O请求的长度必须是设备要求的基本块长的倍数。

显然,本程序所驱动的串行卡只能提供顺序存取的功能,属于是字符设备,因此后面的讨论在两种设备有所区别时都只涉及字符型设备接口。

设备由一个主设备号和一个次设备号标识。

主设备号唯一标识了设备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。

次设备号仅由设备驱动程序解释,一般用于识别在若干可能的硬件设备中,I/O请求所涉及到的那个设备。

设备驱动程序可以分为三个主要组成部分:(1) 自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和是否能正常工作。

如果该设备正常,则对这个设备及其相关的、设备驱动程序需要的软件状态进行初始化。

这部分驱动程序仅在初始化的时候被调用一次。

(2) 服务于I/O请求的子程序,又称为驱动程序的上半部分。

调用这部分是由于系统调用的结果。

这部分程序在执行的时候,系统仍认为是和进行调用的进程属于同一个进程,只是由用户态变成了核心态,具有进行此系统调用的用户程序的运行环境,因此可以在其中调用sleep()等与进程运行环境有关的函数。

eMMC 驱动架构分析

eMMC 驱动架构分析

void mmc_detectБайду номын сангаасchange(struct mmc_host *host, unsigned long delay) // core/core.c
{
mmc_schedule_delayed_work(&host->detect, delay);
}
static int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay)
一.需要的基础知识: 1. LINUX 设备驱动的基本结构。 2. 块设备驱动程序的基本构架(相信研究过 LDD3 当中的 sbull 的人应该都不成问 题,如果只是走马观花的话,那可得好好再补补了)
3. LINUX 设备驱动模型。
4.
EMMC 的原理,是 Nand Flash 的基础上加上一个负责:ECC、负载均衡和坏块管
理功能的 controler。
二.驱动程序分析 首先,说明一下 EMMC 驱动涉及到的文件。另外,我们重点是分析驱动程序的基本构
架,所以不同内核版本的差异并不是很大。 MMC/SD 卡驱动程序位于 drivers/mmc 目录 下 Card/
block.c queue.c/queue.h core/ bus.c/bus.h core.c/core.h
(3) 主机控制器层
主机控制器则是依赖于不同的平台的,例如 s3c2410 的卡控制器和 atmel 的卡控制器必 定是不一样的,所以要针对不同的控制器来实现。以 s3cmci.c 为例,它首先要进行一些设 置,例如中断函数注册,全能控制器等等。然后它会向 core 层注册一个主机( host ), 用结构 mmc_host_ops 描述,这样核心层就可以拿着这个 host 来操作 s3c24xx 的卡控 制器了,而具体是 s3c24xx 的卡控制器还是 atmel 的卡控制器, core 层是不用知道的。

Rootkit技术

Rootkit技术

Rootkit技术rootkit的主要分类早期的rootkit主要为应用级rootkit,应用级rootkit主要通过替换login、ps、ls、netstat 等系统工具,或修改.rhosts等系统配置文件等实现隐藏及后门;硬件级rootkit主要指bios rootkit,可以在系统加载前获得控制权,通过向磁盘中写入文件,再由引导程序加载该文件重新获得控制权,也可以采用虚拟机技术,使整个操作系统运行在rootkit掌握之中;目前最常见的rootkit是内核级rootkit。

内核级rootkit又可分为lkm rootkit、非lkm rootkit。

lkm rootkit主要基于lkm技术,通过系统提供的接口加载到内核空间,成为内核的一部分,进而通过hook系统调用等技术实现隐藏、后门功能。

非lkm rootkit主要是指在系统不支持lkm机制时修改内核的一种方法,主要通过/dev/mem、/dev/kmem设备直接操作内存,从而对内核进行修改。

非lkm rootkit要实现对内核的修改,首先需要获得内核空间的内存,因此需要调用kmalloc分配内存,而kmalloc是内核空间的调用,无法在用户空间直接调用该函数,因此想到了通过int 0x80调用该函数的方法。

先选择一个不常见的系统调用号,在sys_call_table 中找到该项,通过写/dev/mem直接将其修改为kmalloc函数的地址,这样当我们在用户空间调用该系统调用时,就能通过int 0x80进入内核空间,执行kmalloc函数分配内存,并将分配好的内存地址由eax寄存器返回,从而我们得到了一块属于内核地址空间的内存,接着将要hack的函数写入该内存,并再次修改系统调用表,就能实现hook系统调用的功能。

rootkit的常见功能隐藏文件:通过strace ls可以发现ls命令其实是通过sys_getdents64获得文件目录的,因此可以通过修改sys_getdents64系统调用或者更底层的readdir实现隐藏文件及目录,还有对ext2文件系统直接进行修改的方法,不过实现起来不够方便,也有一些具体的限制。

如何安装和更新硬件驱动程序

如何安装和更新硬件驱动程序

如何安装和更新硬件驱动程序硬件驱动程序是与计算机硬件设备交互的关键组成部分。

通过正确安装和更新驱动程序,可以保证硬件设备正常运行,提升计算机性能和稳定性。

本文将详细介绍如何安装和更新硬件驱动程序的步骤和方法。

一、查找硬件信息在安装和更新硬件驱动程序之前,我们首先需要了解硬件设备的相关信息。

可以通过以下几种方式来查找硬件信息:1. 设备管理器:按下Win + X组合键,在弹出的菜单中选择"设备管理器",展开其中的设备列表,可以查看到已连接到计算机上的硬件设备信息。

2. 系统信息:按下Win + R组合键,打开"运行"对话框,输入"msinfo32",打开系统信息窗口。

在左侧的面板中选择"组件"下的"问题设备",可以查看到与硬件设备相关的信息。

3. 第三方软件:有许多第三方软件可以帮助我们快速查找硬件信息,例如CPU-Z、Speccy等。

通过它们,可以获得硬件设备的详细规格和型号。

二、下载驱动程序在得知硬件设备的相关信息后,我们需要找到相应的驱动程序进行下载。

以下是下载驱动程序的几种常见途径:1. 官方网站:前往硬件设备的官方网站,通常可以在其支持或下载页面找到相应的驱动程序。

在官方网站下载驱动程序可以确保其完整性和兼容性。

2. 驱动程序更新软件:许多厂商提供专门的驱动程序更新软件,例如Nvidia的GeForce Experience、Intel的驱动更新工具等。

这些软件可以自动检测并下载最新版本的驱动程序。

3. 第三方驱动程序网站:一些第三方网站收集了各种硬件设备的驱动程序,例如DriverPack Solution、Snappy Driver Installer等。

但要注意确保所下载的驱动程序来源可靠。

三、安装驱动程序在下载好驱动程序之后,我们需要进行安装。

以下是安装驱动程序的步骤:1. 解压驱动程序文件:有些驱动程序下载下来是一个压缩包文件,需要使用解压工具将其解压缩到一个文件夹中。

IO驱动

IO驱动

example
设备描述符 typedef struct ideDev { BLK_DEV blkDev; int drive; 设备号 int blkOffset; 偏移量 }xx_DEV;
块设备-驱动程序安装
n
(2)设计xxDrv()函数执行初始化。 和其他类型的设备驱动程序一样,块设 备也需要一个初始化程序.这个初始化 程序仅执行一些必要的初始化操作(例 如初始化驱动程序数据结构和分配内存 等)。但不会将驱动程序安装在IO系统 中或文件系统中.根据不同的设备,初 始化将执行不同的操作。
example
example
3、设备创建函数
n
设备创建函数xxDevCreate()的主耍作用 是创建逻辑设备。逻辑设备既可以是整 个物理设备也可以是物理设备的一部 分.在创建逻辑设备的过程中,应该初 始化相应的数据结构,并且所返回的数 据结构必须以BLK_DEV结构作为第一个成 员、文件系统里用这个返回值将文件系 统本身安装到设备上。该函数所使用的 参数根据设备的不同而不同。
数据结构
bd_bytesPerBlk:指明分块中包含的字节数. bd_lksPerTrack:指明每一个磁道包含的块的数目。 bd_nHeads:指明磁头数 bd_retry:指明遇到错误后重试的次数。 bd_mode:指明设备模式为O_RDONLY或者O_RDWR。 bd_readyChanged:这个值总是为TRUE。
块设备驱动与非块设备驱动
块设备的特点
n
Vxworks的IO系统是通过文件系统访问块设备的, 所以块设备的驱动程序函数的入口点不会安装到 驱动程序表中,块设备的描述符也不会连接到系 统的设备列表中。块设备驱动程序是由文件系统 来访问的,所以支持另外的一套驱动程序表。块 设备是以块为单位进行数据传输的,而字符设备 则是以字节为单位进行数据传输,这使块设备驱 动程序的功能也大为不同;同一个设备驱动程序 应该同时支持不同的文件系统。尽管块设备驱动 程序可以支持多种文件系统,但对于块设备本省 来说,是不用关心文件系统的存在的.
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

18.5.1 数据从内存到磁盘的过程
内存是一个线性的结构,Linux系统将内存分为页。一页 最大可以是64K,但是目前主流的系统页的大小都是4K。现在 假设数据存储在内存的相邻几页中,希望将这些数据写到磁盘 上。那么每一页的数据会被先封装为一个段,用bio_vec表示。 多个页会被封装成多个段,这些段被组成以一个bio_vec为元素 的数组,这个数组用bio_io_vec表示。
queue_head
request request
rq_disk
queuelist
bio bio_tail
request request
rq_disk
queuelist
bio bio_tail
bio bio bi_next bi_idx bio_io_vec
bio_vec bio_vec
page bv_len bv_offset
磁盘/硬盘等
18.1.2 块设备的结构
在写块设备驱动程序之前,了解典型块设备的结构是非 常重要的。图显示的是磁盘的一个盘面,一些重要的概念将 在下面讲述。
磁道
扇区
10% 101%011%010%011%%001%%0111%0001%%%011%0011%%010%01%%01%0% 101%011%010%011%%001%%0111%0001%%%011%0011%%010%01%%01%0%
18.5.5 请求队列、请求结构、bio等之间的关系
可能读者对请求队列request_queue、请求结构request、 bio、bio_vec、gendisk等结构的关系还并不清楚,除了建议读者 查阅内核源码外,认真查看图也是不错的方法。块设备Βιβλιοθήκη gendisk gendisk
queue
request_queue request_queue
page bv_len bv_offset
系统调用
虚拟文件系统
通用磁盘(gendisk) 请求结构体(request) 请求队列request_queue
块设备IO(bio) 分区表(hd_struct)
...
磁盘文件系统 通用块层 I/O调度器
块设备驱动程序
预期算法(Anticipatory) 最后期限算法(Deadline)
完全公平算法(CFQ) Noop算法(No Operation)
18.5.2 块I/O请求(bio)
数据从内存到磁盘或者从磁盘到内存的过程,叫做I/O操 作。内核使用一个核心数据结构bio来描述I/O操作。
1.bio结构体 bio结构体包含一个块设备完成一次I/O操作所需要的一切 信息。 2.bio_vec结构体 bio中的段用bio_vec结构体来表示。 3.bio结构体的相关宏 为了程序的可移植性,在写驱动程序时,不应该直接的操 作bio结构和bi_io_vec数组,而应该使用内核开发者提供的一 系列宏。由于在驱动中会使用这些宏,这里对其主要的宏进行 介绍。
18.5 I/O调度器
Linux内核中,I/O调度器涉及到很多复杂的数据结构,而 结构之间的关系又非常复杂。要精通这些知识,远非一章一节 知识所能够达到。但本节力图给读者一个清晰的概念,随着内 核的升级,这些概念可能有所细微的变化,但是其主要的原理 是基本不会变化的。在详细讲解I/O调度器之前,需要知道数 据是怎样从内存到达磁盘的。
18.3.3 块设备的注册和注销
为了使内核知道块设备的存在,需要使用块设备注册函 数。在不使用块设备时,也需要注销块设备。块设备的注册 和注销如下所述:
1.注册块设备函数register_blkdev() 2.注销块设备函数unregister_blkdev()
18.3.4 请求队列
简单的讲,一个块设备的请求队列就是包含块设备I/O请求的一 个队列。这个队列使用链表线性的排列。请求队列中存储未完成的块 设备I/O请求,并不是所有的I/O块请求都可以顺利的加入请求队列中 。请求队列中定义了自己能处理的块设备请求限制。这些限制包括: 请求的最大尺寸、一个请求能够包含的独立段数、硬盘扇区大小等。
分配磁盘 alloc_disk()
注册设备 register_blkdev()(可选)
不使用请求队列 blk_init_queue()
使用请求队列 blk_alloc_queue()
磁盘gendisk属性设置
激活磁盘add_disk()
18.2.2 块设备卸载过程
在块设备驱动的卸载模块中完成与模块加载函数相反的工作 。
18.3 通用块层
通用块层是块设备驱动的核心部分,这部分主要包含块 设备驱动程序的通用代码部分。本节将介绍通用块层的主要 函数和数据结构。
18.3.1 通用块层
通用块层是一个内核组件,它处理来自系统其他组件发出的块设
备请求。换句话说,通用块层包含了块设备操作的一些通用函数和数
据结构。图是块设备加载函数中用到的一些重要数据结构,如通用磁 盘结构gendisk、请求队列结构request_queue、请求结构request、块 设备I/O操作结构bio、块设备操作结构block_device_operations等。这 些结构将在下面的几小节详细简述。
18.1 块设备简介
本节对块设备的相关概念进行了简要的分析。理解这些 概念对写块设备驱动程序具有十分重要的意义。
18.1.1 块设备总体概述
Linux内核中,I/O设备大致分为两类:块设备和字符设备。块 设备将信息存储在固定大小的块中,每个块都有自己的地址。数据块 的大小通常在512字节到4K字节之间。块设备的基本特征是每个块都 能独立于其它块而读写。磁盘就是最常见的块设备。在Linux内核中 ,块设备与内核其他模块的关系如图所示:
第18章 块设备驱动程序
除了字符设备、网络设备外,Linux系统中还有块设备。字符 设备和块设备在内核中的结构有很大的不同,总体来说,块设备要 比字符设备复杂很多。块设备主要包含磁盘设备、SD卡等,这些设 备是Linux系统中不可缺少的存储设备。计算机中都需要这样的设 备来存储数据,所以学会块设备驱动程序的写法是非常重要的。
18.4 不使用请求队列的块设备驱动
这里,有两个原因需要向读者介绍不使用请求队列的块 设备驱动程序。第一个原因是,希望尽快的向读者展现一个 完整的块设备驱动程序;第二个原因是,不使用请求队列的 块设备驱动程序相对来说,比较简单。
18.4.1 不使用请求队列的块设备驱动程序的 组成
块设备函数驱动程序主要有一个加载函数、卸载函数和 一个自定义的请求处理函数组成。本节将写一个虚拟的块设备 驱动程序Virtual_blkdev。这个驱动程序在内存中开辟了一个 8M的内存空间来模拟实际的物理块设备。这个块设备驱动程 序代码比较简单,但功能却非常强大。对实际物理设备的操作 命令同样可以应用在Virtual_blkdev这个块设备上,例如 mkdir、mkesfs等命令。
18.4.2 宏定义和全局变量
Virtual_blkdev块设备驱动中定义了一些重要的宏和全 局指针,包括主设备号、设备名、设备的大小等。
18.4.3 加载函数
Virtual_blkdev设备的加载函数主要完成分配磁盘、初 始化请求队列、设置磁盘属性和激活磁盘的工作。
18.4.4 卸载函数
Virtual_blkdev设备的卸载函数中主要完成与设备加载 函数中相反的工作:
18.3.5 设置gendisk属性中的 block_device_operations结构体
在块设备中有一个和字符设备中file_operations对应的结 构体block_device_operations。其也是一个对块设备操作的函 数集合。
下面对这个结构体的主要成员进行分析。 1.打开和释放函数 2.I/O控制函数 3.介质改变函数 4.使介质有效函数 5.获得驱动器信息的函数 6.模块指针
(1)使用del_gendisk()函数删除gendisk设备。 (2)使用put_disk()函数清楚gendisk的引用计数。 (3)使用blk_cleanup_queue()函数清除请求队列。
18.4.5 自定义请求处理函数
内核将I/O读写请求放入请求结构request中,并连接到请 求队列request_queue中。因为Virtual_blkdev设备是一个基于 内存的设备,可以随机读取数据,并不需要复杂的I/O调度( I/O调度的作用是对请求结构request进行排序,最大限度的提 高读写速率)。所以当请求到来时,将直接使用 blk_init_queue()函数中注册的请求处理函数 Virtual_blkdev_do_request()函数,对请求进行实际的操作。这 里的操作就是将数据赋值的Virtual_blkdev设备或者从 Virtual_blkdev设备中读取数据。
(1)使用del_gendisk()函数删除gendisk设备,并使用 put_disk()函数删除对gendisk设备的引用。
(2)使用blk_cleanup_queue()函数清除请求队列,并释放 请求队列所占用的资源。
(3)如果在模块加载函数中使用了register_blkdev()注册设 备,那么需要在模块卸载函数中使用unregister_blkdev()函数注 销块设备,并释放对块设备的引用。
18.5.3 请求结构(request)
几个连续的页面会组成一个bio结构,几个相邻的bio结 构就会组成一个请求结构request。这样当磁盘在接收一个与 request对应的命令,就不需要大幅度的移动磁头,这样就节 省了I/O操作的时间。
18.5.4 请求队列(request_queue)
每个块设备驱动程序都维护着自己的请求队列 request_queue,其包含设备将要处理的请求链表。请求队列 主要用来连接对同一个块设备的多个request请求结构。同时 请求队列中的一些字段还保存了块设备所支持的请求类型信息 、请求的个数、段的大小、硬件扇区数等与设备相关的信息。 总之,内核负责对请求队列的正确配置,使请求队列不会给块 设备发送一个不能处理的请求。
相关文档
最新文档