diff options
-rw-r--r-- | cgpt/cgpt.h | 3 | ||||
-rw-r--r-- | cgpt/cgpt_add.c | 6 | ||||
-rw-r--r-- | cgpt/cgpt_common.c | 14 | ||||
-rw-r--r-- | cgpt/cgpt_show.c | 38 | ||||
-rw-r--r-- | cgpt/cmd_add.c | 9 | ||||
-rw-r--r-- | cgpt/cmd_show.c | 4 | ||||
-rw-r--r-- | firmware/include/gpt.h | 7 | ||||
-rw-r--r-- | firmware/include/gpt_misc.h | 2 | ||||
-rw-r--r-- | firmware/lib/cgptlib/cgptlib_internal.c | 10 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/cgptlib_internal.h | 6 | ||||
-rw-r--r-- | host/include/cgpt_params.h | 2 | ||||
-rw-r--r-- | tests/cgptlib_test.c | 20 |
12 files changed, 107 insertions, 14 deletions
diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h index c4edd954..1216a72c 100644 --- a/cgpt/cgpt.h +++ b/cgpt/cgpt.h @@ -149,6 +149,9 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw); uint32_t GetNumberOfEntries(const struct drive *drive); GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index); +void SetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index, + int legacy_boot); +int GetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index); void SetPriority(struct drive *drive, int secondary, uint32_t entry_index, int priority); int GetPriority(struct drive *drive, int secondary, uint32_t entry_index); diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index d6b3cabd..3808255a 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -55,6 +55,10 @@ static const char* DumpCgptAddParams(const CgptAddParams *params) { snprintf(tmp, sizeof(tmp), "-P %d ", params->priority); StrnAppend(buf, tmp, sizeof(buf)); } + if (params->set_legacy_boot) { + snprintf(tmp, sizeof(tmp), "-B %d ", params->legacy_boot); + StrnAppend(buf, tmp, sizeof(buf)); + } if (params->set_raw) { snprintf(tmp, sizeof(tmp), "-A 0x%x ", params->raw_value); StrnAppend(buf, tmp, sizeof(buf)); @@ -109,6 +113,8 @@ static int SetEntryAttributes(struct drive *drive, SetTries(drive, PRIMARY, index, params->tries); if (params->set_priority) SetPriority(drive, PRIMARY, index, params->priority); + if (params->set_legacy_boot) + SetLegacyBoot(drive, PRIMARY, index, params->legacy_boot); } // New partitions must specify type, begin, and size. diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 29906d40..1a6bd3cb 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -763,6 +763,20 @@ GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index) { return (GptEntry*)(&entries[stride * entry_index]); } +void SetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index, + int legacy_boot) { + require(legacy_boot >= 0 && legacy_boot <= CGPT_ATTRIBUTE_MAX_LEGACY_BOOT); + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + SetEntryLegacyBoot(entry, legacy_boot); +} + +int GetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index) { + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + return GetEntryLegacyBoot(entry); +} + void SetPriority(struct drive *drive, int secondary, uint32_t entry_index, int priority) { require(priority >= 0 && priority <= CGPT_ATTRIBUTE_MAX_PRIORITY); diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index 638655bd..81b499c7 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -100,6 +100,7 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) { char contents[256]; // scratch buffer for formatting output uint8_t label[GPT_PARTNAME_LEN]; char type[GUID_STRLEN], unique[GUID_STRLEN]; + int clen; UTF16ToUTF8(entry->name, sizeof(entry->name) / sizeof(entry->name[0]), label, sizeof(label)); @@ -118,6 +119,7 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) { GuidToStr(&entry->unique, unique, GUID_STRLEN); printf(PARTITION_MORE, "UUID: ", unique); + clen = 0; if (!raw) { if (GuidEqual(&guid_chromeos_kernel, &entry->type)) { int tries = (entry->attrs.fields.gpt_att & @@ -129,16 +131,35 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) { int priority = (entry->attrs.fields.gpt_att & CGPT_ATTRIBUTE_PRIORITY_MASK) >> CGPT_ATTRIBUTE_PRIORITY_OFFSET; - require(snprintf(contents, sizeof(contents), - "priority=%d tries=%d successful=%d", - priority, tries, successful) < sizeof(contents)); - printf(PARTITION_MORE, "Attr: ", contents); + clen = snprintf(contents, sizeof(contents), + "priority=%d tries=%d successful=%d ", + priority, tries, successful); + } + + if (entry->attrs.fields.system) { + clen += snprintf(contents + clen, sizeof(contents) - clen, + "system=%d ", entry->attrs.fields.system); + require(clen < sizeof(contents)); + } + + if (entry->attrs.fields.efi_ignore) { + clen += snprintf(contents + clen, sizeof(contents) - clen, + "efi_ignore=%d ", entry->attrs.fields.efi_ignore); + require(clen < sizeof(contents)); + } + + if (entry->attrs.fields.legacy_boot) { + clen += snprintf(contents + clen, sizeof(contents) - clen, + "legacy_boot=%d ", entry->attrs.fields.legacy_boot); + require(clen < sizeof(contents)); } } else { - require(snprintf(contents, sizeof(contents), - "[%x]", entry->attrs.fields.gpt_att) < sizeof(contents)); - printf(PARTITION_MORE, "Attr: ", contents); + clen = snprintf(contents, sizeof(contents), + "[%x]", entry->attrs.fields.gpt_att); } + require(clen < sizeof(contents)); + if (clen) + printf(PARTITION_MORE, "Attr: ", contents); } void EntriesDetails(struct drive *drive, const int secondary, int raw) { @@ -209,6 +230,9 @@ static int GptShow(struct drive *drive, CgptShowParams *params) { case 'P': printf("%d\n", GetPriority(drive, ANY_VALID, index)); break; + case 'B': + printf("%d\n", GetLegacyBoot(drive, ANY_VALID, index)); + break; case 'A': printf("0x%x\n", entry->attrs.fields.gpt_att); break; diff --git a/cgpt/cmd_add.c b/cgpt/cmd_add.c index ca379a22..3c7741b8 100644 --- a/cgpt/cmd_add.c +++ b/cgpt/cmd_add.c @@ -27,6 +27,7 @@ static void Usage(void) " -S NUM set Successful flag (0|1)\n" " -T NUM set Tries flag (0-15)\n" " -P NUM set Priority flag (0-15)\n" + " -B NUM set Legacy Boot flag (0|1)\n" " -A NUM set raw 16-bit attribute value (bits 48-63)\n" "\n" "Use the -i option to modify an existing partition.\n" @@ -45,7 +46,7 @@ int cmd_add(int argc, char *argv[]) { char *e = 0; opterr = 0; // quiet, you - while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:S:T:P:A:D:")) != -1) + while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:S:T:P:B:A:D:")) != -1) { switch (c) { @@ -103,6 +104,12 @@ int cmd_add(int argc, char *argv[]) { errorcnt += check_int_parse(c, e); errorcnt += check_int_limit(c, params.priority, 0, 15); break; + case 'B': + params.set_legacy_boot = 1; + params.legacy_boot = (uint32_t)strtoul(optarg, &e, 0); + errorcnt += check_int_parse(c, e); + errorcnt += check_int_limit(c, params.legacy_boot, 0, 1); + break; case 'A': params.set_raw = 1; params.raw_value = strtoull(optarg, &e, 0); diff --git a/cgpt/cmd_show.c b/cgpt/cmd_show.c index 860d80e7..b9e64818 100644 --- a/cgpt/cmd_show.c +++ b/cgpt/cmd_show.c @@ -32,6 +32,7 @@ static void Usage(void) " -S Successful flag\n" " -T Tries flag\n" " -P Priority flag\n" + " -B Legacy Boot flag\n" " -A raw 16-bit attribute value (bits 48-63)\n" " -d Debug output (including invalid headers)\n" "\n", progname); @@ -46,7 +47,7 @@ int cmd_show(int argc, char *argv[]) { char *e = 0; opterr = 0; // quiet, you - while ((c=getopt(argc, argv, ":hnvqi:bstulSTPAdD:")) != -1) + while ((c=getopt(argc, argv, ":hnvqi:bstulSTPBAdD:")) != -1) { switch (c) { @@ -75,6 +76,7 @@ int cmd_show(int argc, char *argv[]) { case 'S': case 'T': case 'P': + case 'B': case 'A': params.single_item = c; break; diff --git a/firmware/include/gpt.h b/firmware/include/gpt.h index 275b3ae8..ae957cf7 100644 --- a/firmware/include/gpt.h +++ b/firmware/include/gpt.h @@ -108,7 +108,12 @@ typedef struct { uint64_t ending_lba; union { struct { - uint16_t reserved[3]; + uint8_t system:1; + uint8_t efi_ignore:1; + uint8_t legacy_boot:1; + uint8_t reserved1:5; + uint8_t reserved2; + uint16_t reserved[2]; uint16_t gpt_att; } __attribute__((packed)) fields; uint64_t whole; diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h index 0ecbba4b..58ce83fa 100644 --- a/firmware/include/gpt_misc.h +++ b/firmware/include/gpt_misc.h @@ -198,9 +198,11 @@ int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type); /* Getters and setters for partition attribute fields. */ +int GetEntryLegacyBoot(const GptEntry *e); int GetEntrySuccessful(const GptEntry *e); int GetEntryPriority(const GptEntry *e); int GetEntryTries(const GptEntry *e); +void SetEntryLegacyBoot(GptEntry *e, int legacy_boot); void SetEntrySuccessful(GptEntry *e, int successful); void SetEntryPriority(GptEntry *e, int priority); void SetEntryTries(GptEntry *e, int tries); diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 7d402dfb..24b7ba15 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -378,6 +378,11 @@ void GptRepair(GptData *gpt) gpt->valid_entries = MASK_BOTH; } +int GetEntryLegacyBoot(const GptEntry *e) +{ + return e->attrs.fields.legacy_boot; +} + int GetEntrySuccessful(const GptEntry *e) { return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >> @@ -402,6 +407,11 @@ int GetEntryTries(const GptEntry *e) CGPT_ATTRIBUTE_TRIES_OFFSET; } +void SetEntryLegacyBoot(GptEntry *e, int legacy_boot) +{ + e->attrs.fields.legacy_boot = legacy_boot; +} + void SetEntrySuccessful(GptEntry *e, int successful) { if (successful) diff --git a/firmware/lib/cgptlib/include/cgptlib_internal.h b/firmware/lib/cgptlib/include/cgptlib_internal.h index b13c4916..cd616e5c 100644 --- a/firmware/lib/cgptlib/include/cgptlib_internal.h +++ b/firmware/lib/cgptlib/include/cgptlib_internal.h @@ -26,7 +26,8 @@ * 56 -- success * 55-52 -- tries * 51-48 -- priority - * 47-2 -- UEFI: reserved for future use + * 47-3 -- UEFI: reserved for future use + * 2 -- UEFI: Legacy BIOS bootable * 1 -- UEFI: partition is not mapped * 0 -- UEFI: partition is required */ @@ -45,6 +46,9 @@ #define CGPT_ATTRIBUTE_PRIORITY_MASK (CGPT_ATTRIBUTE_MAX_PRIORITY << \ CGPT_ATTRIBUTE_PRIORITY_OFFSET) +#define CGPT_ATTRIBUTE_LEGACY_BOOT_OFFSET (2) +#define CGPT_ATTRIBUTE_MAX_LEGACY_BOOT (1ULL) + /* Defines ChromeOS-specific limitation on GPT */ #define MIN_SIZE_OF_HEADER 92 #define MAX_SIZE_OF_HEADER 512 diff --git a/host/include/cgpt_params.h b/host/include/cgpt_params.h index 3f0a71bd..92f0d3a4 100644 --- a/host/include/cgpt_params.h +++ b/host/include/cgpt_params.h @@ -32,6 +32,7 @@ typedef struct CgptAddParams { int successful; int tries; int priority; + int legacy_boot; uint32_t raw_value; int set_begin; int set_size; @@ -40,6 +41,7 @@ typedef struct CgptAddParams { int set_successful; int set_tries; int set_priority; + int set_legacy_boot; int set_raw; } CgptAddParams; diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c index 1e8df252..f736fd9a 100644 --- a/tests/cgptlib_test.c +++ b/tests/cgptlib_test.c @@ -1131,6 +1131,15 @@ static int EntryAttributeGetSetTest(void) GptEntry *e = (GptEntry *)(gpt->primary_entries); e->attrs.whole = 0x0000000000000000ULL; + SetEntryLegacyBoot(e, 1); + EXPECT(0x0000000000000004ULL == e->attrs.whole); + EXPECT(1 == GetEntryLegacyBoot(e)); + e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; + SetEntryLegacyBoot(e, 0); + EXPECT(0xFFFFFFFFFFFFFFFBULL == e->attrs.whole); + EXPECT(0 == GetEntryLegacyBoot(e)); + + e->attrs.whole = 0x0000000000000000ULL; SetEntrySuccessful(e, 1); EXPECT(0x0100000000000000ULL == e->attrs.whole); EXPECT(1 == GetEntrySuccessful(e)); @@ -1169,24 +1178,28 @@ static int EntryAttributeGetSetTest(void) override_priority = 0; e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; + EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(15 == GetEntryPriority(e)); EXPECT(15 == GetEntryTries(e)); override_priority = 10; e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; + EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(10 == GetEntryPriority(e)); EXPECT(15 == GetEntryTries(e)); override_priority = 0; - e->attrs.whole = 0x0123000000000000ULL; + e->attrs.whole = 0x0123000000000004ULL; + EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(2 == GetEntryTries(e)); EXPECT(3 == GetEntryPriority(e)); override_priority = 10; - e->attrs.whole = 0x0123000000000000ULL; + e->attrs.whole = 0x0123000000000004ULL; + EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(2 == GetEntryTries(e)); EXPECT(10 == GetEntryPriority(e)); @@ -1194,7 +1207,8 @@ static int EntryAttributeGetSetTest(void) /* Invalid priority */ override_priority = 100; - e->attrs.whole = 0x0123000000000000ULL; + e->attrs.whole = 0x0123000000000004ULL; + EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(2 == GetEntryTries(e)); EXPECT(3 == GetEntryPriority(e)); |