GPT: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
No edit summary
 
(14 intermediate revisions by 9 users not shown)
Line 9: Line 9:
|LBA 1||partition header, can be identified by 8 bytes magic "EFI PART" (45h 46h 49h 20h 50h 41h 52h 54h)
|LBA 1||partition header, can be identified by 8 bytes magic "EFI PART" (45h 46h 49h 20h 50h 41h 52h 54h)
|-
|-
|LBA 2..33||partition table entires
|LBA 2..33||partition table entries
|-
|-
| colspan="2" | ...data on disk...
| colspan="2" | ...data on disk...
Line 20: Line 20:
=== LBA 0: Protective Master Boot Record ===
=== LBA 0: Protective Master Boot Record ===


This is kept untouched for backward compatibility. The UEFI specification requires that the PMBR partition table contain one partition record, with the other three partition records set to zero. The partition record should be defined as follows:
This is kept untouched for backward compatibility. There should be a partition covering the entire disk with type 0xEE (unfortunately this is not clear from the spec if this MBR partition should cover the GPT table itself, or all the partitions that the GPT table describes. The phrasing suggest the latter, but since one of the reasons for GPT was to allow larger disks that cannot be described by the 32 bit sector addresses in the MBR table, this makes not much sense.)


{| {{wikitable}}
You could also record the [[EFI System Partition]] with the type 0xEF, but this makes not much sense either: GPT-aware firmware and utilities recognize the GPT and use that instead of the MBR table, and the old ones which don't, well, they don't recognize 0xEF partition type either.
|'''Offset'''||'''Length (bytes)'''||'''Description'''||'''Value'''
|-
|0x0||1||Boot Indicator||Set to 0x00 to indicate a non-bootable partition.
|-
|0x1||3||Starting CHS||Set to 0x000200, corresponding to the Starting LBA field.
|-
|0x4||1||OS Type||Set to 0xEE (GPT Protective)
|-
|0x5||3||Ending CHS||Set to the CHS address of the last logical block on the disk. Set to 0xFFFFFF if the value cannot be represented in this field.
|-
|0x8||4||Starting LBA||Set to 0x00000001 (LBA of GPT Partition Header)
|-
|0xC||4||Ending LBA||Set to the size in logical blocks of the disk, minus one. Set to 0xFFFFFFFF if the size of the disk is too large to be represented in this field.
|}


The PMBR will always exist if the drive contains a GPT, as it is required in order to maintain compatibility with tools expecting an MBR partition table. It's also worth noting that UEFI firmware implementations are also required to parse legacy MBR partition tables in the event that the drive does not contain a GPT.
The UEFI specification explicitly says (in section 12.3.2 Partition Discovery) that PMBR partitioning table should only be parsed when there's no GPT exists. This means if there's a GPT then the storage's partitions will be specified by the GPT table, and only by the GPT.


=== LBA 1: Partition Table Header ===
=== LBA 1: Partition Table Header ===
Line 39: Line 53:
|0xC||4||Header size
|0xC||4||Header size
|-
|-
|0x10||4||CRC32 checksum of the GPT header
|0x10||4||CRC32 checksum of the GPT header (0x0 to 0x5c)
|-
|-
|0x14||4||Reserved
|0x14||4||Reserved
Line 53: Line 67:
|0x38||16||GUID of the disk
|0x38||16||GUID of the disk
|-
|-
|0x48||8||Starting LBA of the GUID Parition Entry array
|0x48||8||Starting LBA of the GUID Partition Entry array
|-
|-
|0x50||4||Number of Parition Entries
|0x50||4||Number of Partition Entries
|-
|-
|0x54||4||Size (in bytes) of each entry in the Parition Entry array - must be a multiple of 8
|0x54||4||Size (in bytes) of each entry in the Partition Entry array - must be a value of 128×2ⁿ where n ≥ 0 (in the past, multiples of 8 were acceptable)
|-
|-
|0x58||4||CRC32 of the Partition Entry array.
|0x58||4||CRC32 of the Partition Entry array.
Line 63: Line 77:
|0x5C||'''blocksize'''-0x5C||Reserved (should be zeroed)
|0x5C||'''blocksize'''-0x5C||Reserved (should be zeroed)
|}
|}
The Partition Entry array can contain unused entries -- that is, the GUID value is set to zero. For the purposes of the GPT header, these should be counted when considering the Number of Partition Entries field, and should also be taken into account when calculating the CRC32 of the entire array. There should be no more entries in the array, unused or otherwise, than are indicated by this field.
Note: it is somewhat vague what the Number of Partition Entries field contain. For many applications that is the number of '''actually used''' entries, while many partitioning tools (most notably fdisk and gdisk) handles that as the number of '''maximum available''' entries, using full zero Partition Type to mark empty entries. Unfortunately both interpretation is suggested by the EFI spec, so this is unclear. One thing is certain, there should be no more entries (empty or not) than this field.


