summaryrefslogtreecommitdiff
path: root/cgpt/cgpt_common.c
diff options
context:
space:
mode:
authorNam T. Nguyen <namnguyen@chromium.org>2014-12-12 09:38:35 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-12 23:15:08 +0000
commit3200401242aec1521e7c4a8b1906366fcabfb1a2 (patch)
tree9e26df71f99eb92a09871ad64d66236d133cbe4d /cgpt/cgpt_common.c
parent32a999d2c0e5bf8a1c0f6141d3db77a1dcc6f5af (diff)
downloadvboot-3200401242aec1521e7c4a8b1906366fcabfb1a2.tar.gz
cgpt: Support non-standard (smaller) entries table
The standard says that entries table must be at least 16384 bytes. On some of our devices, the NOR section is only 8 KiB and used to store both primary and secondary tables. On this device, we can only store 24 entries. Therefore, this CL adds support for non-standard entry table. It adjusts the MIN_NUMBER_OF_ENTRIES to 16, and replaces GPT_ENTRIES_SECTORS with CalculateEntriesSectors. BUG=chromium:441812 BRANCH=none TEST=unittest Change-Id: I6b85b35ce5612c7abb22142f8252bd0d45b676c5 Reviewed-on: https://chromium-review.googlesource.com/234996 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Commit-Queue: Nam Nguyen <namnguyen@chromium.org> Tested-by: Nam Nguyen <namnguyen@chromium.org>
Diffstat (limited to 'cgpt/cgpt_common.c')
-rw-r--r--cgpt/cgpt_common.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c
index b580e33a..ffaa3090 100644
--- a/cgpt/cgpt_common.c
+++ b/cgpt/cgpt_common.c
@@ -176,7 +176,8 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) {
drive->gpt.flags) == 0) {
if (CGPT_OK != Load(drive, &drive->gpt.primary_entries,
primary_header->entries_lba,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) {
+ drive->gpt.sector_bytes,
+ CalculateEntriesSectors(primary_header))) {
Error("Cannot read primary partition entry array\n");
return -1;
}
@@ -189,7 +190,8 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) {
drive->gpt.flags) == 0) {
if (CGPT_OK != Load(drive, &drive->gpt.secondary_entries,
secondary_header->entries_lba,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) {
+ drive->gpt.sector_bytes,
+ CalculateEntriesSectors(secondary_header))) {
Error("Cannot read secondary partition entry array\n");
return -1;
}
@@ -222,7 +224,8 @@ static int GptSave(struct drive *drive) {
if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) {
if (CGPT_OK != Save(drive, drive->gpt.primary_entries,
primary_header->entries_lba,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) {
+ drive->gpt.sector_bytes,
+ CalculateEntriesSectors(primary_header))) {
errors++;
Error("Cannot write primary entries: %s\n", strerror(errno));
}
@@ -231,7 +234,8 @@ static int GptSave(struct drive *drive) {
if (drive->gpt.modified & GPT_MODIFIED_ENTRIES2) {
if (CGPT_OK != Save(drive, drive->gpt.secondary_entries,
secondary_header->entries_lba,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) {
+ drive->gpt.sector_bytes,
+ CalculateEntriesSectors(secondary_header))) {
errors++;
Error("Cannot write secondary entries: %s\n", strerror(errno));
}
@@ -808,12 +812,16 @@ void UpdateCrc(GptData *gpt) {
if (gpt->modified & GPT_MODIFIED_ENTRIES1 &&
memcmp(primary_header, GPT_HEADER_SIGNATURE2,
GPT_HEADER_SIGNATURE_SIZE)) {
+ size_t entries_size = primary_header->size_of_entry *
+ primary_header->number_of_entries;
primary_header->entries_crc32 =
- Crc32(gpt->primary_entries, TOTAL_ENTRIES_SIZE);
+ Crc32(gpt->primary_entries, entries_size);
}
if (gpt->modified & GPT_MODIFIED_ENTRIES2) {
+ size_t entries_size = secondary_header->size_of_entry *
+ secondary_header->number_of_entries;
secondary_header->entries_crc32 =
- Crc32(gpt->secondary_entries, TOTAL_ENTRIES_SIZE);
+ Crc32(gpt->secondary_entries, entries_size);
}
if (gpt->modified & GPT_MODIFIED_HEADER1) {
primary_header->header_crc32 = 0;
@@ -867,17 +875,26 @@ uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries) {
if (!memcmp(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE))
return 0;
+ if (gpt->valid_headers & MASK_PRIMARY) {
+ h = (GptHeader*)gpt->primary_header;
+ } else if (gpt->valid_headers & MASK_SECONDARY) {
+ h = (GptHeader*)gpt->secondary_header;
+ } else {
+ /* We cannot trust any header, don't update entries. */
+ return 0;
+ }
+
+ size_t entries_size = h->number_of_entries * h->size_of_entry;
if (valid_entries == MASK_BOTH) {
- if (memcmp(gpt->primary_entries, gpt->secondary_entries,
- TOTAL_ENTRIES_SIZE)) {
- memcpy(gpt->secondary_entries, gpt->primary_entries, TOTAL_ENTRIES_SIZE);
+ if (memcmp(gpt->primary_entries, gpt->secondary_entries, entries_size)) {
+ memcpy(gpt->secondary_entries, gpt->primary_entries, entries_size);
return GPT_MODIFIED_ENTRIES2;
}
} else if (valid_entries == MASK_PRIMARY) {
- memcpy(gpt->secondary_entries, gpt->primary_entries, TOTAL_ENTRIES_SIZE);
+ memcpy(gpt->secondary_entries, gpt->primary_entries, entries_size);
return GPT_MODIFIED_ENTRIES2;
} else if (valid_entries == MASK_SECONDARY) {
- memcpy(gpt->primary_entries, gpt->secondary_entries, TOTAL_ENTRIES_SIZE);
+ memcpy(gpt->primary_entries, gpt->secondary_entries, entries_size);
return GPT_MODIFIED_ENTRIES1;
}
@@ -922,7 +939,7 @@ uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers) {
secondary_header->my_lba = gpt->gpt_drive_sectors - 1; /* the last sector */
secondary_header->alternate_lba = primary_header->my_lba;
secondary_header->entries_lba = secondary_header->my_lba -
- GPT_ENTRIES_SECTORS;
+ CalculateEntriesSectors(primary_header);
return GPT_MODIFIED_HEADER2;
} else if (valid_headers == MASK_SECONDARY) {
memcpy(primary_header, secondary_header, sizeof(GptHeader));