diff options
-rw-r--r-- | firmware/include/gpt_misc.h | 48 | ||||
-rw-r--r-- | firmware/lib/cgptlib/cgptlib.c | 73 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/cgptlib.h | 12 | ||||
-rw-r--r-- | firmware/lib/gpt_misc.c | 20 |
4 files changed, 136 insertions, 17 deletions
diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h index f48133a0..a94224f3 100644 --- a/firmware/include/gpt_misc.h +++ b/firmware/include/gpt_misc.h @@ -50,6 +50,16 @@ enum { * entry as invalid. */ GPT_UPDATE_ENTRY_BAD = 2, + /* + * Used for fastboot mode. When an image is written to kernel partition, + * its GPT entry is marked with S1,P1,T15. + */ + GPT_UPDATE_ENTRY_RESET = 3, + /* + * Used for fastboot mode. When an image is written to kernel partition, + * its GPT entry is marked with S0,P0,T0. + */ + GPT_UPDATE_ENTRY_INVALID = 4, }; /* If this bit is 1, the GPT is stored in another from the streaming data */ @@ -130,6 +140,13 @@ typedef struct { int GptInit(GptData *gpt); /** + * Return the nth instance of parition entry matching the partition type guid + * from the gpt table. Instance value starts from 0. If the entry is not found, + * it returns NULL. + */ +GptEntry *GptFindNthEntry(GptData *gpt, const Guid *guid, unsigned int n); + +/** * Allocate and read GPT data from the drive. The sector_bytes and * drive_sectors fields should be filled on input. The primary and secondary * header and entries are filled on output. @@ -148,4 +165,35 @@ int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata); */ int IsUnusedEntry(const GptEntry *e); +/** + * Return size(in lba) of a partition represented by given GPT entry. + */ +size_t GptGetEntrySizeLba(const GptEntry *e); + +/** + * Return size(in bytes) of a partition represented by given GPT entry. + */ +size_t GptGetEntrySizeBytes(const GptData *gpt, const GptEntry *e); + +/** + * Updates the kernel entry with the specified index, using the specified type + * of update (GPT_UPDATE_ENTRY_*). + * + * On return the modified field may be set, if the GPT data has been modified + * and should be written to disk. + * + * Returns GPT_SUCCESS if successful, else + * GPT_ERROR_INVALID_UPDATE_TYPE, invalid 'update_type' is given. + */ +int GptUpdateKernelWithEntry(GptData *gpt, GptEntry *e, uint32_t update_type); + +/** + * Updates the kernel entry identified by current_kernel field. If + * current_kernel is not set it returns an error. + * + * Returns GPT_SUCCESS if successful, else + * GPT_ERROR_INVALID_UPDATE_TYPE, invalid 'update_type' is given. + */ +int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type); + #endif /* VBOOT_REFERENCE_CGPT_MISC_H_ */ diff --git a/firmware/lib/cgptlib/cgptlib.c b/firmware/lib/cgptlib/cgptlib.c index 53b69924..05ee29cb 100644 --- a/firmware/lib/cgptlib/cgptlib.c +++ b/firmware/lib/cgptlib/cgptlib.c @@ -112,14 +112,15 @@ int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size) return GPT_SUCCESS; } -int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type) +/* + * Func: GptUpdateKernelWithEntry + * Desc: This function updates the given kernel entry according to the provided + * update_type. + */ +int GptUpdateKernelWithEntry(GptData *gpt, GptEntry *e, uint32_t update_type) { - GptEntry *entries = (GptEntry *)gpt->primary_entries; - GptEntry *e = entries + gpt->current_kernel; int modified = 0; - if (gpt->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND) - return GPT_ERROR_INVALID_UPDATE_TYPE; if (!IsKernelEntry(e)) return GPT_ERROR_INVALID_UPDATE_TYPE; @@ -156,6 +157,28 @@ int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type) } break; } + case GPT_UPDATE_ENTRY_RESET: { + /* + * Used for fastboot mode. If image is written to kernel + * partition, its GPT entry is marked with S1,P1,T15 + */ + modified = 1; + SetEntryTries(e, 15); + SetEntryPriority(e, 1); + SetEntrySuccessful(e, 1); + break; + } + case GPT_UPDATE_ENTRY_INVALID: { + /* + * Used for fastboot mode. If kernel partition is erased, its + * GPT entry is marked with S0,P0,T0 + */ + modified = 1; + SetEntryTries(e, 0); + SetEntryPriority(e, 0); + SetEntrySuccessful(e, 0); + break; + } default: return GPT_ERROR_INVALID_UPDATE_TYPE; } @@ -166,3 +189,43 @@ int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type) return GPT_SUCCESS; } + +/* + * Func: GptUpdateKernelEntry + * Desc: This function updates current_kernel entry with provided + * update_type. If current_kernel is not set, then it returns error. + */ +int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type) +{ + GptEntry *entries = (GptEntry *)gpt->primary_entries; + GptEntry *e = entries + gpt->current_kernel; + + if (gpt->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND) + return GPT_ERROR_INVALID_UPDATE_TYPE; + + return GptUpdateKernelWithEntry(gpt, e, update_type); +} + +/* + * Func: GptFindNthEntry + * Desc: This function returns the nth instance of parition entry matching the + * partition type guid from the gpt table. Instance value starts from 0. If the + * entry is not found it returns NULL. + */ +GptEntry *GptFindNthEntry(GptData *gpt, const Guid *guid, unsigned int n) +{ + GptHeader *header = (GptHeader *)gpt->primary_header; + GptEntry *entries = (GptEntry *)gpt->primary_entries; + GptEntry *e; + int i; + + for (i = 0, e = entries; i < header->number_of_entries; i++, e++) { + if (!Memcmp(&e->type, guid, sizeof(*guid))) { + if (n == 0) + return e; + n--; + } + } + + return NULL; +} diff --git a/firmware/lib/cgptlib/include/cgptlib.h b/firmware/lib/cgptlib/include/cgptlib.h index 968ec635..df85494e 100644 --- a/firmware/lib/cgptlib/include/cgptlib.h +++ b/firmware/lib/cgptlib/include/cgptlib.h @@ -22,16 +22,4 @@ * GPT_ERROR_NO_VALID_KERNEL, no avaliable kernel, enters recovery mode */ int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size); -/** - * Updates the kernel entry with the specified index, using the specified type - * of update (GPT_UPDATE_ENTRY_*). - * - * On return the modified field may be set, if the GPT data has been modified - * and should be written to disk. - * - * Returns GPT_SUCCESS if successful, else - * GPT_ERROR_INVALID_UPDATE_TYPE, invalid 'update_type' is given. - */ -int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type); - #endif /* VBOOT_REFERENCE_CGPTLIB_H_ */ diff --git a/firmware/lib/gpt_misc.c b/firmware/lib/gpt_misc.c index 00c7f9f2..4061bdd9 100644 --- a/firmware/lib/gpt_misc.c +++ b/firmware/lib/gpt_misc.c @@ -201,3 +201,23 @@ int IsUnusedEntry(const GptEntry *e) static Guid zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; return !Memcmp(&zero, (const uint8_t*)(&e->type), sizeof(zero)); } + +/* + * Func: GptGetEntrySize + * Desc: This function returns size(in lba) of a partition represented by + * given GPT entry. + */ +size_t GptGetEntrySizeLba(const GptEntry *e) +{ + return (e->ending_lba - e->starting_lba + 1); +} + +/* + * Func: GptGetEntrySize + * Desc: This function returns size(in bytes) of a partition represented by + * given GPT entry. + */ +size_t GptGetEntrySizeBytes(const GptData *gpt, const GptEntry *e) +{ + return GptGetEntrySizeLba(e) * gpt->sector_bytes; +} |