linux0.12-9-1-总体功能

news2025/1/20 5:49:21

[395页]

9-1 总体功能

对硬盘和软盘块设备上数据的读写操作是通过中断程序进行的。内核每次读写的数据量以一个逻辑块(1024字节)为单位,而块设备控制器则是以扇区(512字节)为单位。在处理过程中,使用了读写请求项等待队列来顺序缓冲一次读写多个逻辑块的操作。

(a)当程序需要读取硬盘上的一个逻辑块时,就会向缓冲区管理程序提出申请,而程序的进程则进入睡眠等待状态。
(b)缓冲区管理程序首先在缓冲区中寻找以前是否已经读取过这块数据。
©如果缓冲区中已经有了,就直接将对应的缓冲区块头指针返回给程序并唤醒该程序进程。
(d)若缓冲区中还不存在所要求的数据块,则缓冲管理程序就会调用本章中的低级块读写函数ll_rw_block(),向相应的块设备驱动程序发出一个读数据块的操作请求。
(e)该函数会为此创建一个请求结构项,并插入请求队列中。为了提高读写磁盘的效率,减小磁头移动的距离,在插入请求项时使用了电梯移动算法。
(f)此时,若对应块设备的请求项队列为空,则表明此刻该块设备不忙。于是内核就会立刻向该块设备的控制器发发出读数据命令。
(g)当块设备的控制器将数据读入到指定的缓冲块中后,就会发出中断请求信号,
并调用相应的读命令后处理函数,处理继续读扇区操作或者结束本次请求项的过程。
例如对相应块设备进行关闭操作和设置该缓冲块数据已经更新标志,最后唤醒等待该块数据的进程。

9-1-1 块设备请求项和请求队列

根据上面描述,我们知道低级读写函数ll_rw_block()是通过请求项来与各种块设备建立联系并发出读写请求的。对于各种块设备,内核使用了一张块设备表blk_dev[]来进行管理。每种块设备都在块设备表中占有一项。块设备表中每个块设备项的结构为(摘自后面的blk.h):

struct blk_dev_struct {
	void (*request_fn)(void);//请求项操作的函数指针。
	struct request * current_request;//当前请求项指针。
};
extern struct blk_dev_struct blk_dev[NR_BLK_DEV];//块设备表(数组)(NR_BLK_DEV=7)。

第一个字段是一个函数指针,用于操作相应块设备的请求项。例如,对于硬盘驱动程序,它是do_hd_request(),而对于软盘设备,它就是do_floppy_request()。
第二个字段是当前请求项结构指针,用于指明本块设备目前正在处理的请求项,初始化时都被置成NULL。

块设备表将在内核初始化时,在init/main.c程序调用各设备的初始化函数时被设置。为了 便于扩展,Linus把块设备表建成了一个以主设备号为索引的数组。在Linux0.12中,主设备号有7种,其中,主设备号1、2和3分别对应块设备:虚拟盘、软盘和硬盘。在块设备数组中其他各项都被默认地置成NULL。相关操作函数见表9-1。

当内核发出一个块设备读写或其他操作请求时,ll_rw_block()函数即会根据其参数中指明的操作命令和数据缓冲块头中的设备号,利用对应的请求项操作函数do_XX_request()建立一个块设备请求项,并利用电梯算法插入到请求项队列中。请求项队列由请求项数组中的项构成,共有32项,
每个请求项的数据结构如下所示:

struct request {
	int dev;						//使用的设备号(若为-1,表示该项空闲)。
	int cmd;						//命令(READ或WRITE)。
	int errors;						//操作时产生的错误次数。
	unsigned long sector;			//起始扇区。(1块=2扇区)
	unsigned long nr_sectors;		//读、写扇区数。
	char * buffer;					//数据缓冲区。
	struct task_struct * waiting;	//任务等待操作执行完成的地方。
	struct buffer_head * bh;		//缓冲区头指针(include/linux/fs.h,68)。
	struct request * next;			//指向下一请求项。
};
extern struct request request[NR_REQUEST];//请求项数组(NR_REQUEST=32)。

每个块设备的当前请求指针与请求项数组中该设备的请求项链表共同构成了该设备的请求队列。项与项之间利用字段next指针形成链表。因此块设备想和相关的请求队列形成如图9-1所示结构。

