Linux操作系统用来组织和管理文件的系统是十分复杂的。文件系统是软件层的概念,其底层是可以存储数据的硬件,比如硬盘、U盘、软盘等,要想理解上层的文件系统要从底层的硬件系统来着手,不过作为程序员,不需要了解所有的存储硬件的构造,只需要体会其中的设计理念和了解软件层的架构演变过程。
一、机械硬盘
(一)物理结构
传统机械硬盘依靠圆形的盘片来进行数据持久化,每个盘片上有许多半径不同的圆环,每个圆环上可以认为存在着一个个的具有磁性的点,每一个磁点在某一刻处于N极或者S极,用于记录1bit数据,这个圆环通常被称为磁道(track)。最外圈的磁道编号为0,从外向内编号递增。
盘片的上下两面结构是一样的,都可以用来存储数据,其中心固定于主轴上,可以跟着主轴旋转。在盘片的上下两面各有一个固定于磁臂上的磁头(header),磁头可以根据其扫过的磁道上的磁点的磁性来产生不同的电信号,以此来判断当前bit是0还是1。
为了方便数据的格式化管理,制造商将磁道划分成一个个的圆弧,每个圆弧的角度是相同的,存储的数据量也是相同的,默认为512B,这一个圆弧通常被叫做扇区(sector)。每个磁道上的扇区都有着一个编号,磁道第一个扇区的编号为1。
为了存储更多的数据,一块硬盘中通常有很多个盘片,每个盘面都配有一个可以读取磁性的磁头,磁头的编号从0开始,从上到下递增,通常以磁头编号来指代具体的盘面。不同盘面上的相同编号的磁道上的相同编号的扇区的集合,被叫做柱面(cylinder)。
观察前文中列举出的最早的机械硬盘的物理结构,可以发现扇区从盘片的外圈磁道到内圈磁道,扇区的弧长是递减的,但是在设计时他们的容量是相同的,即都是512B。但是由于外圈磁道上的扇区弧长较长,导致其磁性材料的密度较低,浪费容量,所以经过改进,技术人员将磁道划分为了不同的集合。同一个集合内的磁道是相邻的,而且其弧度是相同的,弧长只有细微差距,而不同集合的磁道弧长是相同的,但是弧度不同。
上图所示的盘片结构中,每一个扇区的容量仍然为512B,外圈磁道的扇区最多,内圈磁道的扇区最少。
(二)、数据查找
通过简单了解了机械硬盘的结构,现在应该可以清楚下面这几个概念:
磁道:track 扇区:sector 磁头:header 柱面:cylinder
接着我们来思考一个问题,硬盘是如何读取某个特定位置的数据的呢?首先我们要知道下面两个基本概念:
- 硬盘的CPU
硬盘有自己的CPU和缓存,其CPU能够在接收到存储或者写入目标地址的指令时,根据固化在硬盘ROM中的代码指令操作机械臂移动, 从而能够让磁头移动到目标地址进行数据读写。
- 设备驱动
硬盘作为一个硬件设备,通常是通过主板与CPU进行相连,其他的还比如显卡、键盘、鼠标等,像这种通常也叫作外接设备。而设备的种类和版本又各种各样,所以操作系统将设备抽象成一个个的接口,由设备管理器统一管理。
设备管理器用于管理设备的程序就叫做设备驱动器,如下图所示
这样在我们更换了硬件设备之后,只需要再更新一下对应的设备驱动器就可以了,而操作系统本身对于硬件是否更换了是无感知的,属于一种解耦的设计。
这也就是说机械硬盘上的CPU所接收到的指令是由操作系统通过磁盘驱动下发的。
- 机械硬盘寻址
在硬盘的CPU接收到磁盘驱动下发数据读写的指令后,其中重要的一步就是数据的寻址,其物理意义就是将磁头移动到目标位置。
传统的机械硬盘寻址方式为CHS寻址,最开始的时候地址为24位:
C cylinder 柱面 前8位 编号从0开始
H header 磁头 中间10位 编号从0开始
S sector 扇区 最后6位 编号从1开始
上面参数所代表的意义在前面的已经介绍过,下面来看一个实际的例子:
当机械硬盘的CPU接收到地址0x00000001时,经过CHS的地址转换,可以得到
C = 0
H = 0
S = 1
即目标的实际位置为0号盘面0号磁道的1号扇区,然后就交给硬盘的CPU区控制磁臂将磁头移动到这个位置
不过由于CHS寻址受到地址位数的限制,寻址空间有限,所以现在一般放弃了CHS寻址而采用LBA寻址方式。
(三)、硬盘格式
从硬盘的物理结构可以看出硬盘只是二进制数据的一个载体,而二进制数据本身是没有意义的,就是连续的01二进制序列。那么计算机怎么能分清哪些序列是文件内容,哪些序列是空白呢?所以需要将硬盘中的数据以某种格式组织起来,即硬盘的格式化,从这我们也能够得知硬盘的格式是软件层面的概念,而不是硬盘本身的属性。传统机械硬盘的数据组织方式一般为MBR格式。
MBR格式的硬盘的第一个扇区存放一张MBR表,其由4个部分组成:
其中比较重要的是下面两个部分:
- 主引导程序
主引导程序共446字节大小。其主要提供下面功能:
提供菜单:用户可以选择不同的开机项目(比如装了双系统,选择启动哪个系统的菜单)
载入核心文件:直接指向操作系统的引导代码所处的硬盘位置
转交其他 loader:将开机管理功能转交给其他 loader 负责,主要用于多系统引导。
- 主分区表<