For the checksums in the header, the CCITT32 ANSI CRC method is used, the one with the polynominal 0x04c11db7 (same as in gzip, and different to the Castagnoli CRC32 that hardware accelerated CRC instructions calculate).
For the checksums in the header, the CCITT32 ANSI CRC method is used, the one with the polynomial 0x04c11db7 (same as in gzip, and different to the Castagnoli CRC32 that hardware accelerated CRC instructions calculate). The header checksum field at 0x10 is zeroed during calculation and the reserved data are not included.


=== LBA 2: Partition Entries ===
=== LBA 2: Partition Entries ===
Line 79: Line 93:
|0x10||16||Unique Partition GUID
|0x10||16||Unique Partition GUID
|-
|-
|0x20||8||StartingLBA
|0x20||8||Starting LBA
|-
|-
|0x28||8||EndingLBA
|0x28||8||Ending LBA
|-
|-
|0x30||8||Attributes
|0x30||8||Attributes
Line 90: Line 104:
Partition type has no central registry, but with 16 bytes it is unlikely that there'll ever be a collision. You can find types for OSes on their corresponding corporation's website (for MacOSX see Apple; for Windows see Microsoft etc.)
Partition type has no central registry, but with 16 bytes it is unlikely that there'll ever be a collision. You can find types for OSes on their corresponding corporation's website (for MacOSX see Apple; for Windows see Microsoft etc.)


Attributes is a bit set. Bit 1 (attrib & 1) means that the partition is required by the firmware and should not be touched. [[EFI System Partition]] would be a good example, however that's always explicitly assumed to have this bit set. Bit 2 (attrib & 2) means that the partition contains necessary files to boot an operating system (defined as EFI_PART_USED_BY_OS). This is somewhat similar to 0x80 boot flag for MBR partitions, but not entirely.
Attributes is a bit set. Bit 0 (attrib & 1) means that the partition is required by the firmware and should not be touched. [[EFI System Partition]] would be a good example, however that's always explicitly assumed to have this bit set. Bit 2 (attrib & 2) means that the partition contains necessary files to boot an operating system (defined as EFI_PART_USED_BY_OS). This is somewhat similar to 0x80 boot flag for MBR partitions, but not entirely.


