diff options
author | Mike Frysinger <vapier@chromium.org> | 2016-09-07 16:45:48 -0400 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-09-08 15:36:23 -0700 |
commit | 6c18af501798c9b597839a3628c8374a2f8d7483 (patch) | |
tree | e846d7253980759aed453ba8649653cc7a4b60b9 /cgpt | |
parent | 6764405c93664efcf9742bf4973225099f65b6ec (diff) | |
download | vboot-6c18af501798c9b597839a3628c8374a2f8d7483.tar.gz |
cgpt: add support for managing the legacy boot gpt bitstabilize-kevin-8785.94.B
Bit 2 in the GPT partition attributes has been allocated as the legacy
bios boot (equivalent to the "active" or "boot" flag in MBR). If we
try to boot images on newer x86 systems, syslinux dies because it can't
find any GPT partition marked bootable.
Update the various parts of cgpt add & show to manage this bit. Now we
can run:
cgpt add -i 12 -B 1 chromiumos_image.bin
And the EFI partition will be marked bootable.
BUG=chromium:644845
TEST=vboot_reference unittests pass
TEST=booted an amd64-generic disk image via USB on a generic laptop
BRANCH=None
Change-Id: I78e17b8df5b0c61e9e2d8a3c703e6d5ad230fe92
Reviewed-on: https://chromium-review.googlesource.com/382411
Commit-Ready: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'cgpt')
-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 |
6 files changed, 65 insertions, 9 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; |