本文就将从 Ext文件系统入手从硬件磁盘入手进行介绍,然后将操作系统与文件系统结合起来为大家介绍操作系统是如何通过内核数据结构与硬件磁盘进行IO操作以及涉及到的内核数据结构为大家进行层层抽丝剥茧下面开始我们的学习吧

1.理解硬件

1.1磁盘

磁盘在生活中非常常见基本上大家电脑上都有一块磁盘比如大家经常提到的C盘D盘本质上就是磁盘进行分区得到的,磁盘我们一般称它为机械磁盘它也是计算机上唯一一个机械设备,它的特点也很简单

运行速度较慢

容量大

价格便宜,相较内存磁盘会便宜很多


磁盘内部基本就是这样子磁盘内部一般都是无菌环境,表面盖子打开这个磁盘也就报废了,关于磁盘感兴趣的可以去了解一下机房和磁铁,这里篇幅原因就不进行介绍了

1.2磁盘的物理结构

磁盘主要物理结构基本上就是这些,主轴马达带动磁盘进行高速旋转磁头臂带动磁头进行左右摆动对于磁盘如何写入数据大家可以把磁盘理解成为纸磁头理解成为笔,磁盘进行读写操作时本质上就是通过磁头进行读写操作的,这里有一个需要注意的点就是磁头与磁盘是不能接触的不然会将盘面刮花从而影响后续读写并且磁盘高速旋转过程中磁头摆动会有摩擦生热使磁盘报废,大家可以将磁盘理解成由若干个磁铁组成的高温会使磁铁消磁。

1.3磁盘的存储结构

将磁盘抽象一下存储结构就是这个样子大家可以将一块磁盘其中一个盘面理解成一个大的圆环,其中每一个环可以理解成为一个磁道,一个磁道有间隙每一个间隙称为一个扇区,因为一个磁盘是由几个类似光盘叠放而成而每一个盘有两个面,所以不同面上相同的磁道组成的面我们称为柱面

扇区:磁盘的基本存储单位,512字节

这里对于一个磁盘来说每一个盘面都有一个磁头,所有的磁头连在同一个传动臂上,因此所有磁头“共进退”,每时每刻每个磁头在同一个位置。

在了解完磁盘的物理结构后既然磁盘是存储数据的物理结构,我们也知道扇区是磁盘的基本存储单位,那么有一个问题 “如何定位一个扇区呢?”


1.我们可以先确定是哪个磁头(header)从而确定是哪一个盘面

2.再确定磁头要访问哪一个柱面(cylinder)即确定是哪个磁道

3.最后定位到是哪一个扇区(sector)


当我们能够定位一个扇区以后那么我们也就能够定位多个扇区,我们知道文件本质上是内容+属性,对于一个文件在磁盘上存储来说无非就是占据几个扇区的问题所以对于磁盘来说定位一个文件本质上可以转换成定位几个扇区的问题。

前面我们学习了扇区是磁盘的基本存储单位,它的大小一般是512字节,因此我们可以算出整个磁盘的容量,本质上就是计算一个磁盘有多少个扇区。


磁盘容量 = 磁头数 X 磁道数(柱面数) X 每个磁道扇区数 X 每个扇区字节数


在Linux系统中可以通过指令fdisk来查询磁盘容量,而我们将这种通过磁头,柱面,扇区进行定位数据的方式称为CHS寻址,也是早期的寻址方式

CHS寻址

对早期的磁盘⾮常有效,知道⽤哪个磁头,读取哪个柱⾯上的第⼏扇区就可以读到数据了。 但是CHS模式⽀持的硬盘容量有限,因为系统⽤8bit来存储磁头地址,⽤10bit来存储柱⾯地 址,⽤6bit来存储扇区地址,⽽⼀个扇区共有512Byte,这样使⽤CHS寻址⼀块硬盘最⼤容量 为256*1024*63*512B=8064MB(1MB=1048576B)(若按1MB=1000000B来算就是 8.4GB)

这里因为用8个bit来存储而而每一位有0/1,所以最大值就是全1的时候即2的8次方即256其他同理。

1.4磁盘的逻辑结构

大家在生活中应该看到过磁带吧,我们将磁带拆开将其拉直就可以形成线性结构

磁盘虽然是硬质的但是我们可以将磁盘想象成卷在一起的磁带,那么我们也可以将其抽象成线性结构