请求项采用数组加链表结构的主要原因是为了满足两个目的:
一是利用请求项的数组结构在搜索空闲请求块时可以进行循环操作,搜索访问时间复杂度为常数,因此 程序可以编制得很简洁;
二是为了满足电梯算法插入请求项操作,因此也需要采用链表结构。

图9-1中示出了硬盘设备当前具有4个请求项,软盘设备具有1个请求项,而虚拟盘设备暂时没有读写请求项。
在这里插入图片描述

对于一个当前空闲的块设备,当ll_rw_block()函数为其建立第一个请求项时,会让该设备的当前请求项指针current_request直接指向刚建立的请求项,并且立刻调用对应设备的请求项操作函数开始执行块设备读写操作。当一个块设备已经有几个请求项组成的链表存在,ll_rw_block()就会 利用电梯算法,根据磁头移动距离最小原则,把新建的请求项插入到链表合适的位置。

另外,为满足读操作的优先权,在为建立新的请求项而搜索请求项数组时,把建立写操作时的空闲项搜索范围限制在整个请求项数组的前2/3范围内,而剩下的1/3请求项专门给读操作建立请求项使用。

9-1-2 块设备访问调度处理

相对于内存来说,访问硬盘和软盘等块设备中的数据是比较耗时并且影响系统性能的操作。由于硬盘(或软盘)磁头寻道操作(即把读写磁头从一个磁道移动到另一个指定磁道上)需要花费很长时间,因此我们有必要在向硬盘控制器发送访问操作命令之前对读/写磁盘扇区数据的顺序进行排序,即对请求项链表中各请求项的顺序进行排序,使得所有请求项访问的磁盘扇区数据块都尽量依次顺序进行操作。在Linux0.1X内核中,请求项排序操作使用的是电梯算法。其操作原理类似于电梯的运行轨迹(向一个方向移动),直到该方向上最后一个"请求"停止层为止。然后执行反向移动。对于磁盘来讲就是磁头一直向盘片圆心方向移动,或者反之向盘片边缘移动。

因此,内核并非按照接收到请求项的顺序直接发送给块设备进行处理,而是需要对请求项的顺序进行处理。我们通常把相关的处理程序称为I/O调度程序。Linux0.1x中的I/O调度程序仅对请求项进行了排序处理,而当前流行的Linux内核(例如2.6.x)的I/O调度程序中还包含 对访问相邻磁盘扇区的两个或多个请求项的合并处理。

9-1-3 块设备操作方式

在系统(内核)与硬盘进行I/O操作时,需要考虑三个对象之间的交互作用。它们是系统、控制器和驱动器(例如硬盘或软盘驱动器),如图9-2所示。系统可以直接向控制器发送命令或等待控制器发出中断请求;控制器在接收到命令后就会控制驱动器的操作,读/写数据或者进行其他操作。因此我们可以把这里控制器发出的中断信号看作是这三者之间的同步操作信号,所经历的操作步骤为:

(a)首先系统指明控制器在执行命令结束而引发的中断过程中应该调用的C函数,然后向块设备控制器发送读、写、复位或其他操作命令。
(b)当控制器完成了指定的命令,会发出中断请求信号,引发系统执行块设备的中断处理过程,并在其中调用指定的C函数对读/写或其他命令进行命令结束后的处理工作。
©对于写盘操作,系统需要在发出了写命令后(使用hd_out())等待控制器给予允许向控制器写数据的响应,即需要查询等待控制器状态寄存器的数据请求服务标志DRQ置位。一旦DRQ置位,系统就可以向控制器缓冲区发送一个扇区的数据。
(d)当控制器把数据全部写入驱动器(或发送错误)以后,还会产生中断请求信号,从而在中断处理过程中执行前面预设置的C函数(write_intr())。这个函数会查询是否还有数据要写。如果 有,系统就再把一个扇区的数据传到控制器缓冲区中,然后再次等待控制器把数据写入驱动器后引发的中断,一直这样重复执行。如果此时所有数据都已经写入驱动器,则该C函数就执行本次写盘结束后的处理工作;唤醒等待该请求项有关数据的相关进程、唤醒等待请求项的进程、释放当前请求项并从链表中删除请求项以及释放锁定的相关缓冲区。最后再调用请求项操作函数去执行下一个读/写盘请求项(若还有的话)。
(e)对于读盘操作,系统在向控制器发送出包括需要读的扇区开始位置、扇区数量等信息的命令后,就 等待控制器产生中断信号。当控制器按照读命令的要求,把指定的一扇区数据从驱动器传到了自己的缓冲区之后就会发出中断请求。从而会执行到前面为读盘操作预设置的C函数(read_intr())。该函数首先把控制器缓冲区中一个扇区的数据放到系统的缓冲区中,调整系统缓冲区中当前写入位置,然后递减需读的扇区 数量。若还有数据要读(递减结果值不为0),则继续等待控制器发出下一个中断信号。若此时所有要求的扇区都已经读到系统缓冲区中,就执行与上面写盘操作一样的结束处理工作。

