summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--firmware/include/gpt.h7
-rw-r--r--firmware/include/gpt_misc.h2
-rw-r--r--firmware/lib/cgptlib/cgptlib_internal.c10
-rw-r--r--firmware/lib/cgptlib/include/cgptlib_internal.h6
-rw-r--r--host/include/cgpt_params.h2
-rw-r--r--tests/cgptlib_test.c20
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));