diff options
author | Albert Chaulk <achaulk@chromium.org> | 2013-06-25 11:30:46 -0700 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-07-03 16:02:34 -0700 |
commit | 289b604f6154b118f3c47aa35b09e99a4e144814 (patch) | |
tree | 2db004eff5ba2fc4d3b80d056df970650b74a92b | |
parent | 7d401c5cd58ec422e239b28c334fc2e94778f565 (diff) | |
download | vboot-289b604f6154b118f3c47aa35b09e99a4e144814.tar.gz |
Port MTD structures to use 64-bit byte offsets instead of sectors.
As per the discussion on issue 221745 we will be using 64-bit byte offsets
for the MTD partition table and converting to/from sectors internally in cgpt.
Existing interfaces do not change, eg sizes are still reported in sectors, only
the on-disk representation is affected.
BRANCH=none
BUG=chromium:221745
TEST=unit tests pass
Change-Id: Id312d42783acfdabe6eb8aea11dcbd298e00a100
Reviewed-on: https://gerrit.chromium.org/gerrit/60919
Commit-Queue: Albert Chaulk <achaulk@chromium.org>
Reviewed-by: Albert Chaulk <achaulk@chromium.org>
Tested-by: Albert Chaulk <achaulk@chromium.org>
-rw-r--r-- | cgpt/cgpt_add.c | 17 | ||||
-rw-r--r-- | cgpt/cgpt_create.c | 4 | ||||
-rw-r--r-- | cgpt/cgpt_find.c | 6 | ||||
-rw-r--r-- | cgpt/cgpt_show.c | 31 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/mtdlib.h | 21 | ||||
-rw-r--r-- | firmware/lib/cgptlib/mtdlib.c | 79 | ||||
-rw-r--r-- | tests/cgptlib_test.c | 36 |
7 files changed, 119 insertions, 75 deletions
diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index 8332f222..e0e24b81 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -103,9 +103,14 @@ static int MtdSetEntryAttributes(struct drive *drive, entry = MtdGetEntry(&drive->mtd, PRIMARY, index); if (params->set_begin) - entry->starting_lba = params->begin; - if (params->set_size) - entry->ending_lba = entry->starting_lba + params->size - 1; + memcpy(&entry->starting_offset, ¶ms->begin, sizeof(params->begin)); + if (params->set_size) { + uint64_t start; + uint64_t end; + MtdGetPartitionSize(entry, &start, NULL, NULL); + end = start + params->size - 1; + memcpy(&entry->ending_offset, &end, sizeof(end)); + } if (params->set_type) MtdSetEntryType(entry, LookupMtdTypeForGuid(¶ms->type_guid)); @@ -273,14 +278,10 @@ int CgptGetPartitionDetails(CgptAddParams *params) { if(drive.is_mtd) { MtdDiskPartition *entry = MtdGetEntry(&drive.mtd, PRIMARY, index); - uint64_t start_lba, end_lba; const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry)); memcpy(¶ms->type_guid, guid, sizeof(params->type_guid)); memset(¶ms->unique_guid, 0, sizeof(params->unique_guid)); - start_lba = entry->starting_lba; - end_lba = entry->ending_lba; - params->begin = start_lba; - params->size = end_lba - start_lba + 1; + MtdGetPartitionSizeInSectors(entry, ¶ms->begin, NULL, ¶ms->size); params->raw_value = entry->flags; } else { // GPT-specific code diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c index 0b116b2b..e7cbadf8 100644 --- a/cgpt/cgpt_create.c +++ b/cgpt/cgpt_create.c @@ -60,8 +60,8 @@ int MtdCreate(struct drive *drive, CgptCreateParams *params) { // Prep basic parameters memcpy(h->signature, MTD_DRIVE_SIGNATURE, sizeof(h->signature)); h->size = sizeof(*h); - h->first_lba = 0; - h->last_lba = drive->mtd.drive_sectors - 1; + h->first_offset = 0; + h->last_offset = (drive->mtd.drive_sectors * drive->mtd.sector_bytes) - 1; h->crc32 = MtdHeaderCrc(h); } diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c index df6c4d39..fc223a02 100644 --- a/cgpt/cgpt_find.c +++ b/cgpt/cgpt_find.c @@ -150,13 +150,13 @@ static int mtd_match_type_to_guid(const MtdDiskPartition *e, const Guid *guid) { static int mtd_match_content(CgptFindParams *params, struct drive *drive, MtdDiskPartition *entry) { - uint64_t part_size; + uint64_t start, part_size; if (!params->matchlen) return 1; // Ensure that the region we want to match against is inside the partition. - part_size = LBA_SIZE * (entry->ending_lba - entry->starting_lba + 1); + MtdGetPartitionSize(entry, &start, NULL, &part_size); if (params->matchoffset + params->matchlen > part_size) { return 0; } @@ -164,7 +164,7 @@ static int mtd_match_content(CgptFindParams *params, struct drive *drive, // Read the partition data. if (!FillBuffer(params, drive->fd, - (LBA_SIZE * entry->starting_lba) + params->matchoffset, + start + params->matchoffset, params->matchlen)) { Error("unable to read partition data\n"); return 0; diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index c3c222eb..78a285c7 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -73,8 +73,10 @@ void MtdHeaderDetails(MtdDiskLayout *header, const char *indent, int raw) { printf("%sSize: %d\n", indent, header->size); printf("%sCRC: 0x%08x %s\n", indent, header->crc32, (MtdHeaderCrc(header) != header->crc32) ? "(INVALID)" : ""); - printf("%sFirst LBA: %u\n", indent, header->first_lba); - printf("%sLast LBA: %u\n", indent, header->last_lba); + printf("%sFirst LBA: %llu\n", indent, + (unsigned long long)header->first_offset); + printf("%sLast LBA: %llu\n", indent, + (unsigned long long)header->last_offset); } static void HeaderDetails(GptHeader *header, GptEntry *entries, @@ -110,20 +112,19 @@ static void HeaderDetails(GptHeader *header, GptEntry *entries, void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw) { const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry)); char buf[256]; // scratch buffer for formatting output + uint64_t start, size; if (guid) { ResolveType(guid, buf); } else { snprintf(buf, sizeof(buf), "MTD partition type %d", MtdGetEntryType(entry)); } + MtdGetPartitionSizeInSectors(entry, &start, NULL, &size); + if (!raw) { - printf(PARTITION_FMT, (int)entry->starting_lba, - (int)(entry->ending_lba - entry->starting_lba + 1), - index+1, buf); + printf(PARTITION_FMT, (int)start, (int)size, index+1, buf); } else { - printf(PARTITION_FMT, (int)entry->starting_lba, - (int)(entry->ending_lba - entry->starting_lba + 1), - index+1, buf); + printf(PARTITION_FMT, (int)start, (int)size, index+1, buf); } } @@ -257,14 +258,17 @@ int MtdShow(struct drive *drive, CgptShowParams *params) { MtdDiskPartition *entry = MtdGetEntry(&drive->mtd, ANY_VALID, index); char buf[256]; // scratch buffer for string conversion const Guid *guid; + uint64_t start, size; + + MtdGetPartitionSizeInSectors(entry, &start, NULL, &size); if (params->single_item) { switch(params->single_item) { case 'b': - printf("%u\n", entry->starting_lba); + printf("%u\n", (int)start); break; case 's': - printf("%u\n", entry->ending_lba - entry->starting_lba + 1); + printf("%u\n", (int)size); break; case 't': guid = LookupGuidForMtdType(MtdGetEntryType(entry)); @@ -295,6 +299,9 @@ int MtdShow(struct drive *drive, CgptShowParams *params) { for (i = 0; i < GetNumberOfEntries(drive); ++i) { MtdDiskPartition *entry = MtdGetEntry(&drive->mtd, ANY_VALID, i); const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry)); + uint64_t start, size; + + MtdGetPartitionSizeInSectors(entry, &start, NULL, &size); if (IsUnused(drive, ANY_VALID, i)) continue; @@ -305,9 +312,7 @@ int MtdShow(struct drive *drive, CgptShowParams *params) { snprintf(type, sizeof(type), "MTD partition type %d", MtdGetEntryType(entry)); } - printf(PARTITION_FMT, (int)entry->starting_lba, - (int)(entry->ending_lba - entry->starting_lba + 1), - i+1, type); + printf(PARTITION_FMT, (int)start, (int)size, i+1, type); } } else { // show all partitions if (params->debug || params->verbose) { diff --git a/firmware/lib/cgptlib/include/mtdlib.h b/firmware/lib/cgptlib/include/mtdlib.h index 59fb8b32..0c87822a 100644 --- a/firmware/lib/cgptlib/include/mtdlib.h +++ b/firmware/lib/cgptlib/include/mtdlib.h @@ -63,10 +63,9 @@ typedef struct { - uint32_t starting_lba; - uint32_t ending_lba; + uint64_t starting_offset; + uint64_t ending_offset; uint32_t flags; - uint32_t reserved; } __attribute__((packed)) MtdDiskPartition; typedef struct { @@ -77,15 +76,15 @@ typedef struct { */ uint32_t crc32; uint32_t size; - uint32_t first_lba; - uint32_t last_lba; + uint64_t first_offset; + uint64_t last_offset; MtdDiskPartition partitions[MTD_MAX_PARTITIONS]; } __attribute__((packed)) MtdDiskLayout; -#define MTD_DRIVE_V1_SIZE (24 + 16*16) +#define MTD_DRIVE_V1_SIZE (32 + 16*20) -#define MTDENTRY_EXPECTED_SIZE (16) -#define MTDLAYOUT_EXPECTED_SIZE (24 + 16 * MTDENTRY_EXPECTED_SIZE) +#define MTDENTRY_EXPECTED_SIZE (20) +#define MTDLAYOUT_EXPECTED_SIZE (32 + 16 * MTDENTRY_EXPECTED_SIZE) typedef struct { @@ -135,6 +134,12 @@ void MtdSetEntryPriority(MtdDiskPartition *e, int priority); void MtdSetEntryTries(MtdDiskPartition *e, int tries); void MtdSetEntryType(MtdDiskPartition *e, int type); +void MtdGetPartitionSize(const MtdDiskPartition *e, + uint64_t *start, uint64_t *end, uint64_t *size); + +void MtdGetPartitionSizeInSectors(const MtdDiskPartition *e, uint64_t *start, + uint64_t *end, uint64_t *size); + void MtdModified(MtdData *mtd); int MtdGptInit(MtdData *mtd); int MtdIsPartitionValid(const MtdDiskPartition *part); diff --git a/firmware/lib/cgptlib/mtdlib.c b/firmware/lib/cgptlib/mtdlib.c index db9f4b5d..18aa7c5a 100644 --- a/firmware/lib/cgptlib/mtdlib.c +++ b/firmware/lib/cgptlib/mtdlib.c @@ -11,6 +11,8 @@ #include "utility.h" #include "vboot_api.h" +const int kSectorShift = 9; /* 512 bytes / sector. */ + int MtdInit(MtdData *mtd) { int ret; @@ -85,8 +87,8 @@ static void SetBitfield(MtdDiskPartition *e, e->flags = (e->flags & ~mask) | ((v << offset) & mask); } void MtdSetEntrySuccessful(MtdDiskPartition *e, int successful) { - SetBitfield(e, MTD_ATTRIBUTE_SUCCESSFUL_OFFSET, MTD_ATTRIBUTE_SUCCESSFUL_MASK, - successful); + SetBitfield(e, MTD_ATTRIBUTE_SUCCESSFUL_OFFSET, + MTD_ATTRIBUTE_SUCCESSFUL_MASK, successful); } void MtdSetEntryPriority(MtdDiskPartition *e, int priority) { SetBitfield(e, MTD_ATTRIBUTE_PRIORITY_OFFSET, MTD_ATTRIBUTE_PRIORITY_MASK, @@ -116,31 +118,36 @@ int MtdCheckEntries(MtdDiskPartition *entries, MtdDiskLayout *h) { if (i != j) { MtdDiskPartition *entry = entries + i; MtdDiskPartition *e2 = entries + j; + uint64_t start, end; + uint64_t other_start, other_end; if (!MtdIsPartitionValid(entry) || !MtdIsPartitionValid(e2)) continue; - if((entry->starting_lba == 0 && entry->ending_lba == 0) || - (e2->starting_lba == 0 && e2->ending_lba == 0)) { + MtdGetPartitionSize(entry, &start, &end, NULL); + MtdGetPartitionSize(e2, &other_start, &other_end, NULL); + + if((start == 0 && end == 0) || + (other_start == 0 && other_end == 0)) { continue; } - if (entry->ending_lba > h->last_lba) { + if (end > h->last_offset) { return GPT_ERROR_OUT_OF_REGION; } - if (entry->starting_lba < h->first_lba) { + if (start < h->first_offset) { return GPT_ERROR_OUT_OF_REGION; } - if (entry->starting_lba > entry->ending_lba) { + if (start > end) { return GPT_ERROR_OUT_OF_REGION; } - if ((entry->starting_lba >= e2->starting_lba) && - (entry->starting_lba <= e2->ending_lba)) { + if ((start >= other_start) && + (start <= other_end)) { return GPT_ERROR_START_LBA_OVERLAP; } - if ((entry->ending_lba >= e2->starting_lba) && - (entry->ending_lba <= e2->ending_lba)) { + if ((end >= other_start) && + (end <= other_end)) { return GPT_ERROR_END_LBA_OVERLAP; } } @@ -162,8 +169,8 @@ int MtdSanityCheck(MtdData *disk) { return GPT_ERROR_INVALID_HEADERS; } - if (disk->primary.first_lba > disk->primary.last_lba || - disk->primary.last_lba > disk->drive_sectors) { + if (disk->primary.first_offset > disk->primary.last_offset || + disk->primary.last_offset > disk->drive_sectors * disk->sector_bytes) { return GPT_ERROR_INVALID_SECTOR_NUMBER; } @@ -196,6 +203,31 @@ uint32_t MtdHeaderCrc(MtdDiskLayout *h) { return crc32; } +void MtdGetPartitionSize(const MtdDiskPartition *e, + uint64_t *start, uint64_t *end, uint64_t *size) { + uint64_t start_tmp, end_tmp; + if (!start) + start = &start_tmp; + if (!end) + end = &end_tmp; + + Memcpy(start, &e->starting_offset, sizeof(e->starting_offset)); + Memcpy(end, &e->ending_offset, sizeof(e->ending_offset)); + if (size) { + *size = *end - *start + 1; + } +} + +void MtdGetPartitionSizeInSectors(const MtdDiskPartition *e, uint64_t *start, + uint64_t *end, uint64_t *size) { + MtdGetPartitionSize(e, start, end, size); + if (start) + *start >>= kSectorShift; + if (end) + *end >>= kSectorShift; + if (size) + *size >>= kSectorShift; +} int MtdNextKernelEntry(MtdData *mtd, uint64_t *start_sector, uint64_t *size) @@ -218,18 +250,17 @@ int MtdNextKernelEntry(MtdData *mtd, uint64_t *start_sector, uint64_t *size) e = entries + i; if (!MtdIsKernelEntry(e)) continue; - VBDEBUG(("GptNextKernelEntry looking at same prio " + VBDEBUG(("MtdNextKernelEntry looking at same prio " "partition %d\n", i+1)); - VBDEBUG(("GptNextKernelEntry s%d t%d p%d\n", + VBDEBUG(("MtdNextKernelEntry s%d t%d p%d\n", MtdGetEntrySuccessful(e), MtdGetEntryTries(e), MtdGetEntryPriority(e))); if (!(MtdGetEntrySuccessful(e) || MtdGetEntryTries(e))) continue; if (MtdGetEntryPriority(e) == mtd->current_priority) { + MtdGetPartitionSizeInSectors(e, start_sector, NULL, size); mtd->current_kernel = i; - *start_sector = e->starting_lba; - *size = e->ending_lba - e->starting_lba + 1; - VBDEBUG(("GptNextKernelEntry likes it\n")); + VBDEBUG(("MtdNextKernelEntry likes it\n")); return GPT_SUCCESS; } } @@ -243,9 +274,9 @@ int MtdNextKernelEntry(MtdData *mtd, uint64_t *start_sector, uint64_t *size) int current_prio = MtdGetEntryPriority(e); if (!MtdIsKernelEntry(e)) continue; - VBDEBUG(("GptNextKernelEntry looking at new prio " + VBDEBUG(("MtdNextKernelEntry looking at new prio " "partition %d\n", i+1)); - VBDEBUG(("GptNextKernelEntry s%d t%d p%d\n", + VBDEBUG(("MtdNextKernelEntry s%d t%d p%d\n", MtdGetEntrySuccessful(e), MtdGetEntryTries(e), MtdGetEntryPriority(e))); if (!(MtdGetEntrySuccessful(e) || MtdGetEntryTries(e))) @@ -269,14 +300,14 @@ int MtdNextKernelEntry(MtdData *mtd, uint64_t *start_sector, uint64_t *size) mtd->current_priority = new_prio; if (CGPT_KERNEL_ENTRY_NOT_FOUND == new_kernel) { - VBDEBUG(("GptNextKernelEntry no more kernels\n")); + VBDEBUG(("MtdNextKernelEntry no more kernels\n")); return GPT_ERROR_NO_VALID_KERNEL; } - VBDEBUG(("GptNextKernelEntry likes partition %d\n", new_kernel + 1)); + VBDEBUG(("MtdNextKernelEntry likes partition %d\n", new_kernel + 1)); e = entries + new_kernel; - *start_sector = e->starting_lba; - *size = e->ending_lba - e->starting_lba + 1; + MtdGetPartitionSizeInSectors(e, start_sector, NULL, size); + return GPT_SUCCESS; } diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c index ba9cd05b..1ee551d0 100644 --- a/tests/cgptlib_test.c +++ b/tests/cgptlib_test.c @@ -225,8 +225,8 @@ static void BuildTestMtdData(MtdData *mtd) { Memcpy(mtd->primary.signature, MTD_DRIVE_SIGNATURE, sizeof(mtd->primary.signature)); - mtd->primary.first_lba = 32; - mtd->primary.last_lba = DEFAULT_DRIVE_SECTORS - 1; + mtd->primary.first_offset = 32 * DEFAULT_SECTOR_SIZE; + mtd->primary.last_offset = DEFAULT_DRIVE_SECTORS * DEFAULT_SECTOR_SIZE - 1; mtd->primary.size = MTD_DRIVE_V1_SIZE; /* These values are not used directly by the library, but they are checked */ @@ -236,20 +236,20 @@ static void BuildTestMtdData(MtdData *mtd) { mtd->fts_block_size = 1; partitions = &mtd->primary.partitions[0]; - partitions[0].starting_lba = 34; - partitions[0].ending_lba = 133; + partitions[0].starting_offset = 34 * DEFAULT_SECTOR_SIZE; + partitions[0].ending_offset = 134 * DEFAULT_SECTOR_SIZE - 1; partitions[0].flags = MTD_PARTITION_TYPE_CHROMEOS_KERNEL << MTD_ATTRIBUTE_TYPE_OFFSET; - partitions[1].starting_lba = 134; - partitions[1].ending_lba = 232; + partitions[1].starting_offset = 134 * DEFAULT_SECTOR_SIZE; + partitions[1].ending_offset = 233 * DEFAULT_SECTOR_SIZE - 1; partitions[1].flags = MTD_PARTITION_TYPE_CHROMEOS_ROOTFS << MTD_ATTRIBUTE_TYPE_OFFSET; - partitions[2].starting_lba = 234; - partitions[2].ending_lba = 331; + partitions[2].starting_offset = 234 * DEFAULT_SECTOR_SIZE; + partitions[2].ending_offset = 332 * DEFAULT_SECTOR_SIZE - 1; partitions[2].flags = MTD_PARTITION_TYPE_CHROMEOS_KERNEL << MTD_ATTRIBUTE_TYPE_OFFSET; - partitions[3].starting_lba = 334; - partitions[3].ending_lba = 430; + partitions[3].starting_offset = 334 * DEFAULT_SECTOR_SIZE; + partitions[3].ending_offset = 431 * DEFAULT_SECTOR_SIZE - 1; partitions[3].flags = MTD_PARTITION_TYPE_CHROMEOS_ROOTFS << MTD_ATTRIBUTE_TYPE_OFFSET; @@ -809,8 +809,8 @@ static int ValidEntryTest(void) EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); BuildTestMtdData(mtd); - if (mh->first_lba > 0) { - me[0].starting_lba = mh->first_lba - 1; + if (mh->first_offset > 0) { + me[0].starting_offset = mh->first_offset - 1; mh->crc32 = MtdHeaderCrc(mh); EXPECT(GPT_ERROR_OUT_OF_REGION == MtdCheckEntries(me, mh)); } @@ -822,7 +822,7 @@ static int ValidEntryTest(void) EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); BuildTestMtdData(mtd); - me[0].ending_lba = mh->last_lba + 1; + me[0].ending_offset = mh->last_offset + 1; mh->crc32 = MtdHeaderCrc(mh); EXPECT(GPT_ERROR_OUT_OF_REGION == MtdCheckEntries(me, mh)); @@ -833,7 +833,7 @@ static int ValidEntryTest(void) EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); BuildTestMtdData(mtd); - me[0].starting_lba = me[0].ending_lba + 1; + me[0].starting_offset = me[0].ending_offset + 1; mh->crc32 = MtdHeaderCrc(mh); EXPECT(GPT_ERROR_OUT_OF_REGION == MtdCheckEntries(me, mh)); @@ -846,7 +846,7 @@ static int ValidEntryTest(void) BuildTestMtdData(mtd); me[0].flags = 0; - me[0].starting_lba = me[0].ending_lba + 1; + me[0].starting_offset = me[0].ending_offset + 1; mh->crc32 = MtdHeaderCrc(mh); EXPECT(GPT_SUCCESS == MtdCheckEntries(me, mh)); @@ -928,8 +928,10 @@ static int OverlappedPartitionTest(void) { SetGuid(&e[j].unique, j); e[j].starting_lba = cases[i].entries[j].starting_lba; e[j].ending_lba = cases[i].entries[j].ending_lba; - me[j].starting_lba = cases[i].entries[j].starting_lba; - me[j].ending_lba = cases[i].entries[j].ending_lba; + me[j].starting_offset = cases[i].entries[j].starting_lba * + DEFAULT_SECTOR_SIZE; + me[j].ending_offset = cases[i].entries[j].ending_lba * + DEFAULT_SECTOR_SIZE; } RefreshCrc32(gpt); |