2023年11月25日发(作者:)
GPT分区数据格式分析
1. 背景与前⾔
随着技术的不断提⾼,电⼦产品的集成度变得越来越⾼,硬盘是这⼏年中的⼀个突出产品,近
年来,硬盘容量不断提升,从500G到1TB,⽬前已经能以很便宜的价格买到3TB的硬盘。 分区
就是把⼀块⼤的物理硬盘分成⼀个⼀个的逻辑盘,这样便于⽂档归类,减少坏道损失。
传统的分区格式我们称其为MBR分区,传统的MBR分区格式有⼀个2TB的限制:当个分区⼤⼩
不能超过2TB。
以前在企业和服务器领域,⼀个分区达到2T的情况很正常,所以GPT分区其实很早就已经出现
了,只是个⼈⽤户⽤不到⽽已。
现在,很多⼈⾃⼰就能话很少的钱达到组建⼏TB的磁盘阵列,所以现在个⼈⽤户的操作系统也
开始使⽤GPT分区了。
⽹络上介绍MBR分区的⽂章很多,本⽂不做赘述。但对于GPT分区,⾄少我前段时间查资料发
现深⼊讲解的⽂章还不算多。
本⽂就GPT分区格式进⾏简单的讲解。
本⽂部分资料来源于维基百科:/wiki/GUID_Partition_Table
2. 术语及缩写
术语/缩写解释
GPTGUID Partition Table
MBRMaster Boot Record
LBALogic Block Address
3. GPT分区数据格式
3.1 LBA0
LBA0就是存储设备的第0个逻辑存储块。
逻辑存储块,是与物理存储块进⾏区分的,因为⽬前的⼯艺⽔平导致不论NAND还是机械硬盘
都存在坏块的情况,在使⽤存储设备时,遇到损坏的存储块就会被驱动程序或固件⾃动跳过,
因此坏块对于驱动程序以上的应⽤程序来说是透明的,他们感受不到坏块,也不关注坏块,他
们对存储设备的存储块进⾏的编号称为逻辑块地址(也可以叫:逻辑块编号)。
GPT分区为了兼容传统的MBR分区,其第⼀个逻辑块数据格式与MBR分区⼀致,即:第⼀个逻
辑块就是MBR(主引导记录)。
但为了与传统的MBR分区进⾏区分,GPT分区的分区类型为EE,在传统的MBR中,EE类型的
分区表⽰保护类型,GPT以此来防⽌其数据被⽆意间篡改。
GPT分区的数据格式如下图所⽰:
图 1 GPT分区数据格式
在GPT分区中,每⼀个数据读写单元成为LBA(逻辑块地址),⼀个“逻辑块”相当于传统MBR分
区中的⼀个“扇区”,之所以会有区别,是因为GPT除了要⽀持传统硬盘,还需要⽀持以NAND
FLASH为材料的SSD硬盘,这些硬盘的⼀个读写单元是2KB或4KB,所以GPT分区中⼲脆⽤
LBA来表⽰⼀个基础读写块,当GPT分区⽤在传统硬盘上时,通常,LBA就等于扇区号,有些
物理硬盘⽀持2KB对齐,此时LBA所表⽰的⼀个逻辑块就是2KB的空间。
为了⽅便,我们后⾯仍然将逻辑块称为扇区。
在图1中可以看出:
第0扇区:和传统MBR分区⼀样,仍然为主引导记录
第1扇区:我们称之为“主分区头”
第2~33扇区:共计32个扇区,我们称之为“主分区节点”
最后⼀个扇区(-1扇区):我们称之为“备份分区头”,它就是“主分区头”的⼀个Copy
从-2~-33扇区:共计32个扇区,我们称之为“备份分区节点”,它就是“主分区节点”的⼀个Copy
第34~-34扇区:正常的GPT分区内容,⽂件系统(如:FAT,NTFS,EXT等)就是构建在这⾥
⾯。
下⾯看⼀个GPT分区的第0个扇区,即MBR实例:
图 2 GPT分区的第0个逻辑块-MBR
图2中只截取了第⼀个扇区(地址范围:0x0000~0x01FF)的最末部分,图中,反⾊显⽰的部分
在MBR的数据格式中是⽤于定义4个主分区的,在图2中,可以明确的看出来:只定义了⼀个主
分区,且其类型为0xEE:
⽤WinHex⼯具分析此MBR结果如下:
图 3 WinHex分析GPT的第0个扇区
图3中,WinHex分析结果也显⽰第⼀个分区的类型是EE。
bootloader(或BIOS)根据这个EE就能知道这是⼀个GPT分区表。
3.2 LBA1
参考图1,GPT分区的LBA1中存放的内容我们称为“主分区头(Primary GPT Header)”,主分
区头的数据格式如下:
表格 1 GPT主分区头数据格式
字节偏
长度内容
移
08字节签名("EFI PART", 45 46 49 20 50 41 52 54)
84字节修订版本号(在1.0版中,值是 00 00 01 00)
分区头的⼤⼩(单位是字节,通常是92字节,即 5C 00 00
124字节
00)
分区头(第0-91字节)的CRC32校验,计算前需先将此内容
164字节
写0
204字节保留,必须是 0
248字节当前LBA(这个分区表头的位置)
328字节备份LBA(另⼀个分区表头的位置)
408字节第⼀个可⽤于分区的LBA(主分区表的最后⼀个LBA + 1)
488字节最后⼀个可⽤于分区的LBA(备份分区表的第⼀个LBA − 1)
16字
56
硬盘GUID(在类UNIX系统中也叫UUID)
节
728字节分区表项的起始LBA(在主分区表中是2)
804字节分区表项的数量
844字节⼀个分区表项的⼤⼩(通常是128)
884字节CRC32 of partition array
保留,剩余的字节必须是0(对于512B/LBA的硬盘就是420个
92*
字节)
下⾯是⼀个主分区头的实例:
图 4 GPT分区头实例
在图4的实例中,可以看出,与上⾯的表1中定义的数据格式是⼀⼀对应的。
从图4可以得知,此GPT分区的分区表项是从LBA2开始的:
⼀共有28个分区:
每个分区表项的⼤⼩是128字节:
3.3 LBA2~LBA33
LBA2到LBA33,⼀共32个逻辑块,是⽤于存储分区表项的,每⼀个分区表项就描述了⼀个分
区,分区表项的数据格式如下:
表格 2 GPT分区表项数据格式
起始字节长度内容
016字节分区类型GUID
1616字节分区GUID
328字节起始LBA(⼩端序)
408字节末尾LBA
488字节属性标签(如:bit60表⽰“只读”)
5672字节分区名(可以包括36个UTF-16(⼩端序)字符)
可以看出,GPT分区的分区类型,分区标识,都是⽤GUID进⾏区分的(GUID在Linux上通常叫
UUID),如果你不了解GUID,请⾃⾏请教维基百科。
下⾯是我截取的两个分区表项的实例:
图 5 GPT分区表项实例
将图5对照表2,即可知道这两个分区的具体信息:
分区1:
- 分区范围:LBA[0x20000] ~ LBA[0x4abdf],共计87536KB
- 分区名:modem
分区2:
- 分区范围:LBA[0x60000] ~ LBA[0x600FF],共计128KB
- 分区名:sbl1
分区类型的GUID通常约定如下:
表格 3 分区类型的GUID约定与相关操作系统
GUID[little endian]*含义
00000000-0000-0000-0000-
None
未使⽤
024DEE41-33E7-11D3-
NoneMBR分区表
9D69-0008C781F39F
C12A7328-F81F-11D2-EFI系统分区[EFI System partition (ESP)],必须是VFAT
None
BA4B-00A0C93EC93B
格式
BC13C2FF-59E6-4262-
None
扩展boot分区,必须是VFAT格式
A352-B275FD6F7172
21686148-6449-6E6F-BIOS引导分区,其对应的ASCII字符串
None
744E-656564454649
是"Hah!IdontNeedEFI"。
D3BFE2DE-3DAF-11DF-Intel Fast Flash (iFFS) partition (for Intel Rapid Start
None
BA40-E3A556D89593technology)
E3C9E316-0B5C-4DB8-
Windows
微软保留分区
817D-F92DF00215AE
EBD0A0A2-B9E5-4433-
Windows
基本数据分区
87C0-68B6B72699C7
DE94BBA4-06D1-4D40-
WindowsWindows恢复环境
A16A-BFD50179D6AC
数据分区。Linux曾经使⽤和Windows基本数据分区相同
0FC63DAF-8483-4772-
的GUID。
Linux
8E79-3D69D8477DE4
这个新的GUID是由 GPT fdisk 和 GNU Parted 开发者根
据Linux传统的"8300"分区代码发明的。
44479540-F297-41B2-x86根分区 (/) 这是systemd的发明,可⽤于⽆fstab时的
Linux
9AF7-D131D5F0458A
⾃动挂载
4F68BCE3-E8CD-4DB1-x86-64根分区 (/) 这是systemd的发明,可⽤于⽆fstab时
Linux96E7-FBCAF984B709的⾃动挂载
Linux
Linux
Linux
Linux
Linux
LinuxRAID分区
Linux
Linux
69DAD710-2CE4-4E3C-ARM32根分区 (/) 这是systemd的发明,可⽤于⽆fstab时
B16C-21A1D49ABED3
B921B045-1DF0-41C3-AArch64根分区 (/) 这是systemd的发明,可⽤于⽆fstab
AF44-4C6F280D3FAE
3B8F8425-20E0-4F3B-
907F-1A25A76F98E8fstab时的⾃动挂载
933AC7E1-2EB4-4F13-HOME分区 (/home) 这是systemd的发明,可⽤于⽆
B844-0E14E2AEF915fstab时的⾃动挂载
0657FD6D-A4AB-43C4-
84E5-0933C84B4F4Ffstab时的⾃动挂载
A19D880F-05FC-4D3B-
A006-743F0F84911E
E6D6D379-F507-44C2-
A23C-238F2A3DF928
8DA63339-0007-60C0-
C436-083AC8230908
的⾃动挂载
时的⾃动挂载
服务器数据分区(/srv) 这是systemd的发明,可⽤于⽆
交换分区(swap) 不是systemd的发明,但同样可⽤于⽆
逻辑卷管理器(LVM)分区
保留
* 本表中的GUID使⽤⼩端序表⽰。例如,EFI系统分区的GUID在这⾥写成C12A7328-F81F-
11D2-BA4B-00A0C93EC93B但实际上它对应的16字节的序列是 28 732A C1 1F F8 D2 11 BA
4B 00 A0 C9 3E C9 3B ——只有前3部分的字节序被交换了。
实际上,GUID的约定主要是为了BIOS⽅便识别分区类型,在嵌⼊式系统中,这主要由
bootloader来约定。
GPT分区表项中,有⼀个分区属性的区域,此区域主要是指明此分区的属性,如只读,隐藏,
启动等,通常的约定如下:
表格 4 GPT分区属性标签定义
Bit解释
0系统分区(磁盘分区⼯具必须将此分区保持原样,不得做任何修改)
1EFI隐藏分区(EFI不可见分区)
2传统的BIOS的可引导分区标志
60只读
62隐藏
63不⾃动挂载,也就是不⾃动分配盘符
分区属性标签是位结构的,即:⼀位表⽰⼀个开关
Microsoft还进⼀步对分区的属性进⾏了细分:低位4字节表⽰与分区类型⽆关的属性,⾼位4字
节表⽰与分区类型有关的属性。
3.4 备份分区头与备份分区表项
备份分区头实际上与主分区头的内容完全⼀样,只是它存储在最后⼀个逻辑块(LBA-1)
备份分区表项的内容与分区表项的内容也是完全⼀致的,只是它存放的位置是LBA-33到LBA-2
的区域。
备份分区头与备份分区表项存在的主要意义就是数据恢复。


发布评论