int probe_sector_size(int fd, uint32_t *ret) {
- struct gpt_header {
- char signature[8];
- le32_t revision;
- le32_t header_size;
- le32_t crc32;
- le32_t reserved;
- le64_t my_lba;
- le64_t alternate_lba;
- le64_t first_usable_lba;
- le64_t last_usable_lba;
- sd_id128_t disk_guid;
- le64_t partition_entry_lba;
- le32_t number_of_partition_entries;
- le32_t size_of_partition_entry;
- le32_t partition_entry_array_crc32;
- } _packed_;
-
/* Disk images might be for 512B or for 4096 sector sizes, let's try to auto-detect that by searching
* for the GPT headers at the relevant byte offsets */
- assert_cc(sizeof(struct gpt_header) == 92);
+ assert_cc(sizeof(GptHeader) == 92);
/* We expect a sector size in the range 512…4096. The GPT header is located in the second
* sector. Hence it could be at byte 512 at the earliest, and at byte 4096 at the latest. And we must
/* Let's see if we find the GPT partition header with various expected sector sizes */
for (uint32_t sz = 512; sz <= 4096; sz <<= 1) {
- struct gpt_header *p;
+ const GptHeader *p;
assert(sizeof(sectors) >= sz * 2);
- p = (struct gpt_header*) (sectors + sz);
-
- if (memcmp(p->signature, (const char[8]) { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' }, 8) != 0)
- continue;
-
- if (le32toh(p->revision) != UINT32_C(0x00010000)) /* the only known revision of the spec: 1.0 */
- continue;
-
- if (le32toh(p->header_size) < sizeof(struct gpt_header))
- continue;
-
- if (le32toh(p->header_size) > 4096) /* larger than a sector? something is off… */
- continue;
+ p = (const GptHeader*) (sectors + sz);
- if (le64toh(p->my_lba) != 1) /* this sector must claim to be at sector offset 1 */
+ if (!gpt_header_has_signature(p))
continue;
if (found != 0)
PARTITION_XBOOTLDR,
PARTITION_SWAP);
}
+
+bool gpt_header_has_signature(const GptHeader *p) {
+ assert(p);
+
+ if (memcmp(p->signature, (const char[8]) { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' }, 8) != 0)
+ return false;
+
+ if (le32toh(p->revision) != UINT32_C(0x00010000)) /* the only known revision of the spec: 1.0 */
+ return false;
+
+ if (le32toh(p->header_size) < sizeof(GptHeader))
+ return false;
+
+ if (le32toh(p->header_size) > 4096) /* larger than a sector? something is off… */
+ return false;
+
+ if (le64toh(p->my_lba) != 1) /* this sector must claim to be at sector offset 1 */
+ return false;
+
+ return true;
+}
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <uchar.h>
+
#include "sd-gpt.h"
#include "sd-id128.h"
#include "architecture.h"
#include "id128-util.h"
+#include "sparse-endian.h"
/* maximum length of gpt label */
#define GPT_LABEL_MAX 36
bool gpt_partition_type_knows_read_only(GptPartitionType type);
bool gpt_partition_type_knows_growfs(GptPartitionType type);
bool gpt_partition_type_knows_no_auto(GptPartitionType type);
+
+typedef struct {
+ uint8_t partition_type_guid[16];
+ uint8_t unique_partition_guid[16];
+ le64_t starting_lba;
+ le64_t ending_lba;
+ le64_t attributes;
+ char16_t partition_name[36];
+} _packed_ GptPartitionEntry;
+
+typedef struct {
+ char signature[8];
+ le32_t revision;
+ le32_t header_size;
+ le32_t crc32;
+ le32_t reserved;
+ le64_t my_lba;
+ le64_t alternate_lba;
+ le64_t first_usable_lba;
+ le64_t last_usable_lba;
+ uint8_t disk_guid[16];
+ le64_t partition_entry_lba;
+ le32_t number_of_partition_entries;
+ le32_t size_of_partition_entry;
+ le32_t partition_entry_array_crc32;
+} _packed_ GptHeader;
+
+bool gpt_header_has_signature(const GptHeader *p);