From a4a8c02ad5988bd4b6fd85f6e09e9e0e79d18feb Mon Sep 17 00:00:00 2001 From: Ben Chan Date: Wed, 31 Jan 2018 11:39:14 -0800 Subject: cgpt: add support for managing GPT platform required partition bit Bit 0 in the GPT partition attributes is defined to indicate whether a partition is required by the platform. This CL adds the support for managing this bit to cgpt. BUG=b:70807006 BRANCH=None TEST=Run unit tests. Change-Id: Iaf87c828438b3df6730de502ae420fcf4c61277b Reviewed-on: https://chromium-review.googlesource.com/902196 Commit-Ready: Ben Chan Tested-by: Ben Chan Reviewed-by: Mike Frysinger --- cgpt/cgpt.h | 3 +++ cgpt/cgpt_add.c | 6 ++++++ cgpt/cgpt_common.c | 14 ++++++++++++++ cgpt/cgpt_show.c | 7 +++++-- cgpt/cmd_add.c | 9 ++++++++- cgpt/cmd_show.c | 4 +++- firmware/include/gpt.h | 2 +- firmware/include/gpt_misc.h | 2 ++ firmware/lib/cgptlib/cgptlib_internal.c | 10 ++++++++++ firmware/lib/cgptlib/include/cgptlib_internal.h | 2 ++ host/include/cgpt_params.h | 2 ++ tests/cgptlib_test.c | 13 +++++++++++++ 12 files changed, 69 insertions(+), 5 deletions(-) diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h index 1216a72c..86f4b851 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 SetRequired(struct drive *drive, int secondary, uint32_t entry_index, + int required); +int GetRequired(struct drive *drive, 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); diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index 5ac50677..c0e93f3d 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -53,6 +53,10 @@ static const char* DumpCgptAddParams(const CgptAddParams *params) { snprintf(tmp, sizeof(tmp), "-P %d ", params->priority); StrnAppend(buf, tmp, sizeof(buf)); } + if (params->set_required) { + snprintf(tmp, sizeof(tmp), "-R %d ", params->required); + StrnAppend(buf, tmp, sizeof(buf)); + } if (params->set_legacy_boot) { snprintf(tmp, sizeof(tmp), "-B %d ", params->legacy_boot); StrnAppend(buf, tmp, sizeof(buf)); @@ -113,6 +117,8 @@ static int SetEntryAttributes(struct drive *drive, SetPriority(drive, PRIMARY, index, params->priority); if (params->set_legacy_boot) SetLegacyBoot(drive, PRIMARY, index, params->legacy_boot); + if (params->set_required) + SetRequired(drive, PRIMARY, index, params->required); } // New partitions must specify type, begin, and size. diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 1a6bd3cb..f6108c1e 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 SetRequired(struct drive *drive, int secondary, uint32_t entry_index, + int required) { + require(required >= 0 && required <= CGPT_ATTRIBUTE_MAX_REQUIRED); + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + SetEntryRequired(entry, required); +} + +int GetRequired(struct drive *drive, int secondary, uint32_t entry_index) { + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + return GetEntryRequired(entry); +} + 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); diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index cd4a6136..60d73ec7 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -136,9 +136,9 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) { priority, tries, successful); } - if (entry->attrs.fields.system) { + if (entry->attrs.fields.required) { clen += snprintf(contents + clen, sizeof(contents) - clen, - "system=%d ", entry->attrs.fields.system); + "required=%d ", entry->attrs.fields.required); require(clen < sizeof(contents)); } @@ -230,6 +230,9 @@ static int GptShow(struct drive *drive, CgptShowParams *params) { case 'P': printf("%d\n", GetPriority(drive, ANY_VALID, index)); break; + case 'R': + printf("%d\n", GetRequired(drive, ANY_VALID, index)); + break; case 'B': printf("%d\n", GetLegacyBoot(drive, ANY_VALID, index)); break; diff --git a/cgpt/cmd_add.c b/cgpt/cmd_add.c index 3c7741b8..f10489ac 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" + " -R NUM set Required flag (0|1)\n" " -B NUM set Legacy Boot flag (0|1)\n" " -A NUM set raw 16-bit attribute value (bits 48-63)\n" "\n" @@ -46,7 +47,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:B:A:D:")) != -1) + while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:S:T:P:R:B:A:D:")) != -1) { switch (c) { @@ -104,6 +105,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 'R': + params.set_required = 1; + params.required = (uint32_t)strtoul(optarg, &e, 0); + errorcnt += check_int_parse(c, e); + errorcnt += check_int_limit(c, params.required, 0, 1); + break; case 'B': params.set_legacy_boot = 1; params.legacy_boot = (uint32_t)strtoul(optarg, &e, 0); diff --git a/cgpt/cmd_show.c b/cgpt/cmd_show.c index b9e64818..6f31b3b5 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" + " -R Required flag\n" " -B Legacy Boot flag\n" " -A raw 16-bit attribute value (bits 48-63)\n" " -d Debug output (including invalid headers)\n" @@ -47,7 +48,7 @@ int cmd_show(int argc, char *argv[]) { char *e = 0; opterr = 0; // quiet, you - while ((c=getopt(argc, argv, ":hnvqi:bstulSTPBAdD:")) != -1) + while ((c=getopt(argc, argv, ":hnvqi:bstulSTPRBAdD:")) != -1) { switch (c) { @@ -76,6 +77,7 @@ int cmd_show(int argc, char *argv[]) { case 'S': case 'T': case 'P': + case 'R': case 'B': case 'A': params.single_item = c; diff --git a/firmware/include/gpt.h b/firmware/include/gpt.h index ae957cf7..45702372 100644 --- a/firmware/include/gpt.h +++ b/firmware/include/gpt.h @@ -108,7 +108,7 @@ typedef struct { uint64_t ending_lba; union { struct { - uint8_t system:1; + uint8_t required:1; uint8_t efi_ignore:1; uint8_t legacy_boot:1; uint8_t reserved1:5; diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h index 58ce83fa..7c4367b8 100644 --- a/firmware/include/gpt_misc.h +++ b/firmware/include/gpt_misc.h @@ -198,10 +198,12 @@ int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type); /* Getters and setters for partition attribute fields. */ +int GetEntryRequired(const GptEntry *e); int GetEntryLegacyBoot(const GptEntry *e); int GetEntrySuccessful(const GptEntry *e); int GetEntryPriority(const GptEntry *e); int GetEntryTries(const GptEntry *e); +void SetEntryRequired(GptEntry *e, int required); void SetEntryLegacyBoot(GptEntry *e, int legacy_boot); void SetEntrySuccessful(GptEntry *e, int successful); void SetEntryPriority(GptEntry *e, int priority); diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 9f37def6..9d7bd0c9 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -379,6 +379,11 @@ void GptRepair(GptData *gpt) gpt->valid_entries = MASK_BOTH; } +int GetEntryRequired(const GptEntry *e) +{ + return e->attrs.fields.required; +} + int GetEntryLegacyBoot(const GptEntry *e) { return e->attrs.fields.legacy_boot; @@ -408,6 +413,11 @@ int GetEntryTries(const GptEntry *e) CGPT_ATTRIBUTE_TRIES_OFFSET; } +void SetEntryRequired(GptEntry *e, int required) +{ + e->attrs.fields.required = required; +} + void SetEntryLegacyBoot(GptEntry *e, int legacy_boot) { e->attrs.fields.legacy_boot = legacy_boot; diff --git a/firmware/lib/cgptlib/include/cgptlib_internal.h b/firmware/lib/cgptlib/include/cgptlib_internal.h index 55e79765..eaa24312 100644 --- a/firmware/lib/cgptlib/include/cgptlib_internal.h +++ b/firmware/lib/cgptlib/include/cgptlib_internal.h @@ -46,6 +46,8 @@ #define CGPT_ATTRIBUTE_PRIORITY_MASK (CGPT_ATTRIBUTE_MAX_PRIORITY << \ CGPT_ATTRIBUTE_PRIORITY_OFFSET) +#define CGPT_ATTRIBUTE_REQUIRED_OFFSET (0) +#define CGPT_ATTRIBUTE_MAX_REQUIRED (1ULL) #define CGPT_ATTRIBUTE_LEGACY_BOOT_OFFSET (2) #define CGPT_ATTRIBUTE_MAX_LEGACY_BOOT (1ULL) diff --git a/host/include/cgpt_params.h b/host/include/cgpt_params.h index 10fc7fed..431443b9 100644 --- a/host/include/cgpt_params.h +++ b/host/include/cgpt_params.h @@ -33,6 +33,7 @@ typedef struct CgptAddParams { int successful; int tries; int priority; + int required; int legacy_boot; uint32_t raw_value; int set_begin; @@ -42,6 +43,7 @@ typedef struct CgptAddParams { int set_successful; int set_tries; int set_priority; + int set_required; int set_legacy_boot; int set_raw; } CgptAddParams; diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c index c0147e16..f37a2725 100644 --- a/tests/cgptlib_test.c +++ b/tests/cgptlib_test.c @@ -1129,6 +1129,15 @@ static int EntryAttributeGetSetTest(void) GptData *gpt = GetEmptyGptData(); GptEntry *e = (GptEntry *)(gpt->primary_entries); + e->attrs.whole = 0x0000000000000000ULL; + SetEntryRequired(e, 1); + EXPECT(0x0000000000000001ULL == e->attrs.whole); + EXPECT(1 == GetEntryRequired(e)); + e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; + SetEntryRequired(e, 0); + EXPECT(0xFFFFFFFFFFFFFFFEULL == e->attrs.whole); + EXPECT(0 == GetEntryRequired(e)); + e->attrs.whole = 0x0000000000000000ULL; SetEntryLegacyBoot(e, 1); EXPECT(0x0000000000000004ULL == e->attrs.whole); @@ -1184,6 +1193,7 @@ static int EntryAttributeGetSetTest(void) override_priority = 10; e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; + EXPECT(1 == GetEntryRequired(e)); EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(10 == GetEntryPriority(e)); @@ -1191,6 +1201,7 @@ static int EntryAttributeGetSetTest(void) override_priority = 0; e->attrs.whole = 0x0123000000000004ULL; + EXPECT(0 == GetEntryRequired(e)); EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(2 == GetEntryTries(e)); @@ -1198,6 +1209,7 @@ static int EntryAttributeGetSetTest(void) override_priority = 10; e->attrs.whole = 0x0123000000000004ULL; + EXPECT(0 == GetEntryRequired(e)); EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(2 == GetEntryTries(e)); @@ -1207,6 +1219,7 @@ static int EntryAttributeGetSetTest(void) /* Invalid priority */ override_priority = 100; e->attrs.whole = 0x0123000000000004ULL; + EXPECT(0 == GetEntryRequired(e)); EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(2 == GetEntryTries(e)); -- cgit v1.2.1