对于虚拟盘设备,由于它的读写操作不涉及与外部设备之间的同步操作,因此没有上述的 中断处理过程。当前请求项对虚拟设备的读写操作完全在do_rd_request()中实现。

需要注意的是:在向硬盘或软盘控制器发送了读/写或其他命令后,发送命令函数并不会等待所发命令的执行过程,而是立刻返回调用它的程序中,并最终返回到调用块设备读写函数ll_rw_block()的其他程序中去等待块设备IO的完成。

例如高速缓冲区管理程序fs/buffer.c中的读块函数bread()(第267行),在调用了ll_rw_block()之后,就调用等待函数wait_on_buffer()让执行当前内核代码的进程立刻进入睡眠状态,直到相关的设备IO结束,在end_request()函数中被唤醒。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/532219.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

测试用例常见的几种设计方法

我们将从以下几种常见的方法入手,讲解测试用例的设计方法: 基于需求的设计方法、等价类、边界值、因果图、正交排列、场景设计法、错误猜测法。 1.测试用例的基本要素 测试用例(Test Case)是为了实施测试而向被测试的系统提供的一…

Android中AIDL的简单使用(Hello world)

AIDL:Android Interface Definition Language(Android接口定义语言) 作用:跨进程通讯。如A应用调用B应用提供的接口 代码实现过程简述: A应用创建aidl接口,并且创建一个Service来实现这个接口&#xff08…

使用阿里云服务器

一、购买阿里云服务器(如果是学生可以免费体验几个月) 二、开启安全组: (开启安全组): 现在这台服务器是专用网络的,那这边的网卡类型的话就内网。如果您是一个经典网络的服务器,那…

_fs.readFileSync is not a function

背景 项目需要通过读取本地一个 xlsx 的可配置文件,并生成 json 格式的文件。 查找资料发现 js 的 xlsx 库可以对 xlsx 文件进行读写和格式转换的操作,也看到了几篇xlsx结合elementui处理文件的博文,于是写下了如下代码,结果报错…

Servlet技术及代码实现

Servlet概念 Servlet是JavaEE规范之一,规范指的就是接口。Servlet是JavaWeb三大组件之一,三大组件分别是:Servlet程序、Filter过滤器、Listener监听器。Servlet是运行在服务器上的一个java小程序,它可以接收客户端发送过来的请求&#xff0c…

5个设计师都在用的在线网页设计编辑器!

在当今的设计领域,选择一款适合的在线网页设计编辑器对于产设研团队来说至关重要。有许多选择可供考虑,其中包括即时设计、Axure RP、Adobe Illustrator、Sketch 和 Figma 等工具。在这些选择中,即时设计是一款备受推荐的在线网页设计编辑器。…

搭建免费的文件自动同步服务器,无公网IP外网远程访问【Syncthing私人云盘】

文章目录 1. 前言2. Syncthing网站搭建2.1 Syncthing下载和安装2.2 Syncthing网页测试2.3 注册安装cpolar内网穿透 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 转发自CSDN远程穿透的文章:Syncthing文件同步 - 免费搭建开源的文件…

计算机网络 | 基于UDP的C/S模型代码实现

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和…

高端NEV社媒阵地火热加温,蔚来最来“电”,极氪最“美丽”