Name is UNICODE16-LE encoded, meaning it can only store the UNICODE Bilingual Plane (code points 32 to 65535), and each character consumes 2 bytes. However the EFI spec defines name length as 72 bytes (36 characters), you should never hard-code this into your application. Always use (Partition Entry Size in header at 0x54) - 0x38 instead.
Name is UNICODE16-LE encoded, meaning it can only store the UNICODE Bilingual Plane (code points 32 to 65535), and each character consumes 2 bytes. However the EFI spec defines name length as 72 bytes (36 characters), you should never hard-code this into your application. Always use (Partition Entry Size in header at 0x54) - 0x38 instead.
Line 97: Line 111:
The following utilities can handle GPT:
The following utilities can handle GPT:
* [http://www.gnu.org/software/parted/manual/parted.html parted], [http://linux.die.net/man/8/gparted gparted], [http://www.rodsbooks.com/gdisk/ gdisk] on Linux
* [http://www.gnu.org/software/parted/manual/parted.html parted], [http://linux.die.net/man/8/gparted gparted], [http://www.rodsbooks.com/gdisk/ gdisk] on Linux
* [http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/diskutil.8 diskutil] on MacOSX
* [https://www.unix.com/man-page/OSX/8/diskutil/ diskutil] on MacOSX
* [http://technet.microsoft.com/en-us/library/bb490893.aspx diskpart] on Windows (Vista and upwards)
* [http://technet.microsoft.com/en-us/library/bb490893.aspx diskpart] on Windows (Vista and upwards)
* [http://www.freebsd.org/cgi/man.cgi?query=gpt&manpath=FreeBSD+7.1-RELEASE gpt] on MacOSX and BSDs.
* [http://www.freebsd.org/cgi/man.cgi?query=gpt&manpath=FreeBSD+7.1-RELEASE gpt] on MacOSX and BSDs.
* [https://gitlab.com/bztsrc/bootboot/tree/master/mkbootimg mkbootimg] an easy to use disk image creator available on Windows, MacOSX and Linux.


== Boot loaders ==
== Boot loaders ==
Line 118: Line 131:
* [http://msdn.microsoft.com/en-us/windows/hardware/gg463524.aspx GPT on MSDN]
* [http://msdn.microsoft.com/en-us/windows/hardware/gg463524.aspx GPT on MSDN]
* [http://developer.apple.com/library/mac/#technotes/tn2166/_index.html GPT on Apple Developer]
* [http://developer.apple.com/library/mac/#technotes/tn2166/_index.html GPT on Apple Developer]
* [http://www.ibm.com/developerworks/linux/library/l-gpt/ GPT on IBM devloperWorks]
* [http://www.ibm.com/developerworks/linux/library/l-gpt/ GPT on IBM developerWorks]
* [[wikipedia:GUID_Partition_Table|Wikipedia: GUID Partition Table]]
* [[wikipedia:GUID_Partition_Table|Wikipedia: GUID Partition Table]]
* [[wikipedia:BIOS_Boot_partition|Wikipedia: BIOS Boot partition]]
* [[wikipedia:BIOS_Boot_partition|Wikipedia: BIOS Boot partition]]


[[Category:X86]]
[[Category:Disks]]
[[Category:X86-64]]
[[Category:IA-64]]
[[Category:UEFI]]
[[Category:UEFI]]
[[Category:Firmware]]
[[Category:Firmware]]

Latest revision as of 04:40, 9 July 2023

GPT stands for GUID Partition Table. It is made to replace MBR partitioning.

Layout

A GPT partitioned media looks like this:

LBA 0 Protective Master Boot Record (PMBR). Holds a partition pointing to GPT to avoid accidental overwrite by old programs.
LBA 1 partition header, can be identified by 8 bytes magic "EFI PART" (45h 46h 49h 20h 50h 41h 52h 54h)
LBA 2..33 partition table entries
...data on disk...
LBA -33..-2 mirror of partition table
LBA -1 mirror of partition header on last addressable sector

LBA 0: Protective Master Boot Record

This is kept untouched for backward compatibility. The UEFI specification requires that the PMBR partition table contain one partition record, with the other three partition records set to zero. The partition record should be defined as follows:

Offset Length (bytes) Description Value
0x0 1 Boot Indicator Set to 0x00 to indicate a non-bootable partition.
0x1 3 Starting CHS Set to 0x000200, corresponding to the Starting LBA field.
0x4 1 OS Type Set to 0xEE (GPT Protective)
0x5 3 Ending CHS Set to the CHS address of the last logical block on the disk. Set to 0xFFFFFF if the value cannot be represented in this field.
0x8 4 Starting LBA Set to 0x00000001 (LBA of GPT Partition Header)
0xC 4 Ending LBA Set to the size in logical blocks of the disk, minus one. Set to 0xFFFFFFFF if the size of the disk is too large to be represented in this field.

The PMBR will always exist if the drive contains a GPT, as it is required in order to maintain compatibility with tools expecting an MBR partition table. It's also worth noting that UEFI firmware implementations are also required to parse legacy MBR partition tables in the event that the drive does not contain a GPT.

LBA 1: Partition Table Header

Right after the first sector, there's a special sector to identify GPT. This sector is repeated in the last sector of the media (pointed by the field at 0x20).

Offset Length (bytes) Description
0x0 8 Signature, can be identified by 8 bytes magic "EFI PART" (45h 46h 49h 20h 50h 41h 52h 54h)
0x8 4 GPT Revision
0xC 4 Header size
0x10 4 CRC32 checksum of the GPT header (0x0 to 0x5c)
0x14 4 Reserved
0x18 8 The LBA containing this header
0x20 8 The LBA of the alternate GPT header
0x28 8 The first usable block that can be contained in a GPT entry
0x30 8 The last usable block that can be contained in a GPT entry
0x38 16 GUID of the disk
0x48 8 Starting LBA of the GUID Partition Entry array
0x50 4 Number of Partition Entries
0x54 4 Size (in bytes) of each entry in the Partition Entry array - must be a value of 128×2ⁿ where n ≥ 0 (in the past, multiples of 8 were acceptable)
0x58 4 CRC32 of the Partition Entry array.
0x5C blocksize-0x5C Reserved (should be zeroed)

The Partition Entry array can contain unused entries -- that is, the GUID value is set to zero. For the purposes of the GPT header, these should be counted when considering the Number of Partition Entries field, and should also be taken into account when calculating the CRC32 of the entire array. There should be no more entries in the array, unused or otherwise, than are indicated by this field.

For the checksums in the header, the CCITT32 ANSI CRC method is used, the one with the polynomial 0x04c11db7 (same as in gzip, and different to the Castagnoli CRC32 that hardware accelerated CRC instructions calculate). The header checksum field at 0x10 is zeroed during calculation and the reserved data are not included.

LBA 2: Partition Entries

Usually after the EFI header sector, comes the table itself, however this could be defined in a GPT header field at 0x48 otherwise. For compatibility it is recommended to use LBA 2. The table is repeated at the end of the media before the alternate GPT header sector.

Each entry in the table looks like this:

Offset Length (bytes) Description
0x0 16 Partition Type GUID (zero means unused entry)
0x10 16 Unique Partition GUID
0x20 8 Starting LBA
0x28 8 Ending LBA
0x30 8 Attributes
0x38 72 Partition Name

Partition type has no central registry, but with 16 bytes it is unlikely that there'll ever be a collision. You can find types for OSes on their corresponding corporation's website (for MacOSX see Apple; for Windows see Microsoft etc.)

Attributes is a bit set. Bit 0 (attrib & 1) means that the partition is required by the firmware and should not be touched. EFI System Partition would be a good example, however that's always explicitly assumed to have this bit set. Bit 2 (attrib & 2) means that the partition contains necessary files to boot an operating system (defined as EFI_PART_USED_BY_OS). This is somewhat similar to 0x80 boot flag for MBR partitions, but not entirely.

Name is UNICODE16-LE encoded, meaning it can only store the UNICODE Bilingual Plane (code points 32 to 65535), and each character consumes 2 bytes. However the EFI spec defines name length as 72 bytes (36 characters), you should never hard-code this into your application. Always use (Partition Entry Size in header at 0x54) - 0x38 instead.

Utilities

The following utilities can handle GPT:

Boot loaders

EFI firmware is capable of booting from a specific GPT partition, EFI System Partition which is basically a FAT32 partition. It should contain a slightly modified PE-executable, like ELILO. On old machines with legacy BIOS only you can use GRUB, or you can write a custom boot code.

Limine fully supports GPT both when using UEFI and when using BIOS. Furthermore, unlike GRUB, when using BIOS, it supports embedding itself into the GPT structures as to make an additional reserved partition unnecessary (but an can be optionally configured to use one anyways).

BOOTBOOT by default boots your kernel from EFI System Partition. On UEFI machines it does that natively, and on legacy BIOS systems and other platforms (ARM for example) it interprets GPT and ESP on its own.

See Also

Articles

External Links