简介

GPT全称是GUID Partition Table,是硬盘分区的一种格式。

硬盘分区格式有两种,一种是MBR,另一种是GPT。

GPT是随著UEFI引入了,UEFI用来替代BIOS,而GPT用来替代MBR。

GPT相对于MBR的优势有:

  1. LBA是64位的,可以寻址的硬盘地址更多,因此支持的硬盘也更大;
  2. MBR只支持4个分区,而GPT支持更多的分区;
  3. GPT的分区表有主备两份,比MBR更安全;
  4. 可扩展性更好;
  5. 有CRC32来保证数据的完整性;
  6. 每一个分区有一个唯一的GUID;
  7. 每一个分区有一个用GUID表示的分区类型;
  8. 每一个分区有一个字符串名称来表示;

LBA0

LBA0是硬盘的第一个Block。

为了保持兼容性,GPT并没有使用第一个Block,还是将它作为MBR。

对于不支持GPT的系统,这个MBR就必须要使用,此时它就应该是一个Legacy MBR;而对于支持GPT的系统,如果不使用它,就需要把它配置成一个Protective MBR。

Legacy MBR

简单讲一下Legacy MBR,它的结构大致如下:

GPT 架构 gpt-f_sed

其中从446字节开始是MBR表示的4个分区,它的结构如下:

GPT 架构 gpt-f_uefi_02

这里需要注意OSType的值,UEFI规范只能识别0xEF和0xEE两者值。

当值是0xEE的时候,这个MBR才是Protective MBR。

最后补上使用Legacy MBR分区的硬盘的格式:

GPT 架构 gpt-f_硬盘分区_03

 Protective MBR

Protective MBR就是给GPT分区使用的。

它的作用就是兼容老的MBR格式。

它的结构如下:

GPT 架构 gpt-f_gpt_04

它跟Legacy MBR的格式差的不多。主要的差异是在Partition Record中。

这里需要设置其中的一个Partition Record,将它覆盖整个硬盘,这样Legacy MBR相应的工具也能够识别,这个Partition Record的结构如下:

GPT 架构 gpt-f_gpt_05

而另外的3个分区都需要设置成0。

下图是GPT分区的硬盘的格式:

GPT 架构 gpt-f_硬盘分区_06

出现红框部分的原因是硬盘的大小可能超过Partition Record中成员SizeInLBA能够表示的长度。

GPT分区格式

GPT分区的格式在上面的图中大致已经描述出来了,下面是更详细的图:

GPT 架构 gpt-f_gpt_07

首先,LBA0是给Protective MBR使用的。

LBA1是给主Partition Table Header使用的。

最后一个LBA是给备份的Partition Table Header使用的。

它的结构如下:

///
/// GPT Partition Table Header.
///
typedef struct {
  ///
  /// The table header for the GPT partition Table.
  /// This header contains EFI_PTAB_HEADER_ID.
  ///
  EFI_TABLE_HEADER  Header;
  ///
  /// The LBA that contains this data structure.
  ///
  EFI_LBA           MyLBA;
  ///
  /// LBA address of the alternate GUID Partition Table Header.
  ///
  EFI_LBA           AlternateLBA;
  ///
  /// The first usable logical block that may be used
  /// by a partition described by a GUID Partition Entry.
  ///
  EFI_LBA           FirstUsableLBA;
  ///
  /// The last usable logical block that may be used
  /// by a partition described by a GUID Partition Entry.
  ///
  EFI_LBA           LastUsableLBA;
  ///
  /// GUID that can be used to uniquely identify the disk.
  ///
  EFI_GUID          DiskGUID;
  ///
  /// The starting LBA of the GUID Partition Entry array.
  ///
  EFI_LBA           PartitionEntryLBA;
  ///
  /// The number of Partition Entries in the GUID Partition Entry array.
  ///
  UINT32            NumberOfPartitionEntries;
  ///
  /// The size, in bytes, of each the GUID Partition
  /// Entry structures in the GUID Partition Entry
  /// array. This field shall be set to a value of 128 x 2^n where n is
  /// an integer greater than or equal to zero (e.g., 128, 256, 512, etc.).
  ///
  UINT32            SizeOfPartitionEntry;
  ///
  /// The CRC32 of the GUID Partition Entry array.
  /// Starts at PartitionEntryLBA and is
  /// computed over a byte length of
  /// NumberOfPartitionEntries * SizeOfPartitionEntry.
  ///
  UINT32            PartitionEntryArrayCRC32;
} EFI_PARTITION_TABLE_HEADER;

其中EFI_TABLE_HEADER如下:

///
/// Data structure that precedes all of the standard EFI table types.
///
typedef struct {
  ///
  /// A 64-bit signature that identifies the type of table that follows.
  /// Unique signatures have been generated for the EFI System Table,
  /// the EFI Boot Services Table, and the EFI Runtime Services Table.
  ///
  UINT64  Signature;
  ///
  /// The revision of the EFI Specification to which this table
  /// conforms. The upper 16 bits of this field contain the major
  /// revision value, and the lower 16 bits contain the minor revision
  /// value. The minor revision values are limited to the range of 00..99.
  ///
  UINT32  Revision;
  ///
  /// The size, in bytes, of the entire table including the EFI_TABLE_HEADER.
  ///
  UINT32  HeaderSize;
  ///
  /// The 32-bit CRC for the entire table. This value is computed by
  /// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
  ///
  UINT32  CRC32;
  ///
  /// Reserved field that must be set to 0.
  ///
  UINT32  Reserved;
} EFI_TABLE_HEADER;

剩余的部分就是用来表示GPT分区的结构,如下所示:

GPT 架构 gpt-f_硬盘分区_08

关于每个结构体成员的作用在这里不一一说明了。

以上。