做存储和计算机架构的研发人员需要深入理解数据在磁盘上的分布,只有这样当系统出现故障的时候才能手动进行系统恢复。目前,磁盘的容量越来越大,故障率越来越高,当故障发生之后需要对磁盘数据进行恢复,磁盘数据的恢复不仅要了解分区等基本的磁盘数据布局,而且需要知道文件系统在磁盘上的数据分布。这里首先讨论分区等系统基本数据在磁盘上的分布。

分区

DOS分区

 

DOS分区是目前常用的一种分区方式,其磁盘数据分布描述如下:

 

数据在磁盘上的布局_休闲

第一个扇区是主引导分区MBRMBR描述了磁盘分区的结构,MBR的内容包括引导代码和分区表信息,最后以标志0xaa55结尾。

MBR中的引导代码是在BIOS启动之后首先得到运行的代码,通常引导代码会检查磁盘分区表,并且判断哪个分区是启动分区,找到那个启动分区之后,然后从启动分区引导操作系统。

DOS分区规定了四个主分区,每个分区最大可以描述2TB的磁盘空间。当磁盘容量增大后,需要采用扩展分区满足应用需求,扩展分区就是在主分区描述的空间中再建分区信息表。在四个主分区中,只能存在一个active的分区,该分区即为启动分区。

GPT分区

 

由于巨磁阻效应的发现,磁盘的容量日益增大,DOS分区存在2TB上限的问题,不能满足日益增长的大分区需求,因此,微软推出了GPTGUID Partition Table),该分区表的磁盘结构如下图所示。

 

数据在磁盘上的布局_DOS分区_02

第一部分是保留MBR,占用一个扇区;第二部分是EFI信息,该部分占用一个扇区,该头描述了分布区的位置信息;第三部分是 分区表,一共占用32个扇区,每个分区表项占用128字节,因此,最多可以容纳128个分区表项;第四部分是分区区域;为了提高可靠性,第五部分为分区表备份区域,占用整个磁盘的最后32个扇区。

Bootload在哪里?

 

知道磁盘的分区信息之后,我们通常会关注操作系统的bootloader具体在哪里?以Linux为例,bootloader通常为grub,嵌入式系统通常采用uboot,这里以grub为例,grub功能比较强大。在安装操作系统的时候,grub就被安装在了boot分区。在Linux中的/boot目录就包含了grub文件和操作系统p_w_picpath文件。

Grub是支持文件系统的,在/boot/grub目录中存在e2fs_stage1_5xfs_stage1_5等文件,这些文件统称为stage1.5,其实就是各个不同文件系统的驱动。这里简要介绍一下grub的构成。Grub的启动文件分为stage1stage2两大部分,stage1是在grub安装的时候由grub拷贝到MBR中的,由于MBR的大小是512字节,因此,stage1文件大小为512字节。Stage1的作用是引导stage2,由于stage2存储在boot 上,其具有文件系统格式,而stage1程序不能很大,因此,无法识别boot分区文件系统,只能采用了程序表的方式在stage1中存储stage2文件和stage1.5文件的位置。

对于grub而言,由于需要获取stage2文件,所以,需要修改MBR中的引导程序,所以,在安装操作系统的时候,grub被安装在了boot分区和MBR中。

系统如何启动?

 

熟悉磁盘数据分布对系统启动过程的了解有一定帮助,在此简要描述一下系统启动过程。

 

1, 系统上电之后,直接将BIOS程序导入内存进行运行,BIOS程序会扫描硬件,并且实现一些基本硬件的驱动(例如PCI扫描)和自检操作。BIOS程序会扫描系统中的启动硬盘,一旦发现一个可以启动的硬盘,BIOS会将启动硬盘内MBR中的引导程序装载入内存,并且将CPU交给引导程序。

 

2, MBR中的引导程序会进行分区表检查,由于该引导程序是grub安装时更新过的,其实际就是grubstage1程序。当所有事情完成之后,引导程序会通过固定地址的方式将启动分区中的grub stage2程序装载入内存,并且将CPU交给stage2程序。

 

3, Stage2程序是grub的主体,其可以识别文件系统。boot分区上有文件系统,这是由用户在安装操作系统时候格式化的,grub会将boot分区mount,这样可以很容易的找到Linux操作系统的镜像文件,在grub运行过程中,有些系统需要一些特殊的驱动,例如,系统根文件系统建立在一个特殊的软RAID之上,那么在启动Linux操作系统之前需要加载特殊的软RAID驱动。为了达到这个目的,可以采用ramdisk的方式为Linux操作系统预加载驱动,ramdisk文件可以在grub配置文件中指定。Grub 完成一些预加载操作,并且将Linux内核加载入内存,然后将CPU资源释放给Linux内核。

 

4, 此时Linux内核开始运行,由于grub已经预加载了一些驱动,因此,Linux也能看到一些特殊的设备,然后Linux会做root switch操作,挂载真正的根文件系统。如果BIOS已经为PCI等设备分配了资源,那么Linux可以直接采用,当然也可以对PCI总线进行重新扫描,并且加载驱动程序。由于根文件系统已经加载,因此,Linux可以根据/etc/inittab启动各种服务,至此Linux系统基本启动完毕。

 

本文概述了分区以及bootloader在磁盘中的数据分布,对于存储系统而言,这是最基本的。