首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从硬件+操作系统的角度解释为什么操作系统的IO单位是磁盘块

从硬件+操作系统的角度解释为什么操作系统的IO单位是磁盘块

作者头像
执生
发布2020-11-24 11:04:26
8040
发布2020-11-24 11:04:26
举报
文章被收录于专栏:立权的博客立权的博客

不同版本的操作系统的 buffer_head 代表的大小可能不一样,但是都是内存和硬盘交换数据的基本单元。

意思是:每次磁盘驱动程序,能写入到硬盘缓存区的数据大小 = buffer_head 代表的大小,线程会等待磁盘缓冲区的内容真正刷入扇区中

写入完成后再唤醒线程,再次将一个块写入到磁盘缓冲区。

我们用旧一点的 Linux 版本验证一下,下图出自 毛德操的《Linux源代码情景分析》

在磁盘的驱动程序向磁盘相关的控制寄存器写入控制信息之后(写入起始扇区号,读还是写等信息)

能向硬盘的写入的 字(16位)数是固定的 一个扇区的字节数,总共写入的字节数 = 扇区大小 * 2

当前语境下的 buffer_head 是 1024 字节,扇区是 512 字节,也就是磁盘块 1024 字节,扇区 512 字节,写入磁盘缓冲区的大小就是磁盘块的大小

随后驱动程序再次写相关的控制寄存器,开启真正的磁盘IO,使得磁盘缓冲区内容写入物理扇区,在此期间写入数据的IO进程如果是阻塞模式需要等待写入完成。

磁盘缓冲区写入到扇区完成后会发出中断,中断程序会唤醒IO进程,IO进程再将下一个 buffer_head 写入磁盘缓冲区,重复上述步骤,这种频繁唤醒睡眠的机制很低效,在新版本应该有优化

驱动程序是硬件厂商(当前考虑硬盘)结合目标操作系统编写的,需要依赖目标操作系统的数据结构(结构体定义),那么也就可以硬件厂商会根据 linux 不同版本的 buffer_head 的大小,还要自己制造的硬件的规格,控制一次能写入磁盘缓冲区的数据大小,让他刚好等于 buffer_head,遵循 linux 的初衷。

节点大小为一个磁盘块,使得一次IO操作就能完成一个节点的写入,读/写一个块 只用一次 中断唤醒,提高效率

关于中断程序和驱动程序的区别:

驱动程序

主要负责对硬件设备的读写,因为不同硬件制造厂商制造硬件的规格各不相同,就要按照自己的规格结合目标操作系统写出良好的驱动程序。

读写当然属于硬件规格的范畴,而且多事一些对控制寄存器和数据寄存器的读写操作(如果操作系统支持 in,out 指令,输入输出几乎都用in ,out)

包括写外设的某些控制寄存器,以准备读写,以及把数据写出到硬件的数据寄存器(CPU拷贝) 或者开启 DMA 进行数据拷贝

中断程序

以硬盘为例,当硬盘读数据到硬盘硬件上的缓存区(应该是寄存器组)完毕,就会通过硬件中断让CPU调用 读取中断程序,主要是拷贝 硬盘缓冲区上的数据到内存中的缓存页上

唤醒在缓冲页上等待的进程,因为进程要读取/写某个缓存页,并且阻塞的话,会进入buffer的 等待队列,中断程序做的就是唤醒他 如果还有已经从磁盘缓冲区读到内存的缓存页待操作,就调整req的下一个缓存页,处理下一个请求页(唤醒该页上等待的进程等)

如果是写入完成,会把缓存页的干净标志设为1

一个请求可能请求 N 个扇区,但是一次中断只完成了 M 个扇区的读取,这次中断只能从硬盘缓冲区拷贝 M 个缓存页到 内存 接下去的 N - M 仍然需要多个中断程序来完成

不同缓冲区可能对应连续的扇区,但是还是得按缓冲区为单位操作,每次只能读/写一个缓冲区(buffer_head)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档