Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: src/platform/vboot_reference/cgptlib/cgptlib.c

Issue 2231002: complete 'cgpt show' and refactor for incoming commands. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/platform/vboot_reference/cgptlib/cgptlib.c
diff --git a/src/platform/vboot_reference/cgptlib/cgptlib.c b/src/platform/vboot_reference/cgptlib/cgptlib.c
index 9a0f784bfee61688b12e3d2a693b90df25cb4646..a871b1aa09fa12f4215c9d8f5fb9bead67b210fb 100644
--- a/src/platform/vboot_reference/cgptlib/cgptlib.c
+++ b/src/platform/vboot_reference/cgptlib/cgptlib.c
@@ -243,7 +243,6 @@ uint32_t CheckValidUsableLbas(GptData *gpt) {
/* Checks header CRC */
uint32_t CheckHeaderCrc(GptData *gpt) {
uint32_t crc32, original_crc32;
- uint32_t valid_headers = MASK_BOTH;
GptHeader *headers[] = {
(GptHeader*)gpt->primary_header,
(GptHeader*)gpt->secondary_header,
@@ -251,20 +250,20 @@ uint32_t CheckHeaderCrc(GptData *gpt) {
int i;
for (i = PRIMARY; i <= SECONDARY; ++i) {
+ if (!(gpt->valid_headers & (1 << i))) continue;
original_crc32 = headers[i]->header_crc32;
headers[i]->header_crc32 = 0;
crc32 = Crc32((const uint8_t *)headers[i], headers[i]->size);
headers[i]->header_crc32 = original_crc32;
if (crc32 != original_crc32)
- INVALIDATE_HEADER(valid_headers, i);
+ INVALIDATE_HEADER(gpt->valid_headers, i);
}
- return valid_headers;
+ return gpt->valid_headers;
}
/* Checks entries CRC */
uint32_t CheckEntriesCrc(GptData *gpt) {
uint32_t crc32;
- uint32_t valid_entries = MASK_BOTH;
GptHeader *headers[] = {
(GptHeader*)gpt->primary_header,
(GptHeader*)gpt->secondary_header,
@@ -273,14 +272,20 @@ uint32_t CheckEntriesCrc(GptData *gpt) {
(GptEntry*)gpt->primary_entries,
(GptEntry*)gpt->secondary_entries,
};
+ uint32_t entries_crc32;
int i;
+ if (gpt->valid_headers & MASK_PRIMARY)
+ entries_crc32 = headers[PRIMARY]->entries_crc32;
+ else
+ entries_crc32 = headers[SECONDARY]->entries_crc32;
+
for (i = PRIMARY; i <= SECONDARY; ++i) {
crc32 = Crc32((const uint8_t *)entries[i], TOTAL_ENTRIES_SIZE);
- if (crc32 != headers[i]->entries_crc32)
- INVALIDATE_HEADER(valid_entries, i);
+ if (crc32 != entries_crc32)
+ INVALIDATE_ENTRIES(gpt->valid_entries, i);
}
- return valid_entries;
+ return gpt->valid_entries;
}
/* Returns non-zero if the given GUID is non-zero. */
@@ -305,20 +310,31 @@ uint32_t CheckValidEntries(GptData *gpt) {
(GptEntry*)gpt->primary_entries,
(GptEntry*)gpt->secondary_entries,
};
+ uint32_t number_of_entries, size_of_entry;
+ uint64_t first_usable_lba, last_usable_lba;
int copy, entry_index;
GptEntry *entry;
+ if (gpt->valid_headers & MASK_PRIMARY)
+ copy = PRIMARY;
+ else
+ copy = SECONDARY;
+ number_of_entries = headers[copy]->number_of_entries;
+ size_of_entry = headers[copy]->size_of_entry;
+ first_usable_lba = headers[copy]->first_usable_lba;
+ last_usable_lba = headers[copy]->last_usable_lba;
+
for (copy = PRIMARY; copy <= SECONDARY; ++copy) {
for (entry_index = 0;
- entry_index < headers[copy]->number_of_entries;
+ entry_index < number_of_entries;
++entry_index) {
entry = (GptEntry*)&(((uint8_t*)entries[copy])
- [entry_index * headers[copy]->size_of_entry]);
+ [entry_index * size_of_entry]);
if (NonZeroGuid(&entry->type)) {
- if ((entry->starting_lba < headers[copy]->first_usable_lba) ||
- (entry->ending_lba > headers[copy]->last_usable_lba) ||
+ if ((entry->starting_lba < first_usable_lba) ||
+ (entry->ending_lba > last_usable_lba) ||
(entry->ending_lba < entry->starting_lba))
- INVALIDATE_HEADER(valid_entries, copy);
+ INVALIDATE_ENTRIES(valid_entries, copy);
}
}
}
@@ -370,9 +386,15 @@ uint32_t CheckOverlappedPartition(GptData *gpt) {
(GptEntry*)gpt->secondary_entries,
};
int i;
+ uint32_t number_of_entries;
+
+ if (gpt->valid_headers & MASK_PRIMARY)
+ number_of_entries = headers[PRIMARY]->number_of_entries;
+ else
+ number_of_entries = headers[SECONDARY]->number_of_entries;
for (i = PRIMARY; i <= SECONDARY; ++i) {
- if (OverlappedEntries(entries[i], headers[i]->number_of_entries))
+ if (OverlappedEntries(entries[i], number_of_entries))
INVALIDATE_ENTRIES(valid_entries, i);
}
return valid_entries;
@@ -384,7 +406,9 @@ uint32_t CheckOverlappedPartition(GptData *gpt) {
* and marks secondary as modified.
* If only one is valid, overwrites invalid one.
* If all are invalid, does nothing.
- * This function returns bit masks for GptData.modified field. */
+ * This function returns bit masks for GptData.modified field.
+ * Note that CRC is NOT re-computed in this function.
+ */
uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries) {
if (valid_entries == MASK_BOTH) {
if (Memcmp(gpt->primary_entries, gpt->secondary_entries,
@@ -445,7 +469,7 @@ void CopySynonymousParts(GptHeader* target, const GptHeader* source) {
* If primary is invalid (CRC32 is wrong), then we repair it from secondary.
* If secondary is invalid (CRC32 is wrong), then we repair it from primary.
* This function returns the bitmasks for modified header.
- * Note that CRC value is not re-computed in this function. UpdateCrc() will
+ * Note that CRC value is NOT re-computed in this function. UpdateCrc() will
* do it later.
*/
uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers) {
@@ -502,48 +526,71 @@ void UpdateCrc(GptData *gpt) {
}
}
-/* Does every sanity check, and returns if any header/entries needs to be
- * written back. */
-int GptInit(GptData *gpt) {
- uint32_t valid_headers = MASK_BOTH;
- uint32_t valid_entries = MASK_BOTH;
+/* This function only checks GptData.
+ * valid_headers and valid_entries are used to store the checking results.
+ *
+ * Returns:
+ * GPT_ERROR_INVALID_HEADERS -- both headers are invalid.
+ * GPT_ERROR_INVALID_ENTRIES -- both entries are invalid.
+ * GPT_SUCCESS -- everything looks fine.
+ */
+int GptSanityCheck(GptData *gpt) {
int retval;
+ assert(gpt);
+
retval = CheckParameters(gpt);
if (retval != GPT_SUCCESS)
return retval;
/* Initialize values */
- gpt->modified = 0;
+ gpt->valid_headers = MASK_BOTH;
+ gpt->valid_entries = MASK_BOTH;
/* Start checking if header parameters are valid. */
- valid_headers &= CheckHeaderSignature(gpt);
- valid_headers &= CheckRevision(gpt);
- valid_headers &= CheckSize(gpt);
- valid_headers &= CheckReservedFields(gpt);
- valid_headers &= CheckMyLba(gpt);
- valid_headers &= CheckSizeOfPartitionEntry(gpt);
- valid_headers &= CheckNumberOfEntries(gpt);
- valid_headers &= CheckEntriesLba(gpt);
- valid_headers &= CheckValidUsableLbas(gpt);
-
- /* Checks if headers are valid. */
- valid_headers &= CheckHeaderCrc(gpt);
- gpt->modified |= RepairHeader(gpt, valid_headers);
+ CheckHeaderSignature(gpt);
+ CheckRevision(gpt);
+ CheckSize(gpt);
+ CheckReservedFields(gpt);
+ CheckMyLba(gpt);
+ CheckSizeOfPartitionEntry(gpt);
+ CheckNumberOfEntries(gpt);
+ CheckEntriesLba(gpt);
+ CheckValidUsableLbas(gpt);
+ CheckHeaderCrc(gpt);
+
+ /* Returns error if we don't have any valid header to use. */
+ if (!gpt->valid_headers)
+ return GPT_ERROR_INVALID_HEADERS;
/* Checks if entries are valid. */
- valid_entries &= CheckEntriesCrc(gpt);
- valid_entries &= CheckValidEntries(gpt);
- valid_entries &= CheckOverlappedPartition(gpt);
- gpt->modified |= RepairEntries(gpt, valid_entries);
+ CheckEntriesCrc(gpt);
+ CheckValidEntries(gpt);
+ CheckOverlappedPartition(gpt);
- /* Returns error if we don't have any valid header/entries to use. */
- if (!valid_headers)
- return GPT_ERROR_INVALID_HEADERS;
- if (!valid_entries)
+ /* Returns error if we don't have any valid entries to use. */
+ if (!gpt->valid_entries)
return GPT_ERROR_INVALID_ENTRIES;
+ return GPT_SUCCESS;
+}
+
+void GptRepair(GptData *gpt) {
+ gpt->modified |= RepairHeader(gpt, gpt->valid_headers);
+ gpt->modified |= RepairEntries(gpt, gpt->valid_entries);
UpdateCrc(gpt);
+}
+
+/* Does every sanity check, and returns if any header/entries needs to be
+ * written back. */
+int GptInit(GptData *gpt) {
+ int retval;
+
+ retval = GptSanityCheck(gpt);
+ if (GPT_SUCCESS != retval) return retval;
+
+ gpt->modified = 0;
+ GptRepair(gpt);
gpt->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND;
@@ -555,18 +602,15 @@ int GptInit(GptData *gpt) {
* 'entry_index' is the partition index: [0, number_of_entries).
*/
GptEntry *GetEntry(GptData *gpt, int secondary, int entry_index) {
- GptHeader *header;
uint8_t *entries;
if (secondary == PRIMARY) {
- header = (GptHeader*)gpt->primary_header;
entries = gpt->primary_entries;
} else {
- header = (GptHeader*)gpt->secondary_header;
entries = gpt->secondary_entries;
}
- return (GptEntry*)(&entries[header->size_of_entry * entry_index]);
+ return (GptEntry*)(&entries[GetNumberOfEntries(gpt) * entry_index]);
}
/* The following functions are helpers to access attributes bit more easily.
@@ -640,8 +684,13 @@ int GetSuccessful(GptData *gpt, int secondary, int entry_index) {
}
uint32_t GetNumberOfEntries(const GptData *gpt) {
- GptHeader *header;
- header = (GptHeader*)gpt->primary_header;
+ GptHeader *header = 0;
+ if (gpt->valid_headers & MASK_PRIMARY)
+ header = (GptHeader*)gpt->primary_header;
+ else if (gpt->valid_headers & MASK_SECONDARY)
+ header = (GptHeader*)gpt->secondary_header;
+ else
+ assert(0);
return header->number_of_entries;
}
« no previous file with comments | « src/platform/vboot_reference/cgptlib/cgptlib.h ('k') | src/platform/vboot_reference/cgptlib/cgptlib_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698