这样看就很熟悉了,很像我们C语言阶段学过的一维数组,学过数组的就会知道不管是二维数组还是三维数组本质上它们都是连续的,我们将磁盘抽象成类似一维数组的结构后这样每一个扇区它都有了类似数组下标的线性地址,我们将这种地址称为LBA。

前面我们学过“所有磁头共进退”,即每时每刻所有磁头都会指向同一个扇区,通过上面的图大家不难看出所有盘面相同磁道组成一个柱面,那么这样我们其实可以将磁盘看成由许多“柱面”卷起来的。

类似我们吃过的山楂卷,而我们将某一个盘面的某一个磁道展开:就可以理解成将一个圆环剪开我们就会得到一个线性结构(即一维数组)

如果我们将一个柱面展开本质上就是不同盘面上的同一磁道展开

前面我们学习过每一个磁道上的扇区是相同的,这里我们就可以将柱面展开抽象成一个二维数组,这样我们就可以通过下标来定位每一个扇区。

在了解柱面展开后,我们前面学习了磁盘是由无数个柱面卷起来的那么将整个磁盘展开,我们就可以将其抽象成无数个柱面展开(即多个个二维数组表)得到的一个三维数组

这样我们就能更好的理解了CHS寻址


即先确定是哪一个柱面(Cylinder),再通过磁头(Head)确定是哪一个盘面,最后再确定扇区(Sector)。对应抽象成三维数组的三个参数


前面讲过无论是二维数组还是三维数组其在内存存储上本质上都是线性的即一维数组:

因此我们就可以将三维数组简化成这样类似一维数组的结构,这样每一个扇区都有了下标即LBA(Logical Block Address)地址,现在操作系统大多使用LBA地址而磁盘使用CHS地址,那么现在我们就会有两个疑问

1.如何得到LBA地址

2.LBA地址与CHS地址如何进行转化

OS只需要使⽤LBA就可以了!! LBA地址转成CHS地址,CHS如何转换成为LBA地址。谁做啊??磁盘 ⾃⼰来做!固件(硬件电路,伺服系统)

对于我们来说只用了解即可

1.5CHS&&LBA地址

CHS转成LBA:

磁头数*每磁道扇区数=单个柱⾯的扇区总数

 LBA=柱⾯号C*单个柱⾯的扇区总数+磁头号H*每磁道扇区数+扇区号S-1

 即:LBA=柱⾯号C*(磁头数*每磁道扇区数)+磁头号H*每磁道扇区数+扇区号S-1

 扇区号通常是从1开始的,⽽在LBA中,地址是从0开始的

 柱⾯和磁道都是从0开始编号的

 总柱⾯,磁道个数,扇区总数等信息,在磁盘内部会⾃动维护,上层开机的时候,会获取到这些参 数。

LBA转成CHS

柱⾯号C=LBA//(磁头数*每磁道扇区数)【就是单个柱⾯的扇区总数】

磁头号H=(LBA%(磁头数*每磁道扇区数))//每磁道扇区数

扇区号S=(LBA%每磁道扇区数)+1

"//": 表⽰除取整

所以:从此往后,在磁盘使⽤者看来,根本就不关⼼CHS地址,⽽是直接使⽤LBA地址,磁盘内部自己转换。

所以: 从现在开始,磁盘就是⼀个元素为扇区的⼀维数组,数组的下标就是每⼀个扇区的LBA地址。OS使⽤磁盘,就可以⽤⼀个数字访问磁盘扇区了。

对于我们来说只需要知道有这么两个地址即可,关于如何转化感兴趣的可以自己试一下。

2.结语

至此,我们从最基础的硬件磁盘出发,完整走完了从物理结构到逻辑抽象的全过程。从看得见摸得着的盘片、磁头、柱面与扇区,到早期的CHS寻址,再到操作系统更易使用的LBA逻辑地址,我们一步步把复杂的机械磁盘,简化成了一个可以用数字下标直接访问的“一维数组”,也彻底搞懂了文件在磁盘上最终是如何被定位与读写的。

理解硬件,是理解Linux文件系统的第一步。只有先看清磁盘的本质工作方式,明白数据是如何被物理存储、逻辑编址,后续我们才能真正深入Ext文件系统的设计原理,理解内核是如何通过各类数据结构,架起操作系统与硬件磁盘之间IO交互的桥梁。硬件是地基,文件系统是上层建筑,当底层逻辑清晰之后,再去学习文件系统的索引、管理与调度,一切都会变得顺理成章。后续我们将继续以此为基础,走进操作系统与文件系统的核心,层层拆解Linux存储体系的奥秘。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