UEFI-编程开发C语言2-磁盘分区与文件系统
-
参考视频:
-
操作系统只稍微讲到文件系统,以及磁盘的扇区、柱面,好像也有讲稍微有讲到
LVM逻辑卷管理,但是对磁盘整个格式的理解没有串下来,导致当时美亚的时候RAID搞不出来。 -
磁盘这边就讨论的是单个磁盘,不考虑RAID的情况,RAID的情况之后再说。(有一说一会RAID手动恢复还挺赚钱的?一个单子至少都是几百,一般都是千元往上?但是不知道现在行情怎么样)
-
先给一个图,看看磁盘的总体结构,对磁盘中的一些结构有个总体把握。首先介绍一下比较早期的磁盘中的数据结构格式(这个早期的磁盘结构格式其实就是指的
GPT磁盘分区表出来之前,用的还是MBR引导分区),对于MBR和GPT目前就先知道这两个名词先。其他的无需过多关注。
总体图片
- 对于目前先全面理解一下
一个硬盘,目前先不考虑UEFI这个程序到底放在哪里(总之不是放在磁盘中,而是放在主板的ROM上) - 先来回顾一下操作系统的内容,计算机在按下电源键的开机时,执行流程如下:
- 按下电源键开机时,先执行主板
bios程序,进行完一系列的检测和配置以后。开始按照bios设定的系统引导顺序引导系统。 - 假设现在是从磁盘中引导系统,
bios就会将控制权交给硬盘去执行硬盘中的一段二进制程序。那么这个二进制程序是在哪里存放的,这就引出了MBR(master boot record)中文名为主引导记录区。(注意并不是直接转到磁盘中执行,而是先将MBR载入到内存地址起始位置为0x7C00后,bios有段汇编是jmp 0x7C00,最终执行MBR那一段代码。) - 之后就会加载操作系统的引导程序(该程序在本篇文章中不做介绍),执行该程序之后就会加载
内核、驱动、UI等程序
- 按下电源键开机时,先执行主板

MBR型
MBR大致结构图1
下面这张图就表示了MBR型的主要大致结构,这里大致介绍一下,主引导记录MBR。图中有三个要点需要注意的:
MBR引导代码其实就是BIOS自检完要将控制权交给磁盘后,磁盘要执行的代码,其实就是MBR引导代码。MBR分区表,主要就是用来标识下面的四个主分区,并且MBR分区表最多只能标识四个主分区(因为设计比较早所以没有考虑太长远。)- 之后就是标识着
MBR结尾的标识符,类似与PE文件头,这个其实算是MBR文件尾。

- 对于MBR分区表这里再给出一个图片,该图片其实表名了MBR分区表可能起到索引作用。由于一开始设计
MBR主引导记录,固定了其大小为512字节,所以MBR分区只能分出四个主分区表项。

MBR大致结构图2
- 主引导记录的大致结构已经看完了,接下来看看每个主分区的结构。对于每个主分区的结构都会有一个引导扇区,该引导扇区被称做
DBR,英文全称为Dos / Volume Boot Record,有的时候也被称为VBR。 - 目前先有个了解,对于
DBR的具体结构后面会具体介绍。
注意:DBR其实是和文件系统在一个层面的,只是这里为了方便循序渐进的理解,将DBR与文件系统分离了。在大致结构图3中会贴出一个图片。

MBR大致结构图3
- 对于每个主分区中数据这块还需要花费一块空间存储文件系统的一些结构和数据,这个该分区的剩余部分才是真正存放文件的地方。
- 这里我就以
FAT12(FAT文件系统最初始的版本)为例子,画出下图中主分区2的引导程序,这个图才是真正的一块能存储文件的硬盘的主要格式。

- 这里贴出一个图片,表示文件系统和DBR其实是在同一个层面,而并非
MBR与DBR在同一个层面。

MBR大致结构图4
- 在大致结构图1中有提到过,使用
MBR磁盘分区只能有四个主分区。但是这个限制在不使用GPT型磁盘分区也可以绕过该限制 - 绕过该限制的方法就是将任意一个主分区当做一个扩展分区,进行分区的嵌套就可以绕过只能有四个主分区的限制了。
- 我们就以
主分区4作为扩展分区来画出一个大致的图片,具体的还是在后面介绍。

特殊情况的MBR结构
- 当一块硬盘中有两个系统,那么这个硬盘的情况就比较特殊了,如下图所示。

