summaryrefslogtreecommitdiff
path: root/cgpt
diff options
context:
space:
mode:
authorMike Frysinger <vapier@chromium.org>2016-09-07 16:45:48 -0400
committerchrome-bot <chrome-bot@chromium.org>2016-09-08 15:36:23 -0700
commit6c18af501798c9b597839a3628c8374a2f8d7483 (patch)
treee846d7253980759aed453ba8649653cc7a4b60b9 /cgpt
parent6764405c93664efcf9742bf4973225099f65b6ec (diff)
downloadvboot-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.h3
-rw-r--r--cgpt/cgpt_add.c6
-rw-r--r--cgpt/cgpt_common.c14
-rw-r--r--cgpt/cgpt_show.c38
-rw-r--r--cgpt/cmd_add.c9
-rw-r--r--cgpt/cmd_show.c4
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;