Social Power 核心解读 汽车高端NEV SMI本月新势力领衔 极氪、凯迪拉克美誉度拉满 社媒阵地,已开局,战不休。 本月由数说故事行业首创的SMI社媒心智品牌榜单中,蔚来最来“电”荣登榜首,理想紧随其后,智己已是三哥。 …

BFT 最前线 | 互联网惊现 AI 鬼城,中国电信天翼云将发布预训练大模型,周鸿祎谈“万模大战”

文 | BFT机器人 01 网易CEO 丁磊:人工智能价值已被引导到生产第一线 网易数帆推出 CodeWave 智能开发平台。据了解,网易数帆结合自身产品的定位,面向智能编程垂直领域推出大模型,并接入到智能开发平台中。网易 CEO 丁磊表示&…

国内AI大模型汇总(附申请网址),建议收藏!

文章目录 前言1. AI文本工具站效率工具自媒体创作工具代码工具 2.道和顺ChatIC3.星期五4.文心一言5.讯飞星火认知大模型6.通义千问7.商汤-日日新8.Moss9.ChatGLM10. 360智脑写在最后 前言 随着ChatGPT迅速走红,国内各大企业纷纷发力认知大模型领域。经过一段时间的酝酿&#x…

【youcans动手学模型】LeNet 模型 MNIST 手写数字识别

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】LeNet 模型 MNIST 手写数字识别 1. LeNet5 卷积神经网络模型1.1 论文简介1.2 卷积神经网络1.3 LeNet5 网络1.4 模型的运行结果 2. 在 PyTorch 中定义 LeNet5 模型类2.1 使用 nn…

如何设计一个合格的高并发秒杀系统

一、前言 在前面的文章中,详细阐述了建设秒杀系统的目标与存在的挑战,并且简单罗列了如何应对这些挑战的方式。本章,就详细阐述对秒杀系统存在挑战的应对之道,最终构建出兼具高并发、高性能和高可用的秒杀系统。心中不仅了解建设…

中原银行:数据资产管理与运营实践

关 注gzh"大数据食铁兽",了解更多的银行大数据案例 案例简介 中原银行整合内外部数据资源,以业务价值为导向,创新面向敏捷组织的AgileData数据治理方法论,依托工具化、自动化、智能化的治理手段与运营方式,…

CSS--移动web基础

01-移动 Web 基础 谷歌模拟器 模拟移动设备,方便查看页面效果 屏幕分辨率 分类: 物理分辨率:硬件分辨率(出厂设置)逻辑分辨率:软件 / 驱动设置 结论:制作网页参考 逻辑分辨率 视口 作用&a…

CVE-2023-32233 Linux kernel

0x01 漏洞介绍 近日,研究人员发现了Linux内核的NetFilter框架中的新漏洞(CVE-2023-32233)。该漏洞可被本地用户用于将权限提升为root,并完全控制系统。问题的根源在于tfilter nf_tables是如何处理批处理请求的,经过身…

科研热点|严整“打招呼”, 国自然基金项目评审请托行为禁止清单来了~

为严整“打招呼”顽疾,5月16日,国家自然科学基金委员会网站公告征求《国家自然科学基金项目评审请托行为禁止清单(征求意见稿)》公众意见。意见稿分别对科研人员、依托单位、评审专家、自然科学基金委工作人员等列出禁止行为清单。…

怎么建企业网站?这份指南告诉你需要知道的事项

随着数字化时代的到来,企业网站已经成为了企业发展过程中不可或缺的一部分。而对于初创企业来说,怎么建企业网站可能会面临许多挑战和问题。本文将介绍如何利用建站工具来轻松建立自己的企业网站。 第一步:选择适合你的模板 建站工具提供了…

EasyImage简单图床 - 快速搭建私人图床云盘同时远程访问

文章目录 1.前言2. EasyImage网站搭建2.1. EasyImage下载和安装2.2. EasyImage网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2 Cpolar内网穿透本地设置 4. 公网访问测试5. 结语 转发自CSDN远程内网穿透的文章:私人图床 - 本地快速搭建简单的E…

LeetCode·每日一题·1335. 工作计划的最低难度·动态规划

作者:小迅 链接:https://leetcode.cn/problems/minimum-difficulty-of-a-job-schedule/solutions/2271898/dong-tai-gui-hua-zhu-shi-chao-ji-xiang-x-4elt/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者…