GPT型
GPT型的磁盘分区格式比较复杂,这里来简单描述一下,GPT的磁盘分区格式以便画图能理解。对于MBR,它所在的位置就是磁盘的第一个扇区(每个扇区大小为512字节)。而GPT的磁盘分区格式,一共要占用67个扇区。
- 在磁盘的开头需要使用
34个扇区包括如下:- 第
1个扇区:存放Protective MBR(保护型MBR),只要是用于兼容MBR的磁盘分区 - 第
2个扇区:存放GPT Header,也就是GPT磁盘分区格式的头即标识符 - 第
3~34个扇区:存放GPT Partition Entries,也就是GPT 分区项表,用来描述每一个分区的详细信息。
- 第
- 在磁盘的结尾需要使用
33个扇区,其使用部分如下:- 最后一个扇区:存放
Backup GPT Header,也就是备份GPT头信息 - 倒数第
2~33个扇区:存放Backup GPT Partition Entries,也就是备份的GPT分区项表。
- 最后一个扇区:存放
注意:如果一个磁盘分区是GPT分区,那么其最好是使用UEFI进行启动。
GPT大致结构图1
- 如果一块硬盘采用
GPT分区,那么它的分区结构大致如下:

GPT大致结构图2
- 对于上面的图片中,只是为了方便理解一下GPT分区格式大致结构,接下来就需要稍微了解一下
GPT分区格式是如何分区的。 - 首先
GPT分区的相关信息都记录GPT分区项表中,该分区项表一共有128项表。对于这128项表,有以下几个注意点:
GPT分区表虽然有128项表,但是实际上是你使用多少分区就有多少分区在使用,其他分区还没被初始化。GPT分区表只标明分区的起止扇区,并没标明分区所使用的文件系统类型。GPT分区表的每一项都是固定128字节

- 假设我们现在有两个分区,那么就只有两个分区表项有相应的信息

GPT大致结构图3
- 首先明确一点就是
GPT磁盘分区格式主要就是用来兼容UEFI启动的。所以在GPT制作中有如下几个规范:
- 需要有
EFI系统分区(EFI System Partition),简称ESP- 对于
ESP这个分区,其文件系统必须要求是FAT32- 分区项表中有一个分区类型 ,该分区类型在表示
ESP分区的时候要设置为EFI System Partition
- 但是由于一般在编写
GPT磁盘的时候,基本上都是把ESP放在第一个分区(其实并不强制放在第几个分区),并且对于EFI系统分区其实不止保持着UEFI程序,还有其他系统的启动程序
- 下面这些
.efi程序都是可执行文件,其作用都相当于一个引导程序,也就是Bootloader,该Bootloader运行在运行在UEFI 固件提供的环境下。- 其中
bootx64.efi其实就是,UEFI固件启动时默认寻找的标准启动程序,对于单个系统可以直接加载操作系统内核;而对于多个系统可能调用更高级的Bootloader来载入指定的操作系统内核。也就是bootx64.efi在执行的时候用户可以选择指定操作系统的bootloader。- 对应目录中的
BCD、grub.cfg文件都是对应bootloader的配置文件。
1 | # 注意:这些都是规定好的比如:bootx64.efi文件名字都是规定好的,也必须要放在/EFI/BOOT/这个文件目录下面 |

MBR与GPT兼容性
- 对于
GPT兼容MBR,下面一个图片可以大致说明,就是如下图所示的一个:GPT中保护型MBR(其实就是MBR的结构),只不过其四个分区表项中只有一个在使用- 保护型
MBR分区标识为0xEE,并且这个分区大小通常是0xFFFFFFFF(32位),这样使得旧软件看到这个分区会认为磁盘已占用,避免GPT格式被破坏

存储设备与原理
- 存储设备这块内容算是比较偏向的是操作系统的内容,算是重新回顾一下操作系统。
磁存储
磁带与磁鼓
磁带在1928年就发明了,实际上磁带是一个纸带(今天一般都使用塑料),该纸带(塑料)上均匀粘上铁磁性颗粒
- 读取和写入都只需要一个机械部件(转动)定位,当实际上大多都是磁带转动
- 读取:放大感应电流
- 写入:电磁头(电磁铁)改变磁畴化方向
- 存储特性:
- 价格低,廉价材料,几乎不涉及打规模集成电路
- 容量高
- 可靠性高(可以适当封装)
- 读写性能:
- 勉强可以顺序读写(需要等待定位)
- 随机读写几乎完全不行
- 应用场景:冷数据的存档和备份
磁鼓是对磁带用作类似与内存的发展,但是速度还是比较慢,后面被淘汰(也是对磁带是否能用作随机读写的尝试)
- 用旋转的二维平面存储数据(无法内卷,容量变小)
- 读写延迟不会超过旋转周期(随机读写速度大幅提升)
磁盘
- 结合磁带与磁鼓的优点就有了曾经很热门的存储设备
磁盘,在二维平面上放置许多磁带。
- 存储特性:
- 价格低:高密度、低成本
- 容量高:2.5D,上万磁道
- 可靠性高(高速运转的机械部件是潜在的威胁)
- 读写性能:
- 顺序读写:较高
- 随机读写:勉强(需要定位)
- 应用场景:计算机系统的主力数据存储(便宜,坏了还有可能修)
- 读写扇区:
- 读写头需要到对应的磁道:
7200pm->120rps,寻道时间大约为8.3ms- 转轴盘片旋转到读写头的位置:读写头移动时间通常也需要几个
ms- 通过
缓存/调度等缓解:比如著名的电梯调度算法(已经成为历史的尘埃)。

