Glossary:
- UUID -(Universally Unique Identifier)
- GUID – (Globally Unique ID)
- EFI – (Extensible Firmware Interface)
- UEFI – (Unified EFI) – EFI evolution
- GPT (GUID Partition Table) – it is the EFI standard part
- partitions – lists of available partitions (defined at u-boot):
./include/configs/{target}.h
Introduction:
This document describes the GPT partition table format and usage of the gpt command in u-boot.
UUID introduction:
GPT for marking disks/partitions is using the UUID. It is supposed to be a globally unique value. A UUID is a 16-byte (128-bit) number. The number of theoretically possible UUIDs is therefore about 3 x 10^38.
More often UUID is displayed as 32 hexadecimal digits, in 5 groups, separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
(32 digits and 4 hyphens)
For instance, GUID of Basic data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 and GUID of Linux filesystem data: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
Historically there are 5 methods to generate this number. The oldest one is combining machine’s MAC address and timer (epoch) value.
Successive versions are using MD5 hash, random numbers and SHA-1 hash. All major OSes and programming languages are providing libraries to compute UUID (e.g.
uuid command line tool).
GPT brief explanation:
Layout:
----------------------------------------------------------
LBA 0 |Protective MBR | legacy MBR
----------------------------------------------------------
LBA 1 |Primary GPT Header | Primary
-----------|---------------------------------| GPT
LBA 2 |Entry 1|Entry 2| Entry 3| Entry 4|
-----------|---------------------------------|
LBA 3~33 |Entries 5 ~ 128 |
| |
| |
----------------------------------------------------------
LBA 34 |Partition 1 |Partitions
| |
|---------------------------------|
|Partition 2 |
| |
|---------------------------------|
|Partition n |
| |
----------------------------------------------------------
LBA -34 |Entry 1|Entry 2| Entry 3| Entry 4| Backup
-----------|---------------------------------| GPT
LBA -33 |Entries 5 ~ 128 |
| |
| |
LBA -2 | |
-----------|---------------------------------|
LBA -1 |Backup GPT Header |
----------------------------------------------------------
For a legacy reasons, GPT’s LBA 0 sector has a MBR structure. It is called "protective MBR".
Its first partition entry ID has 0xEE value, and disk software, which is not handling the GPT sees it as a storage device without free space.
It is possible to define 128 linearly placed partition entries.
"LBA -1" means the last addressable block (in the mmc subsystem:
"dev_desc->lba – 1")
Primary/Backup GPT header:
Offset Size Description
0 8 B Signature ("EFI PART", 45 46 49 20 50 41 52 54)
8 4 B Revision (For version 1.0, the value is 00 00 01 00)
12 4 B Header size (in bytes, usually 5C 00 00 00 meaning 92 bytes)
16 4 B CRC32 of header (0 to header size), with this field zeroed during calculation
20 4 B Reserved (ZERO);
24 8 B Current LBA (location of this header copy)
32 8 B Backup LBA (location of the other header copy)
40 8 B First usable LBA for partitions (primary partition table last LBA + 1)
48 8 B Last usable LBA (secondary partition table first LBA - 1)
56 16 B Disk GUID (also referred as UUID on UNIXes)
72 8 B Partition entries starting LBA (always 2 in primary copy)
80 4 B Number of partition entries
84 4 B Size of a partition entry (usually 128)
88 4 B CRC32 of partition array
92 * Reserved; must be ZERO (420 bytes for a 512-byte LBA)
TOTAL: 512 B
IMPORTANT:
GPT headers and partition entries are protected by CRC32 (the POSIX CRC32).
Primary GPT header and Backup GPT header have swapped values of "Current LBA" and "Backup LBA" and therefore different CRC32 check-sum.
CRC32 for GPT headers (field "CRC of header") are calculated up till "Header size" (92), NOT 512 bytes.
CRC32 for partition entries (field "CRC32 of partition array") is calculated for the whole array entry ( Number_of_partition_entries *
sizeof(partition_entry_size (usually 128)))
Observe, how Backup GPT is placed in the memory. It is NOT a mirror reflect of the Primary.
Partition Entry Format: (128 bytes)
----------------------
Offset Size Description
0 16 B Partition type GUID (Big Endian)
16 16 B Unique partition GUID in (Big Endian)
32 8 B First LBA (Little Endian)
40 8 B Last LBA (inclusive)
48 8 B Attribute flags [+]
56 72 B Partition name (text)
Attribute flags: (8 bytes/64 bits)
Bit 0 - System partition
Bit 1 - Hide from EFI
Bit 2 - Legacy BIOS bootable
Bit 48-63 - Defined and used by the individual partition type
For Basic data partition type: (last 4 bits)
Bit 60 - Read-only
Bit 62 - Hidden
Bit 63 - Not mount
Creating GPT partitions in U-Boot:
To restore GUID partition table one needs to:
-
Define partition layout in the environment.
Format of partitions layout:
"uuid_disk=…;name=u-boot,size=60MiB,uuid=…;
name=kernel,size=60MiB,uuid=…;"
or
"uuid_disk=${uuid_gpt_disk};name=${uboot_name},
size=${uboot_size},uuid=${uboot_uuid};"The fields ‘name’ and ‘size’ are mandatory for every partition.
The field ‘start’ is optional.If field ‘size’ of the last partition is 0, the partition is extended up to the end of the device.
The fields ‘uuid’ and ‘uuid_disk’ are optional if CONFIG_RANDOM_UUID is enabled. A random uuid will be used if omitted or they point to an empty/non-existent environment variable. The environment variable will be set to the generated UUID. The ‘gpt guid’ command reads the current value of the uuid_disk from the GPT.
The field ‘bootable’ is optional, it is used to mark the GPT partition bootable (set attribute flags "Legacy BIOS bootable").
"name=u-boot,size=60MiB;name=boot,size=60Mib,bootable;name=rootfs,size=0"
It can be used to locate bootable disks with command "part list-bootable ", please check out doc/README.distro for use. -
Define ‘CONFIG_EFI_PARTITION’ and ‘CONFIG_CMD_GPT’
-
From u-boot prompt type:
gpt write mmc 0 $partitions
Checking (validating) GPT partitions in U-Boot:
Procedure is the same as above. The only change is at point 3.
At u-boot prompt one needs to write:
gpt verify mmc 0 [$partitions]
where [$partitions] is an optional parameter.
When it is not provided, only basic checks based on CRC32 calculation for GPT header and PTEs are performed.
When provided, additionally partition data – name, size and starting offset (last two in LBA) – are compared with data defined in ‘$partitions’ environment variable.
After running this command, return code is set to 0 if no errors found in on non-volatile medium stored GPT.
Following line can be used to assess if GPT verification has succeed:
U-BOOT> gpt verify mmc 0 $partitions
U-BOOT> if test $? = 0; then echo "GPT OK"; else echo "GPT ERR"; fi
Renaming GPT partitions from U-Boot:
GPT partition names are a mechanism via which userspace and U-Boot can communicate about software updates and boot failure. The ‘gpt guid’, ‘gpt read’, ‘gpt rename’ and ‘gpt swap’ commands facilitate programmatic renaming of partitions from bootscripts by generating and modifying the partitions layout string. Here is an illustration of employing ‘swap’ to exchange ‘primary’ and ‘backup’ partition names:
U-BOOT> gpt swap mmc 0 primary backup
Afterwards, all partitions previously named ‘primary’ will be named ‘backup’, and vice-versa. Alternatively, single partitions may be renamed. In this example, the first partition of mmc0 will be renamed to ‘primary’:
U-BOOT> gpt rename mmc 0 1 primary
The GPT functionality may be tested with the ‘sandbox’ board by creating a disk image as described under ‘Block Device Emulation’ in doc/arch/index.rst:
=>host bind 0 ./disk.raw
=> gpt read host 0
[ . . . ]
=> gpt swap host 0 name othername
[ . . . ]
Modifying GPT partition layout from U-Boot:
The entire GPT partition layout can be exported to an environment variable and then modified enmasse. Users can change the partition numbers, offsets, names and sizes. The resulting variable can used to reformat the device. Here is an example of reading the GPT partitions into a variable and then modifying them:
U-BOOT> gpt read mmc 0 current_partitions
U-BOOT> env edit current_partitions
edit: uuid_disk=[…];name=part1,start=0x4000,size=0x4000,uuid=[…];
name=part2,start=0xc000,size=0xc000,uuid=[…];[ . . . ]
U-BOOT> gpt write mmc 0 $current_partitions
U-BOOT> gpt verify mmc 0 $current_partitions
Partition type GUID:
For created partition, the used partition type GUID is PARTITION_BASIC_DATA_GUID (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7).
If you define ‘CONFIG_PARTITION_TYPE_GUID’, a optionnal parameter ‘type’ can specify a other partition type guid:
"uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
name=kernel,size=60MiB,uuid=...,
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4;"
Some strings can be also used at the place of known GUID :
"system" = PARTITION_SYSTEM_GUID
(C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
"mbr" = LEGACY_MBR_PARTITION_GUID
(024DEE41-33E7-11D3-9D69-0008C781F39F)
"msft" = PARTITION_MSFT_RESERVED_GUID
(E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
"data" = PARTITION_BASIC_DATA_GUID
(EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
"linux" = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID
(0FC63DAF-8483-4772-8E79-3D69D8477DE4)
"raid" = PARTITION_LINUX_RAID_GUID
(A19D880F-05FC-4D3B-A006-743F0F84911E)
"swap" = PARTITION_LINUX_SWAP_GUID
(0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
"lvm" = PARTITION_LINUX_LVM_GUID
(E6D6D379-F507-44C2-A23C-238F2A3DF928)
"u-boot-env" = PARTITION_U_BOOT_ENVIRONMENT
(3DE21764-95BD-54BD-A5C3-4ABE786F38A8)
"uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
name=kernel,size=60MiB,uuid=...,type=linux;"
They are also used to display the type of partition in "part list" command.
Useful info:
Two programs, namely: ‘gdisk’ and ‘parted’ are recommended to work with GPT recovery. Both are able to handle GUID partitions.
Please, pay attention at -l switch for parted.
"uuid" program is recommended to generate UUID string. Moreover it can decode (-d switch) passed in UUID string. It can be used to generate partitions UUID passed to u-boot environment variables.
If optional CONFIG_RANDOM_UUID is defined then for any partition which environment uuid is unset, uuid is randomly generated and stored in correspond environment variable.
GPT
詞彙表:
- UUID -(通用唯一識別子)
- GUID – (全域唯一 ID)
- EFI – (可擴展固件介面)
- UEFI – (統一 EFI) – EFI 的演變
- GPT(GUID 分區表)——它是 EFI 標準部分
- partitions – 可用分區列表(在 u-boot 中定義):
./include/configs/{target}.h
介紹:
本文介紹了 u-boot 中 gpt 命令的 GPT 分區表格式和用法。
UUID 簡介:
用於標記磁碟/分區的 GPT 使用 UUID。它應該是一個全域唯一的值。UUID 是一個 16 位元組 (128 位) 的數位。因此,理論上可能的 UUID 數量約為 3 x 10^38。
更常見的是,UUID 顯示為 32 個十六進位數位,分為 5 個組,用連字元分隔,格式為 8-4-4-4-12,總共 36 個字元
(32 位數位和 4 個連字元)
例如,基本數據分區的 GUID:EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 和 Linux 文件系統數據的 GUID:0FC63DAF-8483-4772-8E79-3D69D8477DE4
歷史上有5種方法可以生成這個數位。最早的是將計算機的 MAC 位址和計時器 (epoch) 值組合在一起。
後續版本使用 MD5 哈希、隨機數和 SHA-1 哈希。所有主要的作系統和程式設計語言都提供了計算 UUID 的庫(例如
uuid 命令行工具)。
GPT簡要說明:
Layout:
----------------------------------------------------------
LBA 0 |Protective MBR | legacy MBR
----------------------------------------------------------
LBA 1 |Primary GPT Header | Primary
-----------|---------------------------------| GPT
LBA 2 |Entry 1|Entry 2| Entry 3| Entry 4|
-----------|---------------------------------|
LBA 3~33 |Entries 5 ~ 128 |
| |
| |
----------------------------------------------------------
LBA 34 |Partition 1 |Partitions
| |
|---------------------------------|
|Partition 2 |
| |
|---------------------------------|
|Partition n |
| |
----------------------------------------------------------
LBA -34 |Entry 1|Entry 2| Entry 3| Entry 4| Backup
-----------|---------------------------------| GPT
LBA -33 |Entries 5 ~ 128 |
| |
| |
LBA -2 | |
-----------|---------------------------------|
LBA -1 |Backup GPT Header |
----------------------------------------------------------
由於遺留原因,GPT 的 LBA 0 扇區具有 MBR 結構。它被稱為「保護性 MBR」。
它的第一個分區條目 ID 具有 0xEE 值,而不處理 GPT 的磁碟軟體將其視為沒有可用空間的儲存設備。
可以定義128個線性放置的分區條目。
"LBA -1" 表示最後一個可尋址塊(在 mmc 子系統中:"
dev_desc->lba – 1")
主/備份 GPT 標頭:
Offset Size Description
0 8 B Signature ("EFI PART", 45 46 49 20 50 41 52 54)
8 4 B Revision (For version 1.0, the value is 00 00 01 00)
12 4 B Header size (in bytes, usually 5C 00 00 00 meaning 92 bytes)
16 4 B CRC32 of header (0 to header size), with this field zeroed during calculation
20 4 B Reserved (ZERO);
24 8 B Current LBA (location of this header copy)
32 8 B Backup LBA (location of the other header copy)
40 8 B First usable LBA for partitions (primary partition table last LBA + 1)
48 8 B Last usable LBA (secondary partition table first LBA - 1)
56 16 B Disk GUID (also referred as UUID on UNIXes)
72 8 B Partition entries starting LBA (always 2 in primary copy)
80 4 B Number of partition entries
84 4 B Size of a partition entry (usually 128)
88 4 B CRC32 of partition array
92 * Reserved; must be ZERO (420 bytes for a 512-byte LBA)
總計: 512 B
重要:
GPT 標頭和分區條目受 CRC32 (POSIX CRC32) 保護。
主 GPT 報頭和備份 GPT 報頭交換了"當前 LBA"和"備份 LBA"的值,因此 CRC32 校驗和不同。
GPT 報頭的 CRC32(位元段"報頭的 CRC")計算到"報頭大小"(92),而不是 512 位元組。
分區條目的 CRC32(字段"分區陣列的CRC32")是針對整個陣列條目計算的 ( Number_of_partition_entries *
sizeof(partition_entry_size (通常為 128)))
觀察Backup GPT是如何放置在記憶體中的。它不是 Primary 的鏡像。
Partition Entry Format: (128 bytes)
----------------------
Offset Size Description
0 16 B Partition type GUID (Big Endian)
16 16 B Unique partition GUID in (Big Endian)
32 8 B First LBA (Little Endian)
40 8 B Last LBA (inclusive)
48 8 B Attribute flags [+]
56 72 B Partition name (text)
Attribute flags: (8 bytes/64 bits)
Bit 0 - System partition
Bit 1 - Hide from EFI
Bit 2 - Legacy BIOS bootable
Bit 48-63 - Defined and used by the individual partition type
For Basic data partition type: (last 4 bits)
Bit 60 - Read-only
Bit 62 - Hidden
Bit 63 - Not mount
在 U-Boot 中建立 GPT 分區:
要恢復 GUID 分區表,需要:
-
在環境中定義分區佈局。
分區佈局格式為:"uuid_disk=...;name=u-boot,size=60MiB,uuid=...;name=kernel,size=60MiB,uuid=...;"或
"uuid_disk=${uuid_gpt_disk};name=${uboot_name},size=${uboot_size},uuid=${uboot_uuid};"- 欄位 ‘name’ 和 ‘size’ 對於每個分區都是強制性的。
- 欄位 ‘start’ 是可選的。
- 如果最後一個分區的欄位 ‘size’ 為 0,則分區將擴展到設備的末尾。
- 如果啟用了 CONFIG_RANDOM_UUID,則字段 ‘uuid’ 和 ‘uuid_disk’ 是可選的。如果省略,則將使用隨機 uuid,或者它們指向空/不存在的環境變數。環境變數將設置為生成的 UUID。"gpt guid"命令從 GPT 中讀取uuid_disk的當前值。
- 欄位 ‘bootable’ 是可選的,它用於將 GPT 分區標記為可啟動(設置屬性標誌 "Legacy BIOS bootable")。
- "名稱=u-boot,大小=60MiB;name=boot,size=60Mib,可啟動;name=rootfs,size=0" 可以通過命令 "part list -bootable " 來定位可啟動磁碟 ,請查看 doc/README.distro 使用。
- 定義 ‘CONFIG_EFI_PARTITION’ 和 ‘CONFIG_CMD_GPT’
-
從 u-boot 提示符鍵入:
gpt write mmc 0 $partitions
在 U-Boot 中檢查(驗證)GPT 分區:
程式同上。唯一的變化是在第 3 點。
在 u-boot 提示符處,需要寫成:
gpt verify mmc 0 [$partitions]
其中 [$partitions] 是可選參數。
如果未提供,則僅執行基於 GPT 標頭和 PTE 的 CRC32 計算的基本檢查。
如果提供,還會將分區數據(名稱、大小和起始偏移量(LBA 中的最後兩個))與 『$partitions』 環境變數中定義的數據進行比較。
運行此命令后,如果在存儲的非易失性介質 GPT 上未發現錯誤,則返回代碼將設置為 0。
以下行可用於評估 GPT 驗證是否成功:
U-BOOT> gpt verify mmc 0 $partitions
U-BOOT> if test $? = 0; then echo "GPT OK"; else echo "GPT ERR"; fi
從 U-Boot 重新命名 GPT 分區:
GPT 分區名稱是一種機制,用戶空間和 U-Boot 可以通過該機制就軟體更新和啟動失敗進行通信。’gpt guid’、’gpt read’、’gpt rename’ 和 ‘gpt swap’ 命令通過生成和修改分區佈局字元串,有助於從引導腳本中以程式設計方式重命名分區。下面是一個使用 ‘swap’ 來交換 ‘primary’ 和 ‘backup’ 分區名稱的例子:
U-BOOT> gpt swap mmc 0 primary backup
之後,所有以前命名為 ‘primary’ 的分區將被命名為 ‘backup’,反之亦然。或者,可以重命名單個分區。在此範例中,mmc0 的第一個分區將重新命名為 ‘primary’:
U-BOOT> gpt rename mmc 0 1 primary
GPT 功能可以通過創建磁碟映射來使用 ‘sandbox’ 板進行測試,如 doc/arch/index.rst 中的"塊設備模擬"中所述:
=>host bind 0 ./disk.raw
=> gpt read host 0
[ . . . ]
=> gpt swap host 0 name othername
[ . . . ]
從 U-Boot 修改 GPT 分區佈局:
整個 GPT 分區佈局可以匯出到環境變數,然後修改 enmasse。用戶可以更改分區編號、偏移量、名稱和大小。生成的變數可用於重新格式化設備。下面是將 GPT 分區讀取到變數中,然後修改它們的範例:
U-BOOT> gpt read mmc 0 current_partitions
U-BOOT> env edit current_partitions
edit: uuid_disk=[...];name=part1,start=0x4000,size=0x4000,uuid=[...];
name=part2,start=0xc000,size=0xc000,uuid=[...];[ . . . ]
U-BOOT> gpt write mmc 0 $current_partitions
U-BOOT> gpt verify mmc 0 $current_partitions
分區類型 (Partition type):
對於創建的分區,使用的分區類型 GUID 為 PARTITION_BASIC_DATA_GUID (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)。
如果 uboot 定義 『CONFIG_PARTITION_TYPE_GUID』,則選項參數 『type』 可以指定其他分區類型 guid:
"uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
name=kernel,size=60MiB,uuid=...,
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4;"
一些字串也可以在已知 GUID 的位置使用:
"system" = PARTITION_SYSTEM_GUID (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
"mbr" = LEGACY_MBR_PARTITION_GUID (024DEE41-33E7-11D3-9D69-0008C781F39F)
"msft" = PARTITION_MSFT_RESERVED_GUID (E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
"data" = PARTITION_BASIC_DATA_GUID (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
"linux" = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID (0FC63DAF-8483-4772-8E79-3D69D8477DE4)
"raid" = PARTITION_LINUX_RAID_GUID (A19D880F-05FC-4D3B-A006-743F0F84911E)
"swap" = PARTITION_LINUX_SWAP_GUID (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
"lvm" = PARTITION_LINUX_LVM_GUID (E6D6D379-F507-44C2-A23C-238F2A3DF928)
"u-boot-env" = PARTITION_U_BOOT_ENVIRONMENT (3DE21764-95BD-54BD-A5C3-4ABE786F38A8)
"uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
name=kernel,size=60MiB,uuid=...,type=linux;"
它們還用於在 「part list」 命令中顯示分區類型。
有用的資訊:
建議使用兩個程式,即:『gdisk』 和 『parted』 來使用 GPT 恢復。兩者都能夠處理 GUID 分區。
請注意 parted 的 -l 開關。
建議使用 uuid 程式生成 UUID 字串。此外,它可以解碼 UUID 字串中傳遞的 (-d 開關)。它可用於生成傳遞給 u-boot 環境變數的分區 UUID。
如果定義了可選 CONFIG_RANDOM_UUID,則對於未設置環境 uuid 的任何分區,將隨機生成 uuid 並將其存儲在相應的環境變數中。
注意:
程式 「uuid」 產生的每個 UUID 字串塊都是大端的,它也存儲在磁碟 GPT 的大端中。
可以通過鍵入 「mmc part」 來列印分區佈局。請注意,每個分區 GUID 的位元組順序與之前生成的 UUID 不同,這是因為 GUID 字串的前三個塊位於 Little Endian 中。
note:
Each string block of UUID generated by program "uuid" is in big endian and it is also stored in big endian in disk GPT.
Partitions layout can be printed by typing "mmc part". Note that each partition GUID has different byte order than UUID generated before, this is because first three blocks of GUID string are in Little Endian.
留言