diff options
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | cgpt/cgpt.c | 58 | ||||
-rw-r--r-- | cgpt/cgpt.h | 17 | ||||
-rw-r--r-- | cgpt/cgpt_add.c | 108 | ||||
-rw-r--r-- | cgpt/cgpt_boot.c | 9 | ||||
-rw-r--r-- | cgpt/cgpt_common.c | 403 | ||||
-rw-r--r-- | cgpt/cgpt_create.c | 34 | ||||
-rw-r--r-- | cgpt/cgpt_find.c | 83 | ||||
-rw-r--r-- | cgpt/cgpt_legacy.c | 7 | ||||
-rw-r--r-- | cgpt/cgpt_prioritize.c | 15 | ||||
-rw-r--r-- | cgpt/cgpt_repair.c | 6 | ||||
-rw-r--r-- | cgpt/cgpt_show.c | 155 | ||||
-rw-r--r-- | cgpt/cmd_create.c | 6 | ||||
-rw-r--r-- | cgpt/flash_ts.c | 423 | ||||
-rw-r--r-- | cgpt/flash_ts.h | 35 | ||||
-rw-r--r-- | cgpt/flash_ts_api.h | 25 | ||||
-rw-r--r-- | cgpt/flash_ts_drv.c | 72 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/mtdlib.h | 145 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/mtdlib_unused.h | 19 | ||||
-rw-r--r-- | firmware/lib/cgptlib/mtdlib.c | 93 | ||||
-rw-r--r-- | firmware/lib/cgptlib/mtdlib_unused.c | 284 | ||||
-rw-r--r-- | host/include/cgpt_params.h | 1 | ||||
-rw-r--r-- | tests/cgptlib_test.c | 564 |
23 files changed, 95 insertions, 2485 deletions
@@ -270,7 +270,6 @@ VBSLK_SRCS = \ firmware/lib/cgptlib/cgptlib.c \ firmware/lib/cgptlib/cgptlib_internal.c \ firmware/lib/cgptlib/crc32.c \ - firmware/lib/cgptlib/mtdlib.c \ firmware/lib/gpt_misc.c \ firmware/lib/utility_string.c \ firmware/lib/vboot_api_kernel.c \ @@ -362,9 +361,6 @@ UTILLIB_SRCS = \ cgpt/cgpt_repair.c \ cgpt/cgpt_prioritize.c \ cgpt/cgpt_common.c \ - cgpt/flash_ts.c \ - cgpt/flash_ts_drv.c \ - firmware/lib/cgptlib/mtdlib.c \ futility/dump_kernel_config_lib.c \ host/arch/${ARCH}/lib/crossystem_arch.c \ host/lib/crossystem.c \ @@ -391,11 +387,8 @@ HOSTLIB_SRCS = \ cgpt/cgpt_common.c \ cgpt/cgpt_create.c \ cgpt/cgpt_prioritize.c \ - cgpt/flash_ts.c \ - cgpt/flash_ts_drv.c \ firmware/lib/cgptlib/cgptlib_internal.c \ firmware/lib/cgptlib/crc32.c \ - firmware/lib/cgptlib/mtdlib.c \ firmware/lib/crc8.c \ firmware/lib/tpm_lite/tlcl.c \ firmware/lib/utility_string.c \ @@ -423,11 +416,8 @@ TINYHOSTLIB_SRCS = \ cgpt/cgpt_common.c \ cgpt/cgpt_create.c \ cgpt/cgpt_prioritize.c \ - cgpt/flash_ts.c \ - cgpt/flash_ts_drv.c \ firmware/lib/cgptlib/cgptlib_internal.c \ firmware/lib/cgptlib/crc32.c \ - firmware/lib/cgptlib/mtdlib.c \ firmware/lib/utility_string.c \ firmware/stub/utility_stub.c \ futility/dump_kernel_config_lib.c @@ -457,9 +447,7 @@ CGPT_SRCS = \ cgpt/cmd_legacy.c \ cgpt/cmd_prioritize.c \ cgpt/cmd_repair.c \ - cgpt/cmd_show.c \ - cgpt/flash_ts.c \ - cgpt/flash_ts_drv.c + cgpt/cmd_show.c CGPT_OBJS = ${CGPT_SRCS:%.c=${BUILD}/%.o} ALL_OBJS += ${CGPT_OBJS} @@ -996,10 +984,6 @@ ${BUILD}/tests/vb2_common3_tests: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/vboot_common2_tests: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/vboot_common3_tests: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/tests/cgptlib_test: OBJS += \ - ${BUILD}/firmware/lib/cgptlib/mtdlib_unused.o -${BUILD}/tests/cgptlib_test: ${BUILD}/firmware/lib/cgptlib/mtdlib_unused.o - ${BUILD}/utility/bmpblk_utility: LD = ${CXX} ${BUILD}/utility/bmpblk_utility: LDLIBS = -llzma -lyaml diff --git a/cgpt/cgpt.c b/cgpt/cgpt.c index ccf73184..38092006 100644 --- a/cgpt/cgpt.c +++ b/cgpt/cgpt.c @@ -52,45 +52,6 @@ void Usage(void) { printf("\nFor more detailed usage, use %s COMMAND -h\n\n", progname); } -static int is_pow2(size_t v) { - return v && (v & (v - 1)) == 0; -} - -static int parse_nand_option(const char *arg) { - int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size; - - if ('=' != arg[0]) - return -1; - - arg++; - bytes_per_page = atoi(arg); - arg = strchr(arg, ','); - if (!arg) - return -1; - - arg++; - pages_per_block = atoi(arg); - arg = strchr(arg, ','); - if (!arg) - return -1; - - arg++; - fts_block_offset = atoi(arg); - arg = strchr(arg, ','); - if (!arg) - return -1; - - arg++; - fts_block_size = atoi(arg); - if (fts_block_size == 0 || !is_pow2(pages_per_block) || - !is_pow2(bytes_per_page) || bytes_per_page < 512) { - return -1; - } - EnableNandImage(bytes_per_page, pages_per_block, fts_block_offset, - fts_block_size); - return 0; -} - int main(int argc, char *argv[]) { int i; int match_count = 0; @@ -103,25 +64,6 @@ int main(int argc, char *argv[]) { else progname = argv[0]; - - for (i = 1; i < argc; ++i) { - if (0 == strncmp(argv[i], "-N", 2)) { - if (!parse_nand_option(argv[i] + 2)) { - int j; - - // Remove it form the list. - for (j = i; j < argc - 1; j++) - argv[j] = argv[j + 1]; - argc--; - break; - } - // Bad nand config. - printf("Nand option must fit: -N=<bytes_per_page>,<pages_per_block>," - "<block_offset_of_partition>,<block_size_of_partition>\n"); - return CGPT_FAILED; - } - } - if (argc < 2) { Usage(); return CGPT_FAILED; diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h index bb3438a0..ff9e1064 100644 --- a/cgpt/cgpt.h +++ b/cgpt/cgpt.h @@ -13,7 +13,6 @@ #include "cgpt_endian.h" #include "cgptlib.h" #include "gpt.h" -#include "mtdlib.h" struct legacy_partition { uint8_t status; @@ -43,23 +42,11 @@ void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen); // Handle to the drive storing the GPT. struct drive { uint64_t size; /* total size (in bytes) */ - int is_mtd; GptData gpt; - MtdData mtd; struct pmbr pmbr; int fd; /* file descriptor */ }; -struct nand_layout { - int enabled; - int use_host_ioctl; /* Use ioctl() on /dev/fts to read/write. */ - int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size; -}; - -/* Write a NAND/MTD image instead of GPT. */ -void EnableNandImage(int bytes_per_page, int pages_per_block, - int fts_block_offset, int fts_block_size); - // Opens a block device or file, loads raw GPT data from it. // 'mode' should be O_RDONLY or O_RDWR. // If 'drive_size' is 0, both the partitions and GPT structs reside on the same @@ -156,11 +143,9 @@ int ResolveType(const Guid *type, char *buf); int SupportedType(const char *name, Guid *type); void PrintTypes(void); void EntryDetails(GptEntry *entry, uint32_t index, int raw); -void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw); uint32_t GetNumberOfEntries(const struct drive *drive); GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index); -MtdDiskPartition *MtdGetEntry(MtdData *mtd, int secondary, uint32_t index); void SetPriority(struct drive *drive, int secondary, uint32_t entry_index, int priority); @@ -184,8 +169,6 @@ int IsSynonymous(const GptHeader* a, const GptHeader* b); int IsUnused(struct drive *drive, int secondary, uint32_t index); int IsKernel(struct drive *drive, int secondary, uint32_t index); -int LookupMtdTypeForGuid(const Guid *type); -const Guid *LookupGuidForMtdType(int type); // Optional. Applications that need this must provide an implementation. // diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index 9bbc3fb5..d6b3cabd 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -95,32 +95,6 @@ static int GptSetEntryAttributes(struct drive *drive, return 0; } -static int MtdSetEntryAttributes(struct drive *drive, - uint32_t index, - CgptAddParams *params) { - MtdDiskPartition *entry; - - entry = MtdGetEntry(&drive->mtd, PRIMARY, index); - if (params->set_begin) { - uint64_t start = params->begin * drive->mtd.sector_bytes; - memcpy(&entry->starting_offset, &start, sizeof(params->begin)); - } - if (params->set_size) { - uint64_t start; - uint64_t end; - MtdGetPartitionSize(entry, &start, NULL, NULL); - end = start + params->size * drive->mtd.sector_bytes - 1; - memcpy(&entry->ending_offset, &end, sizeof(end)); - } - if (params->set_type) - MtdSetEntryType(entry, LookupMtdTypeForGuid(¶ms->type_guid)); - if (params->label) { - strncpy(entry->label, params->label, sizeof(entry->label)); - } - - return 0; -} - // This is an internal helper function which assumes no NULL args are passed. // It sets the given attribute values for a single entry at the given index. static int SetEntryAttributes(struct drive *drive, @@ -153,26 +127,20 @@ static int SetEntryAttributes(struct drive *drive, } static int CgptCheckAddValidity(struct drive *drive) { - if (drive->is_mtd) { - if (drive->mtd.primary.crc32 != MtdHeaderCrc(&drive->mtd.primary)) { - Error("MTD header CRC is invalid\n"); - return -1; - } - } else { - int gpt_retval; - if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) { - Error("GptSanityCheck() returned %d: %s\n", - gpt_retval, GptError(gpt_retval)); - return -1; - } + int gpt_retval; + if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) { + Error("GptSanityCheck() returned %d: %s\n", + gpt_retval, GptError(gpt_retval)); + return -1; + } - if (((drive->gpt.valid_headers & MASK_BOTH) != MASK_BOTH) || - ((drive->gpt.valid_entries & MASK_BOTH) != MASK_BOTH)) { - Error("one of the GPT header/entries is invalid.\n" - "please run 'cgpt repair' before adding anything.\n"); - return -1; - } + if (((drive->gpt.valid_headers & MASK_BOTH) != MASK_BOTH) || + ((drive->gpt.valid_entries & MASK_BOTH) != MASK_BOTH)) { + Error("one of the GPT header/entries is invalid.\n" + "please run 'cgpt repair' before adding anything.\n"); + return -1; } + return 0; } @@ -264,10 +232,6 @@ int CgptGetPartitionDetails(CgptAddParams *params) { Error("either partition or unique_id must be specified\n"); goto bad; } - if (drive.is_mtd) { - Error("MTD partitions cannot be specified by unique_id\n"); - goto bad; - } for (index = 0; index < max_part; index++) { GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index); if (GuidEqual(&entry->unique, ¶ms->unique_guid)) { @@ -282,22 +246,13 @@ int CgptGetPartitionDetails(CgptAddParams *params) { } index = params->partition - 1; - if(drive.is_mtd) { - MtdDiskPartition *entry = MtdGetEntry(&drive.mtd, PRIMARY, index); - const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry)); - memcpy(¶ms->type_guid, guid, sizeof(params->type_guid)); - memset(¶ms->unique_guid, 0, sizeof(params->unique_guid)); - MtdGetPartitionSizeInSectors(entry, ¶ms->begin, NULL, ¶ms->size); - params->raw_value = entry->flags; - } else { - // GPT-specific code - GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index); - params->begin = entry->starting_lba; - params->size = entry->ending_lba - entry->starting_lba + 1; - memcpy(¶ms->type_guid, &entry->type, sizeof(Guid)); - memcpy(¶ms->unique_guid, &entry->unique, sizeof(Guid)); - params->raw_value = entry->attrs.fields.gpt_att; - } + // GPT-specific code + GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index); + params->begin = entry->starting_lba; + params->size = entry->ending_lba - entry->starting_lba + 1; + memcpy(¶ms->type_guid, &entry->type, sizeof(Guid)); + memcpy(¶ms->unique_guid, &entry->unique, sizeof(Guid)); + params->raw_value = entry->attrs.fields.gpt_att; params->successful = GetSuccessful(&drive, PRIMARY, index); params->tries = GetTries(&drive, PRIMARY, index); @@ -338,22 +293,6 @@ static int GptAdd(struct drive *drive, CgptAddParams *params, uint32_t index) { return 0; } -static int MtdAdd(struct drive *drive, CgptAddParams *params, uint32_t index) { - MtdDiskPartition *entry, backup; - entry = MtdGetEntry(&drive->mtd, PRIMARY, index); - memcpy(&backup, entry, sizeof(backup)); - - if (SetEntryAttributes(drive, index, params) || - MtdSetEntryAttributes(drive, index, params)) { - memcpy(entry, &backup, sizeof(*entry)); - return -1; - } - - UpdateAllEntries(drive); - - return 0; -} - int CgptAdd(CgptAddParams *params) { struct drive drive; uint32_t index; @@ -373,13 +312,8 @@ int CgptAdd(CgptAddParams *params) { goto bad; } - if (drive.is_mtd) { - if (MtdAdd(&drive, params, index)) - goto bad; - } else { - if (GptAdd(&drive, params, index)) - goto bad; - } + if (GptAdd(&drive, params, index)) + goto bad; // Write it all out. return DriveClose(&drive, 1); diff --git a/cgpt/cgpt_boot.c b/cgpt/cgpt_boot.c index 928210b5..f4323962 100644 --- a/cgpt/cgpt_boot.c +++ b/cgpt/cgpt_boot.c @@ -79,15 +79,6 @@ int CgptBoot(CgptBootParams *params) { return CGPT_FAILED; } - if (drive.is_mtd) { - /* This command manipulates the legacy MBR sector present at the beginning - * of the GPT structures, and so doesn't apply to MTD drives. - */ - Error("'boot' command unsupported in MTD mode\n"); - retval = CGPT_FAILED; - goto done; - } - if (CGPT_OK != ReadPMBR(&drive)) { Error("Unable to read PMBR\n"); goto done; diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 1e7b5ab4..1438dfb3 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -25,24 +25,11 @@ #include "cgpt.h" #include "cgptlib_internal.h" #include "crc32.h" -#include "flash_ts.h" -#include "flash_ts_api.h" #include "vboot_host.h" static const char kErrorTag[] = "ERROR"; static const char kWarningTag[] = "WARNING"; -struct nand_layout nand; - -void EnableNandImage(int bytes_per_page, int pages_per_block, - int fts_block_offset, int fts_block_size) { - nand.enabled = 1; - nand.bytes_per_page = bytes_per_page; - nand.pages_per_block = pages_per_block; - nand.fts_block_offset = fts_block_offset; - nand.fts_block_size = fts_block_size; -} - static void LogToStderr(const char *tag, const char *format, va_list ap) { fprintf(stderr, "%s: ", tag); vfprintf(stderr, format, ap); @@ -156,161 +143,6 @@ int Save(struct drive *drive, const uint8_t *buf, return CGPT_OK; } -static int get_hex_char_value(char ch) { - if (ch >= '0' && ch <= '9') { - return ch - '0'; - } - if (ch >= 'a' && ch <= 'f') { - return ch - 'a' + 10; - } - if (ch >= 'A' && ch <= 'F') { - return ch - 'A' + 10; - } - return -1; -} - -static int TryInitMtd(const char *dev) { - static int already_inited = 0; - if (already_inited) - return nand.use_host_ioctl; - - already_inited = 1; - - /* If we're running on the live system, we can just use /dev/fts and not - * actually need the specific parameters. This needs to be accessed via - * ioctl and not normal I/O. - */ - if (!strcmp(dev, FTS_DEVICE) && !access(FTS_DEVICE, R_OK | W_OK)) { - nand.enabled = 1; - nand.use_host_ioctl = 1; - return 1; - } - return 0; -} - -int FlashGet(const char *key, uint8_t *data, uint32_t *bufsz) { - char *hex = (char*)malloc(*bufsz * 2); - char *read; - uint32_t written = 0; - - if (nand.use_host_ioctl) { - struct flash_ts_io_req req; - strncpy(req.key, key, sizeof(req.key)); - int fd = open(FTS_DEVICE, O_RDWR); - if (fd < 0) - return -1; - if (ioctl(fd, FLASH_TS_IO_GET, &req)) - return -1; - strncpy(hex, req.val, *bufsz * 2); - close(fd); - } else { - flash_ts_get(key, hex, *bufsz * 2); - } - - /* Hex -> binary */ - for (read = hex; read < hex + *bufsz * 2 && *read != '\0'; read += 2) { - int c0, c1; - c0 = get_hex_char_value(read[0]); - c1 = get_hex_char_value(read[1]); - if (c0 < 0 || c1 < 0) { - free(hex); - return -1; - } - - data[written++] = (c0 << 4) + c1; - } - *bufsz = written; - free(hex); - return 0; -} - -int FlashSet(const char *key, const uint8_t *data, uint32_t bufsz) { - char *hex = (char*)malloc(bufsz * 2 + 1); - const char *hex_chars = "0123456789ABCDEF"; - int ret; - uint32_t i; - - /* Binary -> hex, we need some encoding because FTS only stores C strings */ - for (i = 0; i < bufsz; i++) { - hex[i * 2] = hex_chars[data[i] >> 4]; - hex[i * 2 + 1] = hex_chars[data[i] & 0xF]; - } - /* Buffer must be NUL-terminated. */ - hex[bufsz * 2] = '\0'; - if (nand.use_host_ioctl) { - struct flash_ts_io_req req; - strncpy(req.key, key, sizeof(req.key)); - strncpy(req.val, hex, sizeof(req.val)); - free(hex); - int fd = open(FTS_DEVICE, O_RDWR); - if (fd < 0) - return -1; - if (ioctl(fd, FLASH_TS_IO_SET, &req)) - return -1; - close(fd); - return 0; - } - ret = flash_ts_set(key, hex); - free(hex); - return ret; -} - -int MtdLoad(struct drive *drive, int sector_bytes) { - int ret; - uint32_t sz; - MtdData *mtd = &drive->mtd; - - mtd->sector_bytes = sector_bytes; - mtd->drive_sectors = drive->size / mtd->sector_bytes; - - if (!nand.use_host_ioctl) { - ret = flash_ts_init(mtd->fts_block_offset, - mtd->fts_block_size, - mtd->flash_page_bytes, - mtd->flash_block_bytes, - mtd->sector_bytes, /* Needed for Load() and Save() */ - drive); - if (ret) - return ret; - } - - memset(&mtd->primary, 0, sizeof(mtd->primary)); - sz = sizeof(mtd->primary); - ret = FlashGet(MTD_DRIVE_SIGNATURE, (uint8_t *)&mtd->primary, &sz); - if (ret) - return ret; - - /* Read less than expected */ - if (sz < MTD_DRIVE_V1_SIZE) - memset(&mtd->primary, 0, sizeof(mtd->primary)); - - if (nand.use_host_ioctl) { - /* If we are using /dev/fts, we can't stat() the size, so re-use - * our internal value to set it. - */ - drive->size = mtd->primary.last_offset + 1; - mtd->drive_sectors = drive->size / mtd->sector_bytes; - } - - mtd->current_kernel = -1; - mtd->current_priority = 0; - mtd->modified = 0; - return 0; -} - -int MtdSave(struct drive *drive) { - MtdData *mtd = &drive->mtd; - - if (!mtd->modified) - return 0; - - mtd->primary.crc32 = 0; - mtd->primary.crc32 = Crc32(&mtd->primary, MTD_DRIVE_V1_SIZE); - - return FlashSet(MTD_DRIVE_SIGNATURE, (uint8_t *)&mtd->primary, - sizeof(mtd->primary)); -} - static int GptLoad(struct drive *drive, uint32_t sector_bytes) { drive->gpt.sector_bytes = sector_bytes; if (drive->size % drive->gpt.sector_bytes) { @@ -446,7 +278,6 @@ static int ObtainDriveSize(int fd, uint64_t* size, uint32_t* sector_bytes) { int DriveOpen(const char *drive_path, struct drive *drive, int mode, uint64_t drive_size) { uint32_t sector_bytes; - int is_mtd = nand.enabled; require(drive_path); require(drive); @@ -455,47 +286,32 @@ int DriveOpen(const char *drive_path, struct drive *drive, int mode, memset(drive, 0, sizeof(struct drive)); drive->gpt.stored_on_device = GPT_STORED_ON_DEVICE; - if (TryInitMtd(drive_path)) { - is_mtd = 1; - sector_bytes = 512; /* bytes */ - } else { - drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW); - if (drive->fd == -1) { - Error("Can't open %s: %s\n", drive_path, strerror(errno)); - return CGPT_FAILED; - } - - sector_bytes = 512; - uint64_t gpt_drive_size; - if (ObtainDriveSize(drive->fd, &gpt_drive_size, §or_bytes) != 0) { - Error("Can't get drive size and bytes per sector for %s: %s\n", - drive_path, strerror(errno)); - goto error_close; - } + drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW); + if (drive->fd == -1) { + Error("Can't open %s: %s\n", drive_path, strerror(errno)); + return CGPT_FAILED; + } - drive->gpt.gpt_drive_sectors = gpt_drive_size / sector_bytes; - if (drive_size == 0) { - drive->size = gpt_drive_size; - drive->gpt.stored_on_device = GPT_STORED_ON_DEVICE; - } else { - drive->size = drive_size; - drive->gpt.stored_on_device = GPT_STORED_OFF_DEVICE; - } + sector_bytes = 512; + uint64_t gpt_drive_size; + if (ObtainDriveSize(drive->fd, &gpt_drive_size, §or_bytes) != 0) { + Error("Can't get drive size and bytes per sector for %s: %s\n", + drive_path, strerror(errno)); + goto error_close; } - drive->is_mtd = is_mtd; - - if (is_mtd) { - drive->mtd.fts_block_offset = nand.fts_block_offset; - drive->mtd.fts_block_size = nand.fts_block_size; - drive->mtd.flash_page_bytes = nand.bytes_per_page; - drive->mtd.flash_block_bytes = nand.pages_per_block * nand.bytes_per_page; - if (MtdLoad(drive, sector_bytes)) { - goto error_close; - } + + drive->gpt.gpt_drive_sectors = gpt_drive_size / sector_bytes; + if (drive_size == 0) { + drive->size = gpt_drive_size; + drive->gpt.stored_on_device = GPT_STORED_ON_DEVICE; } else { - if (GptLoad(drive, sector_bytes)) { - goto error_close; - } + drive->size = drive_size; + drive->gpt.stored_on_device = GPT_STORED_OFF_DEVICE; + } + + + if (GptLoad(drive, sector_bytes)) { + goto error_close; } // We just load the data. Caller must validate it. @@ -511,14 +327,8 @@ int DriveClose(struct drive *drive, int update_as_needed) { int errors = 0; if (update_as_needed) { - if (drive->is_mtd) { - if (MtdSave(drive)) { - errors++; - } - } else { - if (GptSave(drive)) { + if (GptSave(drive)) { errors++; - } } } @@ -816,44 +626,16 @@ const static struct { const Guid *type; char *name; char *description; - int mtd_type; } supported_types[] = { - {&guid_chromeos_firmware, "firmware", "ChromeOS firmware", - MTD_PARTITION_TYPE_CHROMEOS_FIRMWARE}, - {&guid_chromeos_kernel, "kernel", "ChromeOS kernel", - MTD_PARTITION_TYPE_CHROMEOS_KERNEL}, - {&guid_chromeos_rootfs, "rootfs", "ChromeOS rootfs", - MTD_PARTITION_TYPE_CHROMEOS_ROOTFS}, - {&guid_linux_data, "data", "Linux data", - MTD_PARTITION_TYPE_LINUX_DATA}, - {&guid_chromeos_reserved, "reserved", "ChromeOS reserved", - MTD_PARTITION_TYPE_CHROMEOS_RESERVED}, - {&guid_efi, "efi", "EFI System Partition", - MTD_PARTITION_TYPE_EFI}, - {&guid_unused, "unused", "Unused (nonexistent) partition", - MTD_PARTITION_TYPE_UNUSED}, + {&guid_chromeos_firmware, "firmware", "ChromeOS firmware"}, + {&guid_chromeos_kernel, "kernel", "ChromeOS kernel"}, + {&guid_chromeos_rootfs, "rootfs", "ChromeOS rootfs"}, + {&guid_linux_data, "data", "Linux data"}, + {&guid_chromeos_reserved, "reserved", "ChromeOS reserved"}, + {&guid_efi, "efi", "EFI System Partition"}, + {&guid_unused, "unused", "Unused (nonexistent) partition"}, }; -int LookupMtdTypeForGuid(const Guid *type) { - int i; - for (i = 0; i < ARRAY_COUNT(supported_types); ++i) { - if (!memcmp(type, supported_types[i].type, sizeof(Guid))) { - return supported_types[i].mtd_type; - } - } - return MTD_PARTITION_TYPE_OTHER; -} - -const Guid *LookupGuidForMtdType(int type) { - int i; - for (i = 0; i < ARRAY_COUNT(supported_types); ++i) { - if (supported_types[i].mtd_type == type) { - return supported_types[i].type; - } - } - return NULL; -} - /* Resolves human-readable GPT type. * Returns CGPT_OK if found. * Returns CGPT_FAILED if no known type found. */ @@ -899,9 +681,6 @@ static GptHeader* GetGptHeader(const GptData *gpt) { } uint32_t GetNumberOfEntries(const struct drive *drive) { - if (drive->is_mtd) - return MTD_MAX_PARTITIONS; - GptHeader *header = GetGptHeader(&drive->gpt); if (!header) return 0; @@ -933,130 +712,74 @@ GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index) { return (GptEntry*)(&entries[stride * entry_index]); } -MtdDiskPartition* MtdGetEntry(MtdData *mtd, int secondary, uint32_t index) { - if (index >= MTD_MAX_PARTITIONS) - return NULL; - return &mtd->primary.partitions[index]; -} - void SetPriority(struct drive *drive, int secondary, uint32_t entry_index, int priority) { require(priority >= 0 && priority <= CGPT_ATTRIBUTE_MAX_PRIORITY); - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index); - MtdSetEntryPriority(e, priority); - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, entry_index); - SetEntryPriority(entry, priority); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + SetEntryPriority(entry, priority); } int GetPriority(struct drive *drive, int secondary, uint32_t entry_index) { - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index); - return MtdGetEntryPriority(e); - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, entry_index); - return GetEntryPriority(entry); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + return GetEntryPriority(entry); } void SetTries(struct drive *drive, int secondary, uint32_t entry_index, int tries) { require(tries >= 0 && tries <= CGPT_ATTRIBUTE_MAX_TRIES); - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index); - MtdSetEntryTries(e, tries); - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, entry_index); - SetEntryTries(entry, tries); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + SetEntryTries(entry, tries); } int GetTries(struct drive *drive, int secondary, uint32_t entry_index) { - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index); - return MtdGetEntryTries(e); - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, entry_index); - return GetEntryTries(entry); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + return GetEntryTries(entry); } void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index, int success) { require(success >= 0 && success <= CGPT_ATTRIBUTE_MAX_SUCCESSFUL); - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index); - MtdSetEntrySuccessful(e, success); - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, entry_index); - SetEntrySuccessful(entry, success); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + SetEntrySuccessful(entry, success); } int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index) { - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index); - return MtdGetEntrySuccessful(e); - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, entry_index); - return GetEntrySuccessful(entry); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + return GetEntrySuccessful(entry); } void SetRaw(struct drive *drive, int secondary, uint32_t entry_index, uint32_t raw) { - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index); - e->flags = raw; - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, entry_index); - entry->attrs.fields.gpt_att = (uint16_t)raw; - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + entry->attrs.fields.gpt_att = (uint16_t)raw; } void UpdateAllEntries(struct drive *drive) { - if (drive->is_mtd) { - drive->mtd.modified = 1; - drive->mtd.primary.crc32 = MtdHeaderCrc(&drive->mtd.primary); - } else { - RepairEntries(&drive->gpt, MASK_PRIMARY); - RepairHeader(&drive->gpt, MASK_PRIMARY); + RepairEntries(&drive->gpt, MASK_PRIMARY); + RepairHeader(&drive->gpt, MASK_PRIMARY); - drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 | - GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); - UpdateCrc(&drive->gpt); - } + drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 | + GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); + UpdateCrc(&drive->gpt); } int IsUnused(struct drive *drive, int secondary, uint32_t index) { - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, index); - return MtdGetEntryType(e) == MTD_PARTITION_TYPE_UNUSED; - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, index); - return GuidIsZero(&entry->type); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, index); + return GuidIsZero(&entry->type); } int IsKernel(struct drive *drive, int secondary, uint32_t index) { - if (drive->is_mtd) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, index); - return MtdGetEntryType(e) == MTD_PARTITION_TYPE_CHROMEOS_KERNEL; - } else { - GptEntry *entry; - entry = GetEntry(&drive->gpt, secondary, index); - return GuidEqual(&entry->type, &guid_chromeos_kernel); - } + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, index); + return GuidEqual(&entry->type, &guid_chromeos_kernel); } diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c index 18e2f51b..298e2ae5 100644 --- a/cgpt/cgpt_create.c +++ b/cgpt/cgpt_create.c @@ -88,31 +88,6 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) { return 0; } -static int MtdCreate(struct drive *drive, CgptCreateParams *params) { - MtdDiskLayout *h = &drive->mtd.primary; - memset(h, 0, sizeof(*h)); - drive->mtd.modified = 1; - - if (!params->zap) { - // Prep basic parameters - memcpy(h->signature, MTD_DRIVE_SIGNATURE, sizeof(h->signature)); - h->size = sizeof(*h); - h->first_offset = 0; - h->last_offset = (drive->mtd.drive_sectors * drive->mtd.sector_bytes) - 1; - h->crc32 = MtdHeaderCrc(h); - } - if (params->size) { - h->last_offset = params->size - 1; - drive->size = params->size; - drive->mtd.drive_sectors = drive->size / drive->mtd.sector_bytes; - } else if (!drive->mtd.drive_sectors) { - Error("MTD create with params->size == 0 && drive->mtd.drive_sectors == 0"); - return -1; - } - - return 0; -} - int CgptCreate(CgptCreateParams *params) { struct drive drive; @@ -123,13 +98,8 @@ int CgptCreate(CgptCreateParams *params) { params->drive_size)) return CGPT_FAILED; - if (drive.is_mtd) { - if (MtdCreate(&drive, params)) - goto bad; - } else { - if (GptCreate(&drive, params)) - goto bad; - } + if (GptCreate(&drive, params)) + goto bad; // Write it all out return DriveClose(&drive, 1); diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c index 7d9ec8df..c3193040 100644 --- a/cgpt/cgpt_find.c +++ b/cgpt/cgpt_find.c @@ -83,20 +83,6 @@ static void showmatch(CgptFindParams *params, char *filename, EntryDetails(entry, partnum - 1, params->numeric); } -// This needs to handle /dev/mmcblk0 -> /dev/mmcblk0p3, /dev/sda -> /dev/sda3 -static void mtd_showmatch(CgptFindParams *params, char *filename, - int partnum, MtdDiskPartition *entry) { - char * format = "%s%d\n"; - if (strncmp("/dev/mmcblk", filename, 11) == 0) - format = "%sp%d\n"; - if (params->numeric) - printf("%d\n", partnum); - else - printf(format, filename, partnum); - if (params->verbose > 0) - MtdEntryDetails(entry, partnum - 1, params->numeric); -} - // This returns true if a GPT partition matches the search criteria. If a match // isn't found (or if the file doesn't contain a GPT), it returns false. The // filename and partition number that matched is left in a global, since we @@ -144,69 +130,6 @@ static int gpt_search(CgptFindParams *params, struct drive *drive, return retval; } -static int mtd_match_type_to_guid(const MtdDiskPartition *e, const Guid *guid) { - return LookupMtdTypeForGuid(guid) == MtdGetEntryType(e); -} - -static int mtd_match_content(CgptFindParams *params, struct drive *drive, - MtdDiskPartition *entry) { - uint64_t start, part_size; - - if (!params->matchlen) - return 1; - - // Ensure that the region we want to match against is inside the partition. - MtdGetPartitionSize(entry, &start, NULL, &part_size); - if (params->matchoffset + params->matchlen > part_size) { - return 0; - } - - // Read the partition data. - if (!FillBuffer(params, - drive->fd, - start + params->matchoffset, - params->matchlen)) { - Error("unable to read partition data\n"); - return 0; - } - - // Compare it - if (0 == memcmp(params->matchbuf, params->comparebuf, params->matchlen)) { - return 1; - } - - // Nope. - return 0; -} - -static int mtd_search(CgptFindParams *params, struct drive *drive, - char *filename) { - int i; - int retval = 0; - for (i = 0; i < GetNumberOfEntries(drive); ++i) { - MtdDiskPartition *e = MtdGetEntry(&drive->mtd, ANY_VALID, i); - - if (IsUnused(drive, ANY_VALID, i)) - continue; - - int found = 0; - - // Only searches by type are possible right now - if (params->set_type && mtd_match_type_to_guid(e, ¶ms->type_guid)) { - found = 1; - } - - if (found && mtd_match_content(params, drive, e)) { - params->hits++; - retval++; - mtd_showmatch(params, filename, i+1, e); - if (!params->match_partnum) - params->match_partnum = i+1; - } - } - return retval; -} - static int do_search(CgptFindParams *params, char *fileName) { int retval; struct drive drive; @@ -214,11 +137,7 @@ static int do_search(CgptFindParams *params, char *fileName) { if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY, params->drive_size)) return 0; - if (drive.is_mtd) { - retval = mtd_search(params, &drive, fileName); - } else { - retval = gpt_search(params, &drive, fileName); - } + retval = gpt_search(params, &drive, fileName); (void) DriveClose(&drive, 0); diff --git a/cgpt/cgpt_legacy.c b/cgpt/cgpt_legacy.c index 07607690..b7582123 100644 --- a/cgpt/cgpt_legacy.c +++ b/cgpt/cgpt_legacy.c @@ -19,13 +19,6 @@ int CgptLegacy(CgptLegacyParams *params) { params->drive_size)) return CGPT_FAILED; - if (drive.is_mtd) { - // This command requires GPT mode. - Error("'legacy' command unsupported in MTD mode\n"); - DriveClose(&drive, 0); - return CGPT_FAILED; - } - h1 = (GptHeader *)drive.gpt.primary_header; h2 = (GptHeader *)drive.gpt.secondary_header; if (params->efipart) { diff --git a/cgpt/cgpt_prioritize.c b/cgpt/cgpt_prioritize.c index 019638d2..2bfc4843 100644 --- a/cgpt/cgpt_prioritize.c +++ b/cgpt/cgpt_prioritize.c @@ -110,17 +110,10 @@ int CgptPrioritize(CgptPrioritizeParams *params) { params->drive_size)) return CGPT_FAILED; - if (drive.is_mtd) { - if (drive.mtd.primary.crc32 != MtdHeaderCrc(&drive.mtd.primary)) { - Error("MTD header crc failure\n"); - return CGPT_FAILED; - } - } else { - if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { - Error("GptSanityCheck() returned %d: %s\n", - gpt_retval, GptError(gpt_retval)); - return CGPT_FAILED; - } + if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { + Error("GptSanityCheck() returned %d: %s\n", + gpt_retval, GptError(gpt_retval)); + return CGPT_FAILED; } max_part = GetNumberOfEntries(&drive); diff --git a/cgpt/cgpt_repair.c b/cgpt/cgpt_repair.c index 98899026..1880ea5b 100644 --- a/cgpt/cgpt_repair.c +++ b/cgpt/cgpt_repair.c @@ -19,12 +19,6 @@ int CgptRepair(CgptRepairParams *params) { params->drive_size)) return CGPT_FAILED; - if (drive.is_mtd) { - // Nothing to do - DriveClose(&drive, 0); - return 0; - } - int gpt_retval = GptSanityCheck(&drive.gpt); if (params->verbose) printf("GptSanityCheck() returned %d: %s\n", diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index 32d62d38..68a185cb 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -66,20 +66,6 @@ void PrintSignature(const char *indent, const char *sig, size_t n, int raw) { printf("\n"); } -static void MtdHeaderDetails(MtdDiskLayout *header, const char *indent, - int raw) { - PrintSignature(indent, (char*)header->signature, sizeof(header->signature), - raw); - - printf("%sSize: %d\n", indent, header->size); - printf("%sCRC: 0x%08x %s\n", indent, header->crc32, - (MtdHeaderCrc(header) != header->crc32) ? "(INVALID)" : ""); - printf("%sFirst offset: %llu\n", indent, - (unsigned long long)header->first_offset); - printf("%sLast offset: %llu\n", indent, - (unsigned long long)header->last_offset); -} - static void HeaderDetails(GptHeader *header, GptEntry *entries, const char *indent, int raw) { PrintSignature(indent, header->signature, sizeof(header->signature), raw); @@ -110,45 +96,6 @@ static void HeaderDetails(GptHeader *header, GptEntry *entries, ); } -void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw) { - const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry)); - char type[256]; - char contents[256]; - char name[sizeof(entry->label) + 1]; - uint64_t start, size; - if (guid) { - ResolveType(guid, type); - } else { - snprintf(type, sizeof(type), "MTD partition type %d", - MtdGetEntryType(entry)); - } - - MtdGetPartitionSizeInSectors(entry, &start, NULL, &size); - - // Provide a NUL if we are at maximum size. - name[sizeof(name)-1] = '\0'; - memcpy(name, entry->label, sizeof(entry->label)); - require(snprintf(contents, sizeof(contents), - "Label: \"%s\"", name) < sizeof(contents)); - - printf(PARTITION_FMT, (int)start, (int)size, index+1, contents); - printf(PARTITION_MORE, "Type: ", type); - - if (raw && MtdGetEntryType(entry) == MTD_PARTITION_TYPE_CHROMEOS_KERNEL) { - int tries = MtdGetEntryTries(entry); - int successful = MtdGetEntrySuccessful(entry); - int priority = MtdGetEntryPriority(entry); - require(snprintf(contents, sizeof(contents), - "priority=%d tries=%d successful=%d", - priority, tries, successful) < sizeof(contents)); - printf(PARTITION_MORE, "Attr: ", contents); - } else { - require(snprintf(contents, sizeof(contents), - "[%x]", entry->flags) < sizeof(contents)); - printf(PARTITION_MORE, "Attr: ", contents); - } -} - void EntryDetails(GptEntry *entry, uint32_t index, int raw) { char contents[256]; // scratch buffer for formatting output uint8_t label[GPT_PARTNAME_LEN]; @@ -194,18 +141,6 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) { } } -void MtdEntriesDetails(struct drive *drive, int secondary, int raw) { - uint32_t i; - - for (i = 0; i < GetNumberOfEntries(drive); ++i) { - MtdDiskPartition *entry; - entry = MtdGetEntry(&drive->mtd, secondary, i); - if (IsUnused(drive, secondary, i)) - continue; - MtdEntryDetails(entry, i, raw); - } -} - void EntriesDetails(struct drive *drive, const int secondary, int raw) { uint32_t i; @@ -220,87 +155,6 @@ void EntriesDetails(struct drive *drive, const int secondary, int raw) { } } -int MtdShow(struct drive *drive, CgptShowParams *params) { - if (params->partition) { // show single partition - if (params->partition > GetNumberOfEntries(drive)) { - Error("invalid partition number: %d\n", params->partition); - return CGPT_FAILED; - } - - uint32_t index = params->partition - 1; - 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", (int)start); - break; - case 's': - printf("%u\n", (int)size); - break; - case 't': - guid = LookupGuidForMtdType(MtdGetEntryType(entry)); - GuidToStr(guid, buf, sizeof(buf)); - printf("%s\n", buf); - break; - case 'S': - printf("%d\n", GetSuccessful(drive, ANY_VALID, index)); - break; - case 'T': - printf("%d\n", GetTries(drive, ANY_VALID, index)); - break; - case 'P': - printf("%d\n", GetPriority(drive, ANY_VALID, index)); - break; - case 'A': - printf("0x%x\n", entry->flags); - break; - } - } else { - printf(TITLE_FMT, "start", "size", "part", "contents"); - MtdEntryDetails(entry, index, params->numeric); - } - } else if (params->quick) { // show all partitions, quickly - uint32_t i; - char type[GUID_STRLEN]; - - 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; - - if (!params->numeric && guid) { - ResolveType(guid, type); - } else { - snprintf(type, sizeof(type), "MTD partition type %d", - MtdGetEntryType(entry)); - } - printf(PARTITION_FMT, (int)start, (int)size, i+1, type); - } - } else { // show all partitions - if (params->debug || params->verbose) { - char indent[64]; - - require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent)); - MtdHeaderDetails(&drive->mtd.primary, indent, 0); - } - printf(TITLE_FMT, "start", "size", "part", "contents"); - MtdEntriesDetails(drive, PRIMARY, params->numeric); - } - - return CGPT_OK; -} - static int GptShow(struct drive *drive, CgptShowParams *params) { int gpt_retval; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) { @@ -486,13 +340,8 @@ int CgptShow(CgptShowParams *params) { params->drive_size)) return CGPT_FAILED; - if (drive.is_mtd) { - if (MtdShow(&drive, params)) - return CGPT_FAILED; - } else { - if (GptShow(&drive, params)) - return CGPT_FAILED; - } + if (GptShow(&drive, params)) + return CGPT_FAILED; DriveClose(&drive, 0); return CGPT_OK; diff --git a/cgpt/cmd_create.c b/cgpt/cmd_create.c index 47137bdc..34f59cbc 100644 --- a/cgpt/cmd_create.c +++ b/cgpt/cmd_create.c @@ -19,7 +19,6 @@ static void Usage(void) " default 0, meaning partitions and GPT structs are\n" " both on DRIVE\n" " -z Zero the sectors of the GPT table and entries\n" - " -s NUM Size (in bytes) of the disk (MTD only)\n" " -p NUM Size (in blocks) of the disk to pad between the\n" " primary GPT header and its entries, default 0\n" "\n", progname); @@ -34,7 +33,7 @@ int cmd_create(int argc, char *argv[]) { char *e = 0; opterr = 0; // quiet, you - while ((c=getopt(argc, argv, ":hzs:p:D:")) != -1) + while ((c=getopt(argc, argv, ":hzp:D:")) != -1) { switch (c) { @@ -49,9 +48,6 @@ int cmd_create(int argc, char *argv[]) { case 'z': params.zap = 1; break; - case 's': - params.size = strtoull(optarg, &e, 0); - break; case 'p': params.padding = strtoull(optarg, &e, 0); if (!*optarg || (e && *e)) diff --git a/cgpt/flash_ts.c b/cgpt/flash_ts.c deleted file mode 100644 index f37c4acc..00000000 --- a/cgpt/flash_ts.c +++ /dev/null @@ -1,423 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* *** THIS CODE HAS NOT BEEN SECURITY REVIEWED *** - * It lives in the firmware directory because that's where it needs to go - * eventually, but at the moment it is used only by usermode tools. - * Security review must be completed before this code is used in the - * firmware. - * See issue 246680 - */ - -#include "flash_ts.h" - -#include <errno.h> -#include <stdio.h> -#include <string.h> - -#include "utility.h" - -// These match the linux driver -#define FLASH_TS_MAGIC 0x53542a46 - -#define FLASH_TS_HEADER_SIZE 16 -#define FLASH_TS_MAX_SIZE 16384 -#define FLASH_TS_MAX_ELEMENT_SIZE (FLASH_TS_MAX_SIZE - FLASH_TS_HEADER_SIZE) - -typedef struct { - uint32_t magic; - uint32_t crc; - uint32_t length; - uint32_t version; - char data[FLASH_TS_MAX_ELEMENT_SIZE]; -} __attribute__((packed)) flash_ts; - -typedef struct { - size_t start_block; // Partition start offset (in erase blocks) - size_t end_block; // Partition end offset (in erase blocks) - size_t chunk_size; // Minimum element size - size_t pages_per_block, chunks_per_block, pages_per_chunk; - nand_geom nand; - - size_t cached_block; - size_t current_block; - - flash_ts current; - flash_ts temp; -} flash_ts_state; - - -static flash_ts_state state; - -size_t pow2(size_t x) { - size_t v = 1; - while (v < x) - v <<= 1; - return v; -} - -static inline uint32_t flash_ts_crc(const flash_ts *cache) -{ - const unsigned char *p; - uint32_t crc = 0; - size_t len; - - /* skip magic and crc fields */ - len = cache->length + 2 * sizeof(uint32_t); - p = (const unsigned char*)&cache->length; - - while (len--) { - int i; - - crc ^= *p++; - for (i = 0; i < 8; i++) - crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); - } - return crc ^ ~0; -} - -static inline int flash_ts_check_crc(const flash_ts *ts) { - return ts->crc == flash_ts_crc(ts); -} - -static int is_blank(const void *ptr, size_t sz) { - const unsigned char *p = (const unsigned char*)ptr; - const unsigned char *end = p + sz; - while (p < end) - if (*p++ != 0xff) - return 0; - return 1; -} - -static int is_pow2(size_t v) { - return v && (v & (v - 1)) == 0; -} - -/* Scan the entire partition to find the latest version */ -static void flash_ts_scan_partition(flash_ts_state *ts) { - size_t block; - - for (block = ts->start_block; block < ts->end_block; block++) { - if (!nand_is_bad_block(&ts->nand, block)) { - size_t chunk; - size_t page_base = block * ts->pages_per_block; - - for (chunk = 0; chunk < ts->chunks_per_block; - chunk++, page_base += ts->pages_per_chunk) { - if (nand_read_page(&ts->nand, page_base, - &ts->temp, sizeof(ts->temp))) { - continue; - } - if (ts->temp.magic != FLASH_TS_MAGIC || - ts->temp.version <= ts->current.version || - !flash_ts_check_crc(&ts->temp)) { - if (is_blank(&ts->temp, sizeof(ts->temp))) { - // Since we only write sequentially, a blank chunk means no more - // data in this block. - break; - } - continue; - } - - // It's good & newer than our current version - VBDEBUG(("Found good version %d\n", ts->temp.version)); - ts->current_block = block; - Memcpy(&ts->current, &ts->temp, sizeof(ts->current)); - } - } - } -} - -static char *flash_ts_search(flash_ts *ts, const char *key) { - char *str = &ts->data[0]; - size_t keylen = strlen(key); - - while(*str && str + keylen < &ts->data[ts->length]) { - // Format: name=value\0name2=value2\0 ... keyn=valuen\0\0 - if (!Memcmp(str, key, keylen) && str[keylen] == '=') { - return &str[keylen + 1]; - } else { - str += strlen(str) + 1; // Skip to next key - } - } - return NULL; -} - -static int flash_ts_find_writeable_chunk(flash_ts_state *ts, uint32_t block) { - uint32_t page_base = block * ts->pages_per_block; - uint32_t page_end = (block + 1) * ts->pages_per_block; - - for(; page_base < page_end; page_base += ts->pages_per_chunk) { - if(!nand_read_page(&ts->nand, page_base, - &ts->temp, sizeof(ts->temp))) { - if (is_blank(&ts->temp, sizeof(ts->temp))) - return page_base; - } - } - - return -1; -} - -static int in_range(const flash_ts_state *ts, uint32_t block) { - return block >= ts->start_block && block < ts->end_block; -} - -static int flash_try_write(flash_ts_state *ts, uint32_t page) { - return nand_write_page(&ts->nand, page, &ts->current, sizeof(ts->current)) || - nand_read_page(&ts->nand, page, &ts->temp, sizeof(ts->temp)) || - Memcmp(&ts->current, &ts->temp, sizeof(ts->current)); -} - - -static int flash_ts_find_writeable_spot(flash_ts_state *ts, - uint32_t *page_ofs) { - uint32_t block; - if (in_range(ts, ts->cached_block)) { - // We have a starting position to scan from - block = ts->cached_block; - } else { - block = ts->start_block; - VBDEBUG(("Cached block not in range - starting from %u\n", block)); - } - for (; block < ts->end_block; block++) { - int chunk; - if (nand_is_bad_block(&ts->nand, block)) { - VBDEBUG(("Skipping bad block %u\n", block)); - continue; - } - - chunk = flash_ts_find_writeable_chunk(ts, block); - if (chunk < 0) { - VBDEBUG(("No free chunks in block %u\n", block)); - continue; - } - - VBDEBUG(("Free chunk %d in block %u\n", chunk, block)); - *page_ofs = chunk; - ts->cached_block = block; - return 0; - } - return -1; -} - -static int flash_try_erase(flash_ts_state *ts, int block) { - return nand_is_bad_block(&ts->nand, block) || - nand_erase_block(&ts->nand, block); -} - -static int flash_erase_any_block(flash_ts_state *ts, uint32_t hint) { - uint32_t block; - for (block = hint; block < ts->end_block; block++) { - if (!flash_try_erase(ts, block)) { - ts->cached_block = block; - VBDEBUG(("Erased block %u\n", block)); - return 0; - } - } - - if (hint > ts->end_block) - hint = ts->end_block; - - for (block = ts->start_block; block < hint; block++) { - if (!flash_try_erase(ts, block)) { - ts->cached_block = block; - VBDEBUG(("Erased block %u\n", block)); - return 0; - } - } - return -1; -} - -static int flash_ts_write(flash_ts_state *ts) { - int passes = 3; - uint32_t page; - - - ts->cached_block = ts->current_block; - ts->current.version++; - ts->current.crc = flash_ts_crc(&ts->current); - VBDEBUG(("flash_ts_write() - %u bytes, crc %08X\n", - ts->current.length, ts->current.crc)); - - while(passes--) { - if (flash_ts_find_writeable_spot(ts, &page)) { - if (ts->cached_block == ts->end_block) { - uint32_t block; - - // Partition full! - // Erase a block to get some space - if (in_range(ts, ts->current_block) && - ts->current_block != ts->end_block - 1) { - // We don't want to overwrite our good copy if we can avoid it. - block = ts->current_block + 1; - } else { - block = ts->start_block; - } - VBDEBUG(("Partition full - begin erasing from block %u\n", block)); - - // Erase block, and try again. - if (flash_erase_any_block(ts, block)) { - // Failed to erase anything, so abort. - VBDEBUG(("All erases failed, aborting\n")); - return -ENOMEM; - } - continue; - } else { - // Try again, re-scan everything. - ts->cached_block = ts->end_block; - continue; - } - } - - if (flash_try_write(ts, page)) { - // Write failure, or read-back failure, try again with the next block. - VBDEBUG(("Write failure, retry\n")); - ts->cached_block++; - continue; - } - - VBDEBUG(("Successfully written v%u @ %u\n", ts->current.version, page)); - ts->current_block = ts->cached_block; - return 0; - } - - VBDEBUG(("Out of tries\n")); - return -EAGAIN; -} - -// Set value, returns 0 on success -int flash_ts_set(const char *key, const char *value) { - flash_ts *ts = &state.current; - char *at; - size_t keylen = strlen(key); - size_t value_len = strlen(value); - - if (keylen == 0) { - VBDEBUG(("0-length key - illegal\n")); - return -1; - } - - if (strchr(key, '=')) { - VBDEBUG(("key contains '=' - illegal\n")); - return -1; - } - - Memcpy(&state.temp, &state.current, sizeof(state.temp)); - - at = flash_ts_search(ts, key); - if (at) { - size_t old_value_len; - - // Already exists - if (!strcmp(at, value)) { - // No change - VBDEBUG(("Values are the same, not writing\n")); - return 0; - } - - old_value_len = strlen(at); - if (value_len == old_value_len) { - // Overwrite it - Memcpy(at, value, value_len); - VBDEBUG(("Values are the same length, overwrite\n")); - } else { - // Remove it - // if value_len == 0, then we're done - // if value_len != old_value_len, then we do the append below - char *src = at - (keylen + 1); - char *end = &ts->data[ts->length]; - char *from = at + old_value_len + 1; - - VBDEBUG(("Delete old value\n")); - memmove(src, from, end - from); - ts->length -= (from-src); - ts->data[ts->length - 1] = '\0'; - at = NULL; // Enter the append branch below - } - } else if (value_len == 0) { - // Removing non-existent entry - return 0; - } - - if (!at && value_len > 0) { - // Append it - - if (ts->length + keylen + 1 + value_len + 1 > FLASH_TS_MAX_ELEMENT_SIZE) { - // Not enough space, restore previous - VBDEBUG(("Not enough space to write %d data bytes\n", (int)value_len)); - Memcpy(&state.current, &state.temp, sizeof(state.temp)); - return -1; - } - - VBDEBUG(("Append new value\n")); - at = &ts->data[ts->length - 1]; - strcpy(at, key); - at[keylen] = '='; - strcpy(at + keylen + 1, value); - ts->length += keylen + 1 + value_len + 1; - ts->data[ts->length-1] = '\0'; - } - - return flash_ts_write(&state); -} - -void flash_ts_get(const char *key, char *value, unsigned int size) { - flash_ts_state *ts = &state; - const char *at; - - at = flash_ts_search(&ts->current, key); - if (at) { - strncpy(value, at, size); - } else { - *value = '\0'; - } -} - -int flash_ts_init(unsigned int start_block, unsigned int blocks, - unsigned int szofpg, unsigned int szofblk, - unsigned int szofsector, void *user) { - flash_ts_state *ts = &state; - - if (!is_pow2(szofpg) || !is_pow2(szofblk) || !is_pow2(szofsector) || - szofsector > szofpg || szofpg > szofblk || blocks == 0) - return -ENODEV; - - Memset(ts, 0, sizeof(*ts)); - - // Page <= chunk <= block - // Page is minimum writable unit - // Chunk is actual write unit - // Block is erase unit - ts->start_block = start_block; - ts->end_block = start_block + blocks; - ts->pages_per_block = szofblk / szofpg; - - ts->nand.user = user; - ts->nand.szofpg = szofpg; - ts->nand.szofblk = szofblk; - ts->nand.szofsector = szofsector; - - // Calculate our write size, this mirrors the linux driver's logic - ts->chunk_size = pow2((sizeof(flash_ts) + szofpg - 1) & ~(szofpg - 1)); - if (!is_pow2(ts->chunk_size)) - return -ENODEV; - - ts->pages_per_chunk = ts->chunk_size / szofpg; - if (ts->pages_per_chunk == 0 || ts->chunk_size > szofblk) - return -ENODEV; - - ts->chunks_per_block = szofblk / ts->chunk_size; - - ts->current.version = 0; - ts->current.length = 1; - ts->current.magic = FLASH_TS_MAGIC; - ts->current.crc = flash_ts_crc(&ts->current); - ts->current.data[0] = '\0'; - ts->current_block = ts->end_block; - - flash_ts_scan_partition(ts); - - return 0; -} diff --git a/cgpt/flash_ts.h b/cgpt/flash_ts.h deleted file mode 100644 index e5771bb1..00000000 --- a/cgpt/flash_ts.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef _FLASH_TS_H -#define _FLASH_TS_H - -typedef struct { - unsigned int szofpg; /* Erase unit */ - unsigned int szofblk; /* Write unit */ - unsigned int szofsector; /* Sector size used by the rest of cgpt */ - void *user; -} nand_geom; - -int flash_ts_init(unsigned int start_block, unsigned int blocks, - unsigned int szofpg, unsigned int szofblk, - unsigned int szofsector, void *user); - -/* Get/set value, returns 0 on success */ -int flash_ts_set(const char *key, const char *value); -void flash_ts_get(const char *key, char *value, unsigned int size); - -/* Get value as an integer, if missing/invalid return 'default_value' */ -int flash_ts_get_int(const char *key, int default_value); - - -/* These must be implemented outside the driver. */ -int nand_read_page(const nand_geom *nand, int page, void *buf, int size); -int nand_write_page(const nand_geom *nand, int page, const void *buf, int size); -int nand_erase_block(const nand_geom *nand, int block); -int nand_is_bad_block(const nand_geom *nand, int block); - - - -#endif /* _FLASH_TS_H */ diff --git a/cgpt/flash_ts_api.h b/cgpt/flash_ts_api.h deleted file mode 100644 index 47264a4d..00000000 --- a/cgpt/flash_ts_api.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef _LINUX_FLASH_TS_H_ -#define _LINUX_FLASH_TS_H_ - -#include <asm/ioctl.h> -#include <asm/types.h> - -#define FLASH_TS_MAX_KEY_SIZE 64 -#define FLASH_TS_MAX_VAL_SIZE 2048 - -struct flash_ts_io_req { - char key[FLASH_TS_MAX_KEY_SIZE]; - char val[FLASH_TS_MAX_VAL_SIZE]; -}; - -#define FLASH_TS_IO_MAGIC 0xFE -#define FLASH_TS_IO_SET _IOW(FLASH_TS_IO_MAGIC, 0, struct flash_ts_io_req) -#define FLASH_TS_IO_GET _IOWR(FLASH_TS_IO_MAGIC, 1, struct flash_ts_io_req) - -#define FTS_DEVICE "/dev/fts" - -#endif /* _LINUX_FLASH_TS_H_ */ diff --git a/cgpt/flash_ts_drv.c b/cgpt/flash_ts_drv.c deleted file mode 100644 index 4709b37c..00000000 --- a/cgpt/flash_ts_drv.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c - * files for more details. - */ - -#include <errno.h> -#include <stdio.h> -#include <string.h> - -#include "flash_ts.h" -#include "cgpt.h" - -inline int page_to_sector(const nand_geom *nand, int page) { - return page * (nand->szofpg / nand->szofsector); -} - -int nand_read_page(const nand_geom *nand, int page, void *buf, int size) { - uint8_t *page_buff; - - if (Load((struct drive *)nand->user, &page_buff, - page_to_sector(nand, page), nand->szofsector, - (size + nand->szofsector - 1) / nand->szofsector)) { - - // page may be not erased. return default data. - memset(buf, 0xff, size); - return 0; - } - memcpy(buf, page_buff, size); - free(page_buff); - return 0; -} - -int nand_write_page(const nand_geom *nand, - int page, const void *buf, int buf_size) { - void *page_buff; - int ret; - int sectors = (buf_size + nand->szofsector - 1) / nand->szofsector; - int size = nand->szofsector * sectors; - - page_buff = malloc(size); - if (!page_buff) - return -1; - - memset(page_buff, 0xff, size); - memcpy(page_buff, buf, buf_size); - - ret = Save((struct drive *)nand->user, page_buff, page_to_sector(nand, page), - nand->szofsector, sectors); - free(page_buff); - return ret; -} - -int nand_erase_block(const nand_geom *nand, int block) { - int sector = block * (nand->szofblk / nand->szofsector); - int res; - void *erase_buff = malloc(nand->szofblk); - if (!erase_buff) - return -1; - - memset(erase_buff, 0xff, nand->szofblk); - res = Save((struct drive *)nand->user, erase_buff, sector, - nand->szofsector, nand->szofblk / nand->szofsector); - free(erase_buff); - return res; -} - -int nand_is_bad_block(const nand_geom *nand, int block) { - return 0; -} diff --git a/firmware/lib/cgptlib/include/mtdlib.h b/firmware/lib/cgptlib/include/mtdlib.h deleted file mode 100644 index 916c9fab..00000000 --- a/firmware/lib/cgptlib/include/mtdlib.h +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef VBOOT_REFERENCE_MTDLIB_H_ -#define VBOOT_REFERENCE_MTDLIB_H_ - -#include "cgptlib.h" -#include "sysincludes.h" - - -#define MTD_DRIVE_SIGNATURE "CrOSPart" /* This must be exactly 8 chars */ - -/* - * Bit definitions and masks for MTD attributes. - * - * 13-16 -- partition number - * 9-12 -- partition type - * 8 -- success - * 7-4 -- tries - * 3-0 -- priority - */ -#define MTD_ATTRIBUTE_PRIORITY_OFFSET (0) -#define MTD_ATTRIBUTE_MAX_PRIORITY (15UL) -#define MTD_ATTRIBUTE_PRIORITY_MASK (MTD_ATTRIBUTE_MAX_PRIORITY << \ - MTD_ATTRIBUTE_PRIORITY_OFFSET) - -#define MTD_ATTRIBUTE_TRIES_OFFSET (4) -#define MTD_ATTRIBUTE_MAX_TRIES (15UL) -#define MTD_ATTRIBUTE_TRIES_MASK (MTD_ATTRIBUTE_MAX_TRIES << \ - MTD_ATTRIBUTE_TRIES_OFFSET) - -#define MTD_ATTRIBUTE_SUCCESSFUL_OFFSET (8) -#define MTD_ATTRIBUTE_MAX_SUCCESSFUL (1UL) -#define MTD_ATTRIBUTE_SUCCESSFUL_MASK (MTD_ATTRIBUTE_MAX_SUCCESSFUL << \ - MTD_ATTRIBUTE_SUCCESSFUL_OFFSET) - -#define MTD_ATTRIBUTE_TYPE_OFFSET (9) -#define MTD_ATTRIBUTE_MAX_TYPE (15UL) -#define MTD_ATTRIBUTE_TYPE_MASK (MTD_ATTRIBUTE_MAX_TYPE << \ - MTD_ATTRIBUTE_TYPE_OFFSET) - -#define MTD_ATTRIBUTE_NUMBER_OFFSET (13) -#define MTD_ATTRIBUTE_MAX_NUMBER (15UL) -#define MTD_ATTRIBUTE_NUMBER_MASK (MTD_ATTRIBUTE_MAX_NUMBER << \ - MTD_ATTRIBUTE_NUMBER_OFFSET) - - -#define MTD_PARTITION_TYPE_UNUSED 0 -#define MTD_PARTITION_TYPE_CHROMEOS_KERNEL 1 -#define MTD_PARTITION_TYPE_CHROMEOS_FIRMWARE 2 -#define MTD_PARTITION_TYPE_CHROMEOS_ROOTFS 3 -#define MTD_PARTITION_TYPE_CHROMEOS_RESERVED 4 -#define MTD_PARTITION_TYPE_CHROMEOS_FLAGSTORE 5 -#define MTD_PARTITION_TYPE_LINUX_DATA 6 -#define MTD_PARTITION_TYPE_EFI 7 -#define MTD_PARTITION_TYPE_OTHER 8 - -/* This is mostly arbitrary at the moment, but gives a little room to expand. */ -#define MTD_MAX_PARTITIONS 16 - - - -typedef struct { - uint64_t starting_offset; - uint64_t ending_offset; - uint32_t flags; - - /* 28 characters is a balance between GPT parity and size constraints, at - * current sizes this table occupies 10% of the FTS data store. - */ - char label[28]; -} __attribute__((packed)) MtdDiskPartition; - -typedef struct { - unsigned char signature[8]; - /* For compatibility, this is only ever the CRC of the first - * MTD_DRIVE_V1_SIZE bytes. Further extensions must include their own CRCs, - * so older FW can boot newer layouts if we expand in the future. - */ - uint32_t crc32; - uint32_t size; - uint64_t first_offset; - uint64_t last_offset; - MtdDiskPartition partitions[MTD_MAX_PARTITIONS]; -} __attribute__((packed)) MtdDiskLayout; - -#define MTD_DRIVE_V1_SIZE (32 + 16*48) - -#define MTDENTRY_EXPECTED_SIZE (48) -#define MTDLAYOUT_EXPECTED_SIZE (32 + 16 * MTDENTRY_EXPECTED_SIZE) - - -typedef struct { - /* Specifies the flash geometry, in erase blocks & write pages */ - uint32_t flash_block_bytes; - uint32_t flash_page_bytes; - - /* Location, in blocks, of FTS partition */ - uint32_t fts_block_offset; - /* Size, in blocks, of FTS partition */ - uint32_t fts_block_size; - - /* Size of a LBA sector, in bytes */ - uint32_t sector_bytes; - /* Size of drive in LBA sectors, in sectors */ - uint64_t drive_sectors; - - /* - * The current chromeos kernel index in partition table. -1 means not - * found on drive. - */ - int current_kernel; - int current_priority; - - /* If set, the flags partition has been modified and needs to be flushed */ - int modified; - - /* Internal variables */ - MtdDiskLayout primary; -} MtdData; - - -/* APIs are documented in cgptlib.h & cgptlib_internal.h */ -int MtdGetEntryPriority(const MtdDiskPartition *e); -int MtdGetEntryTries(const MtdDiskPartition *e); -int MtdGetEntrySuccessful(const MtdDiskPartition *e); -int MtdGetEntryType(const MtdDiskPartition *e); -void MtdSetEntrySuccessful(MtdDiskPartition *e, int successful) ; -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); - -int MtdGptInit(MtdData *mtd); -uint32_t MtdHeaderCrc(MtdDiskLayout *h); - -#endif - diff --git a/firmware/lib/cgptlib/include/mtdlib_unused.h b/firmware/lib/cgptlib/include/mtdlib_unused.h deleted file mode 100644 index f331decd..00000000 --- a/firmware/lib/cgptlib/include/mtdlib_unused.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef VBOOT_REFERENCE_MTDLIB_UNUSED_H_ -#define VBOOT_REFERENCE_MTDLIB_UNUSED_H_ - -int MtdIsKernelEntry(const MtdDiskPartition *e); -void MtdModified(MtdData *mtd); -int MtdIsPartitionValid(const MtdDiskPartition *part); -int MtdCheckParameters(MtdData *disk); -int MtdCheckEntries(MtdDiskPartition *entries, MtdDiskLayout *h); -int MtdSanityCheck(MtdData *disk); -int MtdInit(MtdData *mtd); -int MtdNextKernelEntry(MtdData *mtd, uint64_t *start_sector, uint64_t *size); -int MtdUpdateKernelEntry(MtdData *mtd, uint32_t update_type); - -#endif /* VBOOT_REFERENCE_MTDLIB_UNUSED_H_ */ diff --git a/firmware/lib/cgptlib/mtdlib.c b/firmware/lib/cgptlib/mtdlib.c deleted file mode 100644 index 98662523..00000000 --- a/firmware/lib/cgptlib/mtdlib.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "mtdlib.h" - -#include "cgptlib.h" -#include "cgptlib_internal.h" -#include "crc32.h" -#include "utility.h" -#include "vboot_api.h" - -const int kSectorShift = 9; /* 512 bytes / sector. */ - -int MtdGetEntryPriority(const MtdDiskPartition *e) { - return ((e->flags & MTD_ATTRIBUTE_PRIORITY_MASK) >> - MTD_ATTRIBUTE_PRIORITY_OFFSET); -} - -int MtdGetEntryTries(const MtdDiskPartition *e) { - return ((e->flags & MTD_ATTRIBUTE_TRIES_MASK) >> - MTD_ATTRIBUTE_TRIES_OFFSET); -} - -int MtdGetEntrySuccessful(const MtdDiskPartition *e) { - return ((e->flags & MTD_ATTRIBUTE_SUCCESSFUL_MASK) >> - MTD_ATTRIBUTE_SUCCESSFUL_OFFSET); -} - -int MtdGetEntryType(const MtdDiskPartition *e) { - return ((e->flags & MTD_ATTRIBUTE_TYPE_MASK) >> MTD_ATTRIBUTE_TYPE_OFFSET); -} - -static void SetBitfield(MtdDiskPartition *e, - uint32_t offset, uint32_t mask, uint32_t v) { - 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); -} -void MtdSetEntryPriority(MtdDiskPartition *e, int priority) { - SetBitfield(e, MTD_ATTRIBUTE_PRIORITY_OFFSET, MTD_ATTRIBUTE_PRIORITY_MASK, - priority); -} -void MtdSetEntryTries(MtdDiskPartition *e, int tries) { - SetBitfield(e, MTD_ATTRIBUTE_TRIES_OFFSET, MTD_ATTRIBUTE_TRIES_MASK, tries); -} -void MtdSetEntryType(MtdDiskPartition *e, int type) { - SetBitfield(e, MTD_ATTRIBUTE_TYPE_OFFSET, MTD_ATTRIBUTE_TYPE_MASK, type); -} - -uint32_t MtdHeaderCrc(MtdDiskLayout *h) { - uint32_t crc32, original_crc32; - - /* Original CRC is calculated with the CRC field 0. */ - original_crc32 = h->crc32; - h->crc32 = 0; - crc32 = Crc32((const uint8_t *)h, h->size); - h->crc32 = original_crc32; - - 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; -} - - - diff --git a/firmware/lib/cgptlib/mtdlib_unused.c b/firmware/lib/cgptlib/mtdlib_unused.c deleted file mode 100644 index bf285005..00000000 --- a/firmware/lib/cgptlib/mtdlib_unused.c +++ /dev/null @@ -1,284 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "mtdlib.h" -#include "mtdlib_unused.h" - -#include "cgptlib.h" -#include "cgptlib_internal.h" -#include "crc32.h" -#include "utility.h" -#include "vboot_api.h" - -int MtdIsKernelEntry(const MtdDiskPartition *e) { - return MtdGetEntryType(e) == MTD_PARTITION_TYPE_CHROMEOS_KERNEL; -} - -void MtdModified(MtdData *mtd) { - mtd->modified = 1; - mtd->primary.crc32 = MtdHeaderCrc(&mtd->primary); -} - -int MtdIsPartitionValid(const MtdDiskPartition *part) { - return MtdGetEntryType(part) != 0; -} - -int MtdCheckParameters(MtdData *disk) { - if (disk->sector_bytes != 512) { - return GPT_ERROR_INVALID_SECTOR_SIZE; - } - - /* At minimum, the disk must consist of at least one erase block */ - if (disk->drive_sectors < disk->flash_block_bytes / disk->sector_bytes) { - return GPT_ERROR_INVALID_SECTOR_NUMBER; - } - - /* Write pages must be an integer multiple of sector size */ - if (disk->flash_page_bytes == 0 || - disk->flash_page_bytes % disk->sector_bytes != 0) { - return GPT_ERROR_INVALID_FLASH_GEOMETRY; - } - - /* Erase blocks must be an integer multiple of write pages */ - if (disk->flash_block_bytes == 0 || - disk->flash_block_bytes % disk->flash_page_bytes != 0) { - return GPT_ERROR_INVALID_FLASH_GEOMETRY; - } - - /* Without a FTS region, why are you using MTD? */ - if (disk->fts_block_size == 0) { - return GPT_ERROR_INVALID_FLASH_GEOMETRY; - } - return GPT_SUCCESS; -} - - -int MtdCheckEntries(MtdDiskPartition *entries, MtdDiskLayout *h) { - uint32_t i, j; - - for (i = 0; i < MTD_MAX_PARTITIONS; i++) { - for (j = 0; j < MTD_MAX_PARTITIONS; j++) { - 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; - - 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 (end > h->last_offset) { - return GPT_ERROR_OUT_OF_REGION; - } - if (start < h->first_offset) { - return GPT_ERROR_OUT_OF_REGION; - } - if (start > end) { - return GPT_ERROR_OUT_OF_REGION; - } - - if ((start >= other_start) && - (start <= other_end)) { - return GPT_ERROR_START_LBA_OVERLAP; - } - if ((end >= other_start) && - (end <= other_end)) { - return GPT_ERROR_END_LBA_OVERLAP; - } - } - } - } - return GPT_SUCCESS; -} - -int MtdSanityCheck(MtdData *disk) { - MtdDiskLayout *h = &disk->primary; - int ret; - - ret = MtdCheckParameters(disk); - if(GPT_SUCCESS != ret) - return ret; - - if (Memcmp(disk->primary.signature, MTD_DRIVE_SIGNATURE, - sizeof(disk->primary.signature))) { - return GPT_ERROR_INVALID_HEADERS; - } - - 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; - } - - if (h->crc32 != MtdHeaderCrc(h)) { - return GPT_ERROR_CRC_CORRUPTED; - } - if (h->size < MTD_DRIVE_V1_SIZE) { - return GPT_ERROR_INVALID_HEADERS; - } - return MtdCheckEntries(h->partitions, h); -} - - -int MtdInit(MtdData *mtd) { - int ret; - - mtd->modified = 0; - mtd->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; - mtd->current_priority = 999; - - ret = MtdSanityCheck(mtd); - if (GPT_SUCCESS != ret) { - VBDEBUG(("MtdInit() failed sanity check\n")); - return ret; - } - - return GPT_SUCCESS; -} - -int MtdNextKernelEntry(MtdData *mtd, uint64_t *start_sector, uint64_t *size) -{ - MtdDiskLayout *header = &mtd->primary; - MtdDiskPartition *entries = header->partitions; - MtdDiskPartition *e; - int new_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; - int new_prio = 0; - uint32_t i; - - /* - * If we already found a kernel, continue the scan at the current - * kernel's priority, in case there is another kernel with the same - * priority. - */ - if (mtd->current_kernel != CGPT_KERNEL_ENTRY_NOT_FOUND) { - for (i = mtd->current_kernel + 1; - i < MTD_MAX_PARTITIONS; i++) { - e = entries + i; - if (!MtdIsKernelEntry(e)) - continue; - VBDEBUG(("MtdNextKernelEntry looking at same prio " - "partition %d\n", i+1)); - 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; - VBDEBUG(("MtdNextKernelEntry likes it\n")); - return GPT_SUCCESS; - } - } - } - - /* - * We're still here, so scan for the remaining kernel with the highest - * priority less than the previous attempt. - */ - for (i = 0, e = entries; i < MTD_MAX_PARTITIONS; i++, e++) { - int current_prio = MtdGetEntryPriority(e); - if (!MtdIsKernelEntry(e)) - continue; - VBDEBUG(("MtdNextKernelEntry looking at new prio " - "partition %d\n", i+1)); - VBDEBUG(("MtdNextKernelEntry s%d t%d p%d\n", - MtdGetEntrySuccessful(e), MtdGetEntryTries(e), - MtdGetEntryPriority(e))); - if (!(MtdGetEntrySuccessful(e) || MtdGetEntryTries(e))) - continue; - if (current_prio >= mtd->current_priority) { - /* Already returned this kernel in a previous call */ - continue; - } - if (current_prio > new_prio) { - new_kernel = i; - new_prio = current_prio; - } - } - - /* - * Save what we found. Note that if we didn't find a new kernel, - * new_prio will still be -1, so future calls to this function will - * also fail. - */ - mtd->current_kernel = new_kernel; - mtd->current_priority = new_prio; - - if (CGPT_KERNEL_ENTRY_NOT_FOUND == new_kernel) { - VBDEBUG(("MtdNextKernelEntry no more kernels\n")); - return GPT_ERROR_NO_VALID_KERNEL; - } - - VBDEBUG(("MtdNextKernelEntry likes partition %d\n", new_kernel + 1)); - e = entries + new_kernel; - MtdGetPartitionSizeInSectors(e, start_sector, NULL, size); - - return GPT_SUCCESS; -} - - -int MtdUpdateKernelEntry(MtdData *mtd, uint32_t update_type) -{ - MtdDiskLayout *header = &mtd->primary; - MtdDiskPartition *entries = header->partitions; - MtdDiskPartition *e = entries + mtd->current_kernel; - int modified = 0; - - if (mtd->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND) - return GPT_ERROR_INVALID_UPDATE_TYPE; - if (!MtdIsKernelEntry(e)) - return GPT_ERROR_INVALID_UPDATE_TYPE; - - switch (update_type) { - case GPT_UPDATE_ENTRY_TRY: { - /* Used up a try */ - int tries; - if (MtdGetEntrySuccessful(e)) { - /* - * Successfully booted this partition, so tries field - * is ignored. - */ - return GPT_SUCCESS; - } - tries = MtdGetEntryTries(e); - if (tries > 1) { - /* Still have tries left */ - modified = 1; - MtdSetEntryTries(e, tries - 1); - break; - } - /* Out of tries, so drop through and mark partition bad. */ - } - case GPT_UPDATE_ENTRY_BAD: { - /* Giving up on this partition entirely. */ - if (!MtdGetEntrySuccessful(e)) { - /* - * Only clear tries and priority if the successful bit - * is not set. - */ - modified = 1; - MtdSetEntryTries(e, 0); - MtdSetEntryPriority(e, 0); - } - break; - } - default: - return GPT_ERROR_INVALID_UPDATE_TYPE; - } - - if (modified) { - MtdModified(mtd); - } - - return GPT_SUCCESS; -} diff --git a/host/include/cgpt_params.h b/host/include/cgpt_params.h index e10d15e7..e7ac7327 100644 --- a/host/include/cgpt_params.h +++ b/host/include/cgpt_params.h @@ -17,7 +17,6 @@ typedef struct CgptCreateParams { char *drive_name; uint64_t drive_size; int zap; - uint64_t size; uint64_t padding; } CgptCreateParams; diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c index fc166fda..fd5cda16 100644 --- a/tests/cgptlib_test.c +++ b/tests/cgptlib_test.c @@ -7,14 +7,11 @@ #include <string.h> #include "../cgpt/cgpt.h" -#include "../cgpt/flash_ts.h" #include "cgptlib_internal.h" #include "cgptlib_test.h" #include "crc32.h" #include "crc32_test.h" #include "gpt.h" -#include "mtdlib.h" -#include "mtdlib_unused.h" #include "test_common.h" #define _STUB_IMPLEMENTATION_ #include "utility.h" @@ -55,11 +52,6 @@ static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; const char *progname = "CGPT-TEST"; const char *command = "TEST"; -// Ramdisk for flash ts testing. -static uint8_t *nand_drive = NULL; -static uint32_t nand_drive_sz; -static uint8_t *nand_bad_block_map = NULL; - /* * Copy a random-for-this-program-only Guid into the dest. The num parameter * completely determines the Guid. @@ -142,13 +134,6 @@ static GptData *GetEmptyGptData(void) return &gpt; } -static MtdData *GetEmptyMtdData() { - static MtdData mtd; - Memset(&mtd, 0, sizeof(mtd)); - mtd.current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; - return &mtd; -} - /* * Fill in most of fields and creates the layout described in the top of this * file. Before calling this function, primary/secondary header/entries must @@ -215,50 +200,6 @@ static void BuildTestGptData(GptData *gpt) RefreshCrc32(gpt); } -static void BuildTestMtdData(MtdData *mtd) { - MtdDiskPartition *partitions; - - mtd->sector_bytes = DEFAULT_SECTOR_SIZE; - mtd->drive_sectors = DEFAULT_DRIVE_SECTORS; - mtd->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; - mtd->modified = 0; - Memset(&mtd->primary, 0, sizeof(mtd->primary)); - - Memcpy(mtd->primary.signature, MTD_DRIVE_SIGNATURE, - sizeof(mtd->primary.signature)); - 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 */ - mtd->flash_page_bytes = mtd->sector_bytes * 8; - mtd->flash_block_bytes = mtd->flash_page_bytes * 8; - mtd->fts_block_offset = 1; - mtd->fts_block_size = 1; - - partitions = &mtd->primary.partitions[0]; - 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_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_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_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; - - mtd->primary.crc32 = 0; - mtd->primary.crc32 = Crc32(&mtd->primary, MTD_DRIVE_V1_SIZE); -} - - /* * Test if the structures are the expected size; if this fails, struct packing * is not working properly. @@ -269,8 +210,6 @@ static int StructSizeTest(void) EXPECT(GUID_EXPECTED_SIZE == sizeof(Guid)); EXPECT(GPTHEADER_EXPECTED_SIZE == sizeof(GptHeader)); EXPECT(GPTENTRY_EXPECTED_SIZE == sizeof(GptEntry)); - EXPECT(MTDENTRY_EXPECTED_SIZE == sizeof(MtdDiskPartition)); - EXPECT(MTDLAYOUT_EXPECTED_SIZE == sizeof(MtdDiskLayout)); return TEST_OK; } @@ -288,26 +227,15 @@ static int TestBuildTestGptData(void) return TEST_OK; } -static int TestBuildTestMtdData() { - MtdData *mtd = GetEmptyMtdData(); - - BuildTestMtdData(mtd); - EXPECT(GPT_SUCCESS == MtdInit(mtd)); - return TEST_OK; -} - /* * Test if wrong sector_bytes or drive_sectors is detected by GptInit(). * Currently we only support 512 bytes per sector. In the future, we may * support other sizes. A too small drive_sectors should be rejected by * GptInit(). - * For MtdInit(), additionally test various flash geometries to verify - * that only valid ones are accepted. */ static int ParameterTests(void) { GptData *gpt; - MtdData *mtd; struct { uint32_t sector_bytes; uint64_t drive_sectors; @@ -321,32 +249,6 @@ static int ParameterTests(void) GPT_ENTRIES_SECTORS * 2, GPT_SUCCESS}, {4096, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE}, }; - struct { - uint32_t sector_bytes; - uint32_t drive_sectors; - uint32_t flash_page_bytes; - uint32_t flash_block_bytes; - int expected_retval; - } mtdcases[] = { - {512, DEFAULT_DRIVE_SECTORS, 8*512, - 8*512, GPT_SUCCESS}, - {510, DEFAULT_DRIVE_SECTORS, 8*512, - 8*512, GPT_ERROR_INVALID_SECTOR_SIZE}, - {512, DEFAULT_DRIVE_SECTORS, 8*512, - 8*512, GPT_SUCCESS}, - {512, DEFAULT_DRIVE_SECTORS, 512, - 8*512, GPT_SUCCESS}, - {512, DEFAULT_DRIVE_SECTORS, 8*512, - 10*512, GPT_ERROR_INVALID_FLASH_GEOMETRY}, - {512, DEFAULT_DRIVE_SECTORS, 3*512, - 9*512, GPT_SUCCESS}, - {512, DEFAULT_DRIVE_SECTORS, 8*512, - 6*512, GPT_ERROR_INVALID_FLASH_GEOMETRY}, - {512, DEFAULT_DRIVE_SECTORS, 256, - 6*512, GPT_ERROR_INVALID_FLASH_GEOMETRY}, - {512, DEFAULT_DRIVE_SECTORS, 512, - 6*512 + 256, GPT_ERROR_INVALID_FLASH_GEOMETRY}, - }; int i; gpt = GetEmptyGptData(); @@ -357,19 +259,6 @@ static int ParameterTests(void) EXPECT(cases[i].expected_retval == CheckParameters(gpt)); } - mtd = GetEmptyMtdData(); - for (i = 0; i < ARRAY_SIZE(cases); ++i) { - BuildTestMtdData(mtd); - mtd->sector_bytes = mtdcases[i].sector_bytes; - mtd->drive_sectors = mtdcases[i].drive_sectors; - mtd->flash_block_bytes = mtdcases[i].flash_block_bytes; - mtd->flash_page_bytes = mtdcases[i].flash_page_bytes; - if(mtdcases[i].expected_retval != MtdCheckParameters(mtd)) { - printf("i=%d\n",i); - } - EXPECT(mtdcases[i].expected_retval == MtdCheckParameters(mtd)); - } - return TEST_OK; } @@ -811,9 +700,6 @@ static int ValidEntryTest(void) GptData *gpt = GetEmptyGptData(); GptHeader *h1 = (GptHeader *)gpt->primary_header; GptEntry *e1 = (GptEntry *)(gpt->primary_entries); - MtdData *mtd = GetEmptyMtdData(); - MtdDiskLayout *mh = &mtd->primary; - MtdDiskPartition *me = mh->partitions; /* error case: entry.StartingLBA < header.FirstUsableLBA */ BuildTestGptData(gpt); @@ -821,35 +707,18 @@ static int ValidEntryTest(void) RefreshCrc32(gpt); EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); - BuildTestMtdData(mtd); - 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)); - } - /* error case: entry.EndingLBA > header.LastUsableLBA */ BuildTestGptData(gpt); e1[2].ending_lba = h1->last_usable_lba + 1; RefreshCrc32(gpt); EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); - BuildTestMtdData(mtd); - me[0].ending_offset = mh->last_offset + 1; - mh->crc32 = MtdHeaderCrc(mh); - EXPECT(GPT_ERROR_OUT_OF_REGION == MtdCheckEntries(me, mh)); - /* error case: entry.StartingLBA > entry.EndingLBA */ BuildTestGptData(gpt); e1[3].starting_lba = e1[3].ending_lba + 1; RefreshCrc32(gpt); EXPECT(GPT_ERROR_OUT_OF_REGION == CheckEntries(e1, h1)); - BuildTestMtdData(mtd); - me[0].starting_offset = me[0].ending_offset + 1; - mh->crc32 = MtdHeaderCrc(mh); - EXPECT(GPT_ERROR_OUT_OF_REGION == MtdCheckEntries(me, mh)); - /* case: non active entry should be ignored. */ BuildTestGptData(gpt); Memset(&e1[1].type, 0, sizeof(e1[1].type)); @@ -857,12 +726,6 @@ static int ValidEntryTest(void) RefreshCrc32(gpt); EXPECT(0 == CheckEntries(e1, h1)); - BuildTestMtdData(mtd); - me[0].flags = 0; - me[0].starting_offset = me[0].ending_offset + 1; - mh->crc32 = MtdHeaderCrc(mh); - EXPECT(GPT_SUCCESS == MtdCheckEntries(me, mh)); - return TEST_OK; } @@ -871,9 +734,6 @@ static int OverlappedPartitionTest(void) { GptData *gpt = GetEmptyGptData(); GptHeader *h = (GptHeader *)gpt->primary_header; GptEntry *e = (GptEntry *)gpt->primary_entries; - MtdData *mtd = GetEmptyMtdData(); - MtdDiskLayout *mh = &mtd->primary; - MtdDiskPartition *me = mh->partitions; int i, j; struct { @@ -926,8 +786,6 @@ static int OverlappedPartitionTest(void) { for (i = 0; i < ARRAY_SIZE(cases); ++i) { BuildTestGptData(gpt); - BuildTestMtdData(mtd); - Memset(mh->partitions, 0, sizeof(mh->partitions)); ZeroEntries(gpt); for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { if (!cases[i].entries[j].starting_lba) @@ -935,22 +793,14 @@ static int OverlappedPartitionTest(void) { if (cases[i].entries[j].active) { Memcpy(&e[j].type, &guid_kernel, sizeof(Guid)); - me[j].flags = - MTD_PARTITION_TYPE_CHROMEOS_KERNEL << MTD_ATTRIBUTE_TYPE_OFFSET; } 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_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); EXPECT(cases[i].overlapped == CheckEntries(e, h)); - EXPECT(cases[i].overlapped == MtdCheckEntries(me, mh)); } return TEST_OK; } @@ -1181,8 +1031,6 @@ static int EntryAttributeGetSetTest(void) { GptData *gpt = GetEmptyGptData(); GptEntry *e = (GptEntry *)(gpt->primary_entries); - MtdData *mtd = GetEmptyMtdData(); - MtdDiskPartition *m = &mtd->primary.partitions[0]; e->attrs.whole = 0x0000000000000000ULL; SetEntrySuccessful(e, 1); @@ -1193,15 +1041,6 @@ static int EntryAttributeGetSetTest(void) EXPECT(0xFEFFFFFFFFFFFFFFULL == e->attrs.whole); EXPECT(0 == GetEntrySuccessful(e)); - m->flags = 0; - MtdSetEntrySuccessful(m, 1); - EXPECT(0x00000100 == m->flags); - EXPECT(1 == MtdGetEntrySuccessful(m)); - m->flags = ~0; - MtdSetEntrySuccessful(m, 0); - EXPECT(0xFFFFFEFF == m->flags); - EXPECT(0 == MtdGetEntrySuccessful(m)); - e->attrs.whole = 0x0000000000000000ULL; SetEntryTries(e, 15); EXPECT(15 == GetEntryTries(e)); @@ -1211,15 +1050,6 @@ static int EntryAttributeGetSetTest(void) EXPECT(0xFF0FFFFFFFFFFFFFULL == e->attrs.whole); EXPECT(0 == GetEntryTries(e)); - m->flags = 0; - MtdSetEntryTries(m, 15); - EXPECT(0x000000F0 == m->flags); - EXPECT(15 == MtdGetEntryTries(m)); - m->flags = ~0; - MtdSetEntryTries(m, 0); - EXPECT(0xFFFFFF0F == m->flags); - EXPECT(0 == MtdGetEntryTries(m)); - e->attrs.whole = 0x0000000000000000ULL; SetEntryPriority(e, 15); EXPECT(0x000F000000000000ULL == e->attrs.whole); @@ -1229,15 +1059,6 @@ static int EntryAttributeGetSetTest(void) EXPECT(0xFFF0FFFFFFFFFFFFULL == e->attrs.whole); EXPECT(0 == GetEntryPriority(e)); - m->flags = 0; - MtdSetEntryPriority(m, 15); - EXPECT(0x0000000F == m->flags); - EXPECT(15 == MtdGetEntryPriority(m)); - m->flags = ~0; - MtdSetEntryPriority(m, 0); - EXPECT(0xFFFFFFF0 == m->flags); - EXPECT(0 == MtdGetEntryPriority(m)); - e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; EXPECT(1 == GetEntrySuccessful(e)); EXPECT(15 == GetEntryPriority(e)); @@ -1277,11 +1098,6 @@ static void FreeEntry(GptEntry *e) Memset(&e->type, 0, sizeof(Guid)); } -static void MtdFreeEntry(MtdDiskPartition *e) -{ - MtdSetEntryType(e, MTD_PARTITION_TYPE_UNUSED); -} - /* Set up an entry. */ static void FillEntry(GptEntry *e, int is_kernel, int priority, int successful, int tries) @@ -1292,16 +1108,6 @@ static void FillEntry(GptEntry *e, int is_kernel, SetEntryTries(e, tries); } -static void MtdFillEntry(MtdDiskPartition *e, int is_kernel, - int priority, int successful, int tries) -{ - MtdSetEntryType(e, is_kernel ? MTD_PARTITION_TYPE_CHROMEOS_KERNEL : - MTD_PARTITION_TYPE_CHROMEOS_FIRMWARE); - MtdSetEntryPriority(e, priority); - MtdSetEntrySuccessful(e, successful); - MtdSetEntryTries(e, tries); -} - /* * Invalidate all kernel entries and expect GptNextKernelEntry() cannot find * any usable kernel entry. @@ -1321,20 +1127,6 @@ static int NoValidKernelEntryTest(void) return TEST_OK; } -static int MtdNoValidKernelEntryTest(void) -{ - MtdData *mtd = GetEmptyMtdData(); - MtdDiskPartition *e1 = mtd->primary.partitions; - - BuildTestMtdData(mtd); - MtdSetEntryPriority(e1 + KERNEL_A, 0); - MtdFreeEntry(e1 + KERNEL_B); - EXPECT(GPT_ERROR_NO_VALID_KERNEL == - MtdNextKernelEntry(mtd, NULL, NULL)); - - return TEST_OK; -} - static int GetNextNormalTest(void) { GptData *gpt = GetEmptyGptData(); @@ -1422,169 +1214,6 @@ static int GetNextTriesTest(void) return TEST_OK; } -static int MtdGetNextNormalTest(void) -{ - MtdData *mtd = GetEmptyMtdData(); - MtdDiskPartition *e1 = mtd->primary.partitions; - uint64_t start, size; - - /* Normal case - both kernels successful */ - BuildTestMtdData(mtd); - MtdFillEntry(e1 + KERNEL_A, 1, 2, 1, 0); - MtdFillEntry(e1 + KERNEL_B, 1, 2, 1, 0); - mtd->primary.crc32 = MtdHeaderCrc(&mtd->primary); - MtdInit(mtd); - - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_A == mtd->current_kernel); - EXPECT(34 == start); - EXPECT(100 == size); - - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_B == mtd->current_kernel); - EXPECT(134 == start); - EXPECT(99 == size); - - EXPECT(GPT_ERROR_NO_VALID_KERNEL == - MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(-1 == mtd->current_kernel); - - /* Call as many times as you want; you won't get another kernel... */ - EXPECT(GPT_ERROR_NO_VALID_KERNEL == - MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(-1 == mtd->current_kernel); - - return TEST_OK; -} - -static int MtdGetNextPrioTest(void) -{ - MtdData *mtd = GetEmptyMtdData(); - MtdDiskPartition *e1 = mtd->primary.partitions; - uint64_t start, size; - - /* Priority 3, 4, 0, 4 - should boot order B, Y, A */ - BuildTestMtdData(mtd); - MtdFillEntry(e1 + KERNEL_A, 1, 3, 1, 0); - MtdFillEntry(e1 + KERNEL_B, 1, 4, 1, 0); - MtdFillEntry(e1 + KERNEL_X, 1, 0, 1, 0); - MtdFillEntry(e1 + KERNEL_Y, 1, 4, 1, 0); - mtd->primary.crc32 = MtdHeaderCrc(&mtd->primary); - MtdInit(mtd); - - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_B == mtd->current_kernel); - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_Y == mtd->current_kernel); - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_A == mtd->current_kernel); - EXPECT(GPT_ERROR_NO_VALID_KERNEL == - MtdNextKernelEntry(mtd, &start, &size)); - - return TEST_OK; -} - -static int MtdGetNextTriesTest(void) -{ - MtdData *mtd = GetEmptyMtdData(); - MtdDiskPartition *e1 = mtd->primary.partitions; - uint64_t start, size; - - /* Tries=nonzero is attempted just like success, but tries=0 isn't */ - BuildTestMtdData(mtd); - MtdFillEntry(e1 + KERNEL_A, 1, 2, 1, 0); - MtdFillEntry(e1 + KERNEL_B, 1, 3, 0, 0); - MtdFillEntry(e1 + KERNEL_X, 1, 4, 0, 1); - MtdFillEntry(e1 + KERNEL_Y, 1, 0, 0, 5); - mtd->primary.crc32 = MtdHeaderCrc(&mtd->primary); - MtdInit(mtd); - - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_X == mtd->current_kernel); - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_A == mtd->current_kernel); - EXPECT(GPT_ERROR_NO_VALID_KERNEL == - MtdNextKernelEntry(mtd, &start, &size)); - - return TEST_OK; -} - -static int MtdUpdateTest() { - MtdData *mtd = GetEmptyMtdData(); - MtdDiskPartition *e = &mtd->primary.partitions[0]; - uint64_t start, size; - - BuildTestMtdData(mtd); - - /* Tries=nonzero is attempted just like success, but tries=0 isn't */ - MtdFillEntry(e + KERNEL_A, 1, 4, 1, 0); - MtdFillEntry(e + KERNEL_B, 1, 3, 0, 2); - MtdFillEntry(e + KERNEL_X, 1, 2, 0, 2); - mtd->primary.crc32 = MtdHeaderCrc(&mtd->primary); - mtd->modified = 0; - EXPECT(GPT_SUCCESS == MtdInit(mtd)); - - /* Successful kernel */ - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_A == mtd->current_kernel); - EXPECT(1 == MtdGetEntrySuccessful(e + KERNEL_A)); - EXPECT(4 == MtdGetEntryPriority(e + KERNEL_A)); - EXPECT(0 == MtdGetEntryTries(e + KERNEL_A)); - /* Trying successful kernel changes nothing */ - EXPECT(GPT_SUCCESS == MtdUpdateKernelEntry(mtd, GPT_UPDATE_ENTRY_TRY)); - EXPECT(1 == MtdGetEntrySuccessful(e + KERNEL_A)); - EXPECT(4 == MtdGetEntryPriority(e + KERNEL_A)); - EXPECT(0 == MtdGetEntryTries(e + KERNEL_A)); - EXPECT(0 == mtd->modified); - /* Marking it bad also does not update it. */ - EXPECT(GPT_SUCCESS == MtdUpdateKernelEntry(mtd, GPT_UPDATE_ENTRY_BAD)); - EXPECT(1 == MtdGetEntrySuccessful(e + KERNEL_A)); - EXPECT(4 == MtdGetEntryPriority(e + KERNEL_A)); - EXPECT(0 == MtdGetEntryTries(e + KERNEL_A)); - EXPECT(0 == mtd->modified); - - /* Kernel with tries */ - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_B == mtd->current_kernel); - EXPECT(0 == MtdGetEntrySuccessful(e + KERNEL_B)); - EXPECT(3 == MtdGetEntryPriority(e + KERNEL_B)); - EXPECT(2 == MtdGetEntryTries(e + KERNEL_B)); - /* Marking it bad clears it */ - EXPECT(GPT_SUCCESS == MtdUpdateKernelEntry(mtd, GPT_UPDATE_ENTRY_BAD)); - EXPECT(0 == MtdGetEntrySuccessful(e + KERNEL_B)); - EXPECT(0 == MtdGetEntryPriority(e + KERNEL_B)); - EXPECT(0 == MtdGetEntryTries(e + KERNEL_B)); - /* And that's caused the mtd to need updating */ - EXPECT(1 == mtd->modified); - - /* Another kernel with tries */ - EXPECT(GPT_SUCCESS == MtdNextKernelEntry(mtd, &start, &size)); - EXPECT(KERNEL_X == mtd->current_kernel); - EXPECT(0 == MtdGetEntrySuccessful(e + KERNEL_X)); - EXPECT(2 == MtdGetEntryPriority(e + KERNEL_X)); - EXPECT(2 == MtdGetEntryTries(e + KERNEL_X)); - /* Trying it uses up a try */ - EXPECT(GPT_SUCCESS == MtdUpdateKernelEntry(mtd, GPT_UPDATE_ENTRY_TRY)); - EXPECT(0 == MtdGetEntrySuccessful(e + KERNEL_X)); - EXPECT(2 == MtdGetEntryPriority(e + KERNEL_X)); - EXPECT(1 == MtdGetEntryTries(e + KERNEL_X)); - /* Trying it again marks it inactive */ - EXPECT(GPT_SUCCESS == MtdUpdateKernelEntry(mtd, GPT_UPDATE_ENTRY_TRY)); - EXPECT(0 == MtdGetEntrySuccessful(e + KERNEL_X)); - EXPECT(0 == MtdGetEntryPriority(e + KERNEL_X)); - EXPECT(0 == MtdGetEntryTries(e + KERNEL_X)); - - /* Can't update if entry isn't a kernel, or there isn't an entry */ - MtdSetEntryType(e + KERNEL_X, MTD_PARTITION_TYPE_UNUSED); - EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == - MtdUpdateKernelEntry(mtd, GPT_UPDATE_ENTRY_BAD)); - mtd->current_kernel = CGPT_KERNEL_ENTRY_NOT_FOUND; - EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == - MtdUpdateKernelEntry(mtd, GPT_UPDATE_ENTRY_BAD)); - - return TEST_OK; -} - static int GptUpdateTest(void) { GptData *gpt = GetEmptyGptData(); @@ -1691,20 +1320,6 @@ static int UpdateInvalidKernelTypeTest(void) return TEST_OK; } -static int MtdUpdateInvalidKernelTypeTest(void) -{ - MtdData *mtd = GetEmptyMtdData(); - - BuildTestMtdData(mtd); - /* anything, but not CGPT_KERNEL_ENTRY_NOT_FOUND */ - mtd->current_kernel = 0; - /* any invalid update_type value */ - EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == - MtdUpdateKernelEntry(mtd, 99)); - - return TEST_OK; -} - /* Test duplicate UniqueGuids can be detected. */ static int DuplicateUniqueGuidTest(void) { @@ -1799,177 +1414,6 @@ static int ErrorTextTest(void) return TEST_OK; } -int nand_read_page(const nand_geom *nand, int page, void *buf, int size) { - uint32_t ofs = page * nand->szofpg; - uint32_t sz = size; - if (ofs + sz > nand_drive_sz) { - return -1; - } - Memcpy(buf, nand_drive + ofs, sz); - return 0; -} - -int nand_write_page(const nand_geom *nand, int page, - const void *buf, int size) { - uint32_t ofs = page * nand->szofpg; - uint32_t sz = size; - uint32_t i; - if (ofs + sz > nand_drive_sz) { - return -1; - } - for (i = 0; i < sz; i++) { - if (nand_drive[ofs + i] != 0xff) { - return -1; - } - } - Memcpy(nand_drive + ofs, buf, sz); - return 0; -} - -int nand_erase_block(const nand_geom *nand, int block) { - uint32_t ofs = block * nand->szofblk; - uint32_t sz = nand->szofblk; - if (ofs + sz > nand_drive_sz) { - return -1; - } - if (!--nand_bad_block_map[block]) { - return -1; - } - Memset(nand_drive + ofs, 0xFF, sz); - return 0; -} - -int nand_is_bad_block(const nand_geom *nand, int block) { - return nand_bad_block_map[block] == 0; -} - - -static void nand_make_ramdisk() { - if (nand_drive) { - free(nand_drive); - } - if (nand_bad_block_map) { - free(nand_bad_block_map); - } - nand_drive_sz = 1024 * 1024 * 16; - nand_drive = (uint8_t *)malloc(nand_drive_sz); - nand_bad_block_map = (uint8_t *)malloc(nand_drive_sz / 512); - Memset(nand_drive, 0xff, nand_drive_sz); - Memset(nand_bad_block_map, 0xff, nand_drive_sz / 512); -} - -static int MtdFtsTest() { - int MtdLoad(struct drive *drive, int sector_bytes); - int MtdSave(struct drive *drive); - int FlashGet(const char *key, uint8_t *data, uint32_t *bufsz); - int FlashSet(const char *key, const uint8_t *data, uint32_t bufsz); - - int i, j, err; - - struct { - int result; - unsigned int offset, size, block_size_bytes, page_size_bytes; - } cases[] = { - { 0, 1, 2, 1024 * 1024, 1024 * 4 }, - { 0, 1, 2, 1024 * 1024, 1024 * 16 }, - - /* Failure cases, non-power-of-2 */ - { -ENODEV, 1, 2, 5000000, 1024 * 16 }, - { -ENODEV, 1, 2, 1024 * 1024, 65535 }, - - /* Page > block */ - { -ENODEV, 1, 2, 1024 * 16, 1024 * 1024 }, - }; - - - /* Check if the FTS store works */ - for (i = 0; i < ARRAY_SIZE(cases); i++) { - nand_make_ramdisk(); - EXPECT(cases[i].result == flash_ts_init(cases[i].offset, cases[i].size, - cases[i].page_size_bytes, - cases[i].block_size_bytes, 512, 0)); - - if (cases[i].result == 0) { - /* We should have a working FTS store now */ - char buffer[64]; - uint8_t blob[256], blob_read[256]; - uint32_t sz = sizeof(blob_read); - struct drive drive; - - /* Test the low level API */ - EXPECT(0 == flash_ts_set("some_key", "some value")); - flash_ts_get("some_key", buffer, sizeof(buffer)); - EXPECT(0 == strcmp(buffer, "some value")); - - /* Check overwrite */ - EXPECT(0 == flash_ts_set("some_key", "some other value")); - flash_ts_get("some_key", buffer, sizeof(buffer)); - EXPECT(0 == strcmp(buffer, "some other value")); - - /* Check delete */ - EXPECT(0 == flash_ts_set("some_key", "")); - - /* Verify that re-initialization pulls the right record. */ - flash_ts_init(cases[i].offset, cases[i].size, cases[i].page_size_bytes, - cases[i].block_size_bytes, 512, 0); - flash_ts_get("some_key", buffer, sizeof(buffer)); - EXPECT(0 == strcmp(buffer, "")); - - /* Fill up the disk, eating all erase cycles */ - for (j = 0; j < nand_drive_sz / 512; j++) { - nand_bad_block_map[j] = 2; - } - for (j = 0; j < 999999; j++) { - char str[32]; - sprintf(str, "%d", j); - err = flash_ts_set("some_new_key", str); - if (err) { - EXPECT(err == -ENOMEM); - break; - } - - /* Make sure we can figure out where the latest is. */ - flash_ts_init(cases[i].offset, cases[i].size, cases[i].page_size_bytes, - cases[i].block_size_bytes, 512, 0); - flash_ts_get("some_new_key", buffer, sizeof(buffer)); - EXPECT(0 == strcmp(buffer, str)); - } - EXPECT(j < 999999); - - /* We need our drive back. */ - nand_make_ramdisk(); - flash_ts_init(cases[i].offset, cases[i].size, cases[i].page_size_bytes, - cases[i].block_size_bytes, 512, 0); - - - for (j = 0; j < 256; j++) { - blob[j] = j; - } - - /* Hex conversion / blob storage */ - EXPECT(0 == FlashSet("some_blob", blob, sizeof(blob))); - EXPECT(0 == FlashGet("some_blob", blob_read, &sz)); - EXPECT(sz == sizeof(blob_read)); - EXPECT(0 == Memcmp(blob, blob_read, sizeof(blob))); - - BuildTestMtdData(&drive.mtd); - drive.mtd.flash_block_bytes = cases[i].block_size_bytes; - drive.mtd.flash_page_bytes = cases[i].page_size_bytes; - drive.mtd.fts_block_offset = cases[i].offset; - drive.mtd.fts_block_size = cases[i].size; - drive.mtd.sector_bytes = 512; - drive.mtd.drive_sectors = nand_drive_sz / 512; - - /* MTD-level API */ - EXPECT(0 == MtdSave(&drive)); - Memset(&drive.mtd.primary, 0, sizeof(drive.mtd.primary)); - EXPECT(0 == MtdLoad(&drive, 512)); - } - } - - return TEST_OK; -} - static int CheckHeaderOffDevice() { GptData* gpt = GetEmptyGptData(); @@ -2039,7 +1483,6 @@ int main(int argc, char *argv[]) } test_cases[] = { { TEST_CASE(StructSizeTest), }, { TEST_CASE(TestBuildTestGptData), }, - { TEST_CASE(TestBuildTestMtdData), }, { TEST_CASE(ParameterTests), }, { TEST_CASE(HeaderCrcTest), }, { TEST_CASE(HeaderSameTest), }, @@ -2057,24 +1500,17 @@ int main(int argc, char *argv[]) { TEST_CASE(OverlappedPartitionTest), }, { TEST_CASE(SanityCheckTest), }, { TEST_CASE(NoValidKernelEntryTest), }, - { TEST_CASE(MtdNoValidKernelEntryTest), }, { TEST_CASE(EntryAttributeGetSetTest), }, { TEST_CASE(EntryTypeTest), }, { TEST_CASE(GetNextNormalTest), }, { TEST_CASE(GetNextPrioTest), }, { TEST_CASE(GetNextTriesTest), }, - { TEST_CASE(MtdGetNextNormalTest), }, - { TEST_CASE(MtdGetNextPrioTest), }, - { TEST_CASE(MtdGetNextTriesTest), }, { TEST_CASE(GptUpdateTest), }, - { TEST_CASE(MtdUpdateTest), }, { TEST_CASE(UpdateInvalidKernelTypeTest), }, - { TEST_CASE(MtdUpdateInvalidKernelTypeTest), }, { TEST_CASE(DuplicateUniqueGuidTest), }, { TEST_CASE(TestCrc32TestVectors), }, { TEST_CASE(GetKernelGuidTest), }, { TEST_CASE(ErrorTextTest), }, - { TEST_CASE(MtdFtsTest), }, { TEST_CASE(CheckHeaderOffDevice), }, }; |