软盘
软盘主要就是把读写头和盘片分开,实现数据的移动
光存储
光盘
电存储
闪存
分区表结构
接下来就要进入正题了,具体学习一些分区表的数据结构。对于取证而言需要掌握的是
MBR、DBR、EBR,而对于UEFI开发来说,要熟练掌握的就是GPT磁盘分区表。
MBR分区表
- MBR全称也叫做
master-boot-record,翻译过来就是主引导记录。- MBR是给硬盘分区的,其也被称为
DOS分区表。0号扇区的主引导记录MBR。- DOS分区体系的硬盘用分区表记录每个分区的类型、起始位置和分区的大小,其中分区表就在
0号扇区内,所以0号扇区如果损坏那么这个硬盘就不能正确识别分区。- MBR分区表主要由三部分组成:主引导记录代码(可执行代码)、主分区表项、签名标志,其偏移和大小如下图所示:
- 下面就来具体介绍
MBR分区表的具体结构,首先找一个镜像文件使用Winhex打开它(实在不行就打开磁盘的,但是要注意千万不能一不小心修改了什么东东),为了保险起见这里直接用别人博客上的图片。对于下面这张图片来说最重要的有两个:DPT硬盘分区表、分区有效标志0x55AA

- 对于学习
MBR分区表,主要学习的就是DPT硬盘分区表,因为硬盘分区表中记录了四个主分区(如果有)的一些信息。而DPT硬盘分区表中的数据本质上是一个结构体数组,数组中的元素大小为0x10字节。

1 | typedef struct { |
| 名称 | 字节数 | 描述 | 偏移 |
|---|---|---|---|
| boot_flag | 1 | 相当于标志位,0x00标示不可引导,0x80可引导(一般是系统盘) | 0x00-0x00 |
| start_chs | 3 | 分区的起始CHS地址(由于CHS只能寻址到8G,早已淘汰不用,可空) | 0x01-0x03 |
| partition_type | 1 | 分区的类型,0x00表示未使用,0x07表示NTFS文件系统,0x0c表示FAT32,0x83表示Linux文件系统ext4等,0x82表示Linux Swap,0x0F表示扩展分区,0xEE表示GPT保护型MBR | 0x04-0x04 |
| end_chs | 3 | 结束CHS地址(可空) | 0x05-0x07 |
| start_lba | 4 | 分区的起始扇区号 | 0x08-0x0B |
| sector_count | 4 | 分区扇区数 | 0x0C-0x0F |
注意:
- 由于分区扇区数存储的数据只有
4字节,所以只能存储4294967295个扇区,如果每个扇区512字节的话,那每个主分区的大小最多只能是4294967295 × 512字节,约为2T,这就说明了使用MBR格式的分区大小最大只能是2T。随着技术的发展2T的硬盘很常见了,这就导致了MBR格式有点过时了。
DBR分区表
- 大致了解了
DBR分区表后,现在就可以来了解主分区中的,引导扇区DBR的结构。DBR也称为VBR,英文全称为DOS Boot Record / Volume Boot Record,对于不同的文件系统,DBR数据结构是不同的。- 这里主要介绍两种文件系统的DBR表,分别是
NTFS文件系统和FAT文件系统的DBR表- 绝大多数文件系统的
DBR在逻辑上就是一个扇区,但是可能会有扩展引导区。
FAT文件系统DBR
-
为了先做完取证实验,就先来学习
FAT文件系统的DBR,这里对着别人博客的结构体敲一遍吧。首先先来看这个结构体。 -
先来看看
FAT文件系统的DBR总体结构
1 | typedef struct FAT32_DBR{ |
FAT32_Sector结构体
1 | typedef struct FAT32_Sector{ |
- 再来
Basic_BPB
1 | typedef struct Basic_BPB{ |
FAT32_Extend_BPB结构体
1 | typedef struct FAT32_Extend_BPB{ |





