diff options
-rw-r--r-- | cgpt/cgpt.c | 56 | ||||
-rw-r--r-- | cgpt/cgpt.h | 5 | ||||
-rw-r--r-- | cgpt/cgpt_common.c | 10 |
3 files changed, 70 insertions, 1 deletions
diff --git a/cgpt/cgpt.c b/cgpt/cgpt.c index a3b20d99..2851f7c5 100644 --- a/cgpt/cgpt.c +++ b/cgpt/cgpt.c @@ -18,6 +18,8 @@ const char* progname; const char* command; void (*uuid_generator)(uint8_t* buffer); +extern struct nand_layout nand; + struct { const char *name; int (*fp)(int argc, char *argv[]); @@ -47,7 +49,40 @@ 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) { + if ('=' != arg[0]) + return -1; + + arg++; + nand.bytes_per_page = atoi(arg); + arg = strchr(arg, ','); + if (!arg) + return -1; + + arg++; + nand.pages_per_block = atoi(arg); + arg = strchr(arg, ','); + if (!arg) + return -1; + + arg++; + nand.fts_block_offset = atoi(arg); + arg = strchr(arg, ','); + if (!arg) + return -1; + + arg++; + nand.fts_block_size = atoi(arg); + if (nand.fts_block_size == 0 || !is_pow2(nand.pages_per_block) || + !is_pow2(nand.bytes_per_page) || nand.bytes_per_page < 512) { + return -1; + } + return 0; +} int main(int argc, char *argv[]) { int i; @@ -62,6 +97,27 @@ int main(int argc, char *argv[]) { else progname = argv[0]; + + memset(&nand, 0, sizeof(nand)); + for (i = 1; i < argc; ++i) { + if (0 == strncmp(argv[i], "-N", 2)) { + if (!parse_nand_option(argv[i] + 2)) { + int j; + nand.enabled = 1; + + // 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 3cd6e8db..f6580868 100644 --- a/cgpt/cgpt.h +++ b/cgpt/cgpt.h @@ -52,6 +52,11 @@ struct drive { struct pmbr pmbr; }; +struct nand_layout { + int enabled; + int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size; +}; + /* mode should be O_RDONLY or O_RDWR */ int DriveOpen(const char *drive_path, struct drive *drive, int mode); diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 3d2fe3ba..dd8e510d 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -26,6 +26,10 @@ #include "flash_ts.h" #include "vboot_host.h" +struct nand_layout nand = { + 0, 0, 0, 0, 0 +}; + void Error(const char *format, ...) { va_list ap; va_start(ap, format); @@ -339,7 +343,7 @@ int GptSave(struct drive *drive) { int DriveOpen(const char *drive_path, struct drive *drive, int mode) { struct stat stat; uint32_t sector_bytes; - int is_mtd = 0; + int is_mtd = nand.enabled; require(drive_path); require(drive); @@ -374,6 +378,10 @@ int DriveOpen(const char *drive_path, struct drive *drive, int mode) { } 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; } |