2023年11月25日发(作者:)

GPT分区数据格式分析

1. 背景与前⾔

随着技术的不断提⾼,电⼦产品的集成度变得越来越⾼,硬盘是这⼏年中的⼀个突出产品,近

年来,硬盘容量不断提升,从500G1TB,⽬前已经能以很便宜的价格买到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硬盘,这些硬盘的⼀个读写单元是2KB4KB,所以GPT分区中⼲脆⽤

LBA来表⽰⼀个基础读写块,当GPT分区⽤在传统硬盘上时,通常,LBA就等于扇区号,有些

物理硬盘⽀持2KB对齐,此时LBA所表⽰的⼀个逻辑块就是2KB的空间。

为了⽅便,我们后⾯仍然将逻辑块称为扇区。

在图1中可以看出:

0扇区:和传统MBR分区⼀样,仍然为主引导记录

1扇区:我们称之为主分区头

2~33扇区:共计32个扇区,我们称之为主分区节点

最后⼀个扇区(-1扇区):我们称之为备份分区头,它就是主分区头的⼀个Copy

-2~-33扇区:共计32个扇区,我们称之为备份分区节点,它就是主分区节点的⼀个Copy

34~-34扇区:正常的GPT分区内容,⽂件系统(如:FATNTFSEXT等)就是构建在这⾥

⾯。

下⾯看⼀个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

参考图1GPT分区的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

分区头(第091字节)的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

LBA2LBA33,⼀共32个逻辑块,是⽤于存储分区表项的,每⼀个分区表项就描述了⼀个分

区,分区表项的数据格式如下:

表格 2 GPT分区表项数据格式

起始字节长度内容

016字节分区类型GUID

1616字节分区GUID

328字节起始LBA(⼩端序)

408字节末尾LBA

488字节属性标签(如:bit60表⽰只读

5672字节分区名(可以包括36UTF-16(⼩端序)字符)

可以看出,GPT分区的分区类型,分区标识,都是⽤GUID进⾏区分的(GUIDLinux上通常叫

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-33LBA-2

的区域。

备份分区头与备份分区表项存在的主要意义就是数据恢复。