From 78c8afa5c23f08ff55d43abd340078f65e57f0da Mon Sep 17 00:00:00 2001 From: Evan Lojewski Date: Sat, 8 Sep 2018 23:06:55 +0000 Subject: [PATCH] Add support for file-backed flash emulation. When the --file or -i option is passed in from the command line, use the passed in file as the backing flash device. In this mode, replace all ioctl calls with pwrite calls instead. In this mode, we also assume that the erase size is 4KB. Note: This mode does *not* emulate writes as we can write to non-erased flash areas without issues. To properly emulate writes, a read-and-write sequence would be needed. This code has been tested with a PNOR with invaslid ECC in thee CVPD. The firmware is able to properly erase and write to the CVPD. Signed-off-by: Evan Lojewski --- mbox.h | 2 ++ mboxd.c | 18 ++++++++++-- mboxd_flash_physical.c | 78 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/mbox.h b/mbox.h index e9e7c75..14a6807 100644 --- a/mbox.h +++ b/mbox.h @@ -151,6 +151,8 @@ struct mbox_context { bool current_is_write; /* Memory & Flash State */ + /* Backing file */ + const char* filename; /* Reserved Memory Region */ void *mem; /* Reserved Mem Size (bytes) */ diff --git a/mboxd.c b/mboxd.c index 6e95b56..1c2e857 100644 --- a/mboxd.c +++ b/mboxd.c @@ -57,14 +57,16 @@ "\nUsage: %s [-V | --version] [-h | --help] [-v[v] | --verbose] [-s | --syslog]\n" \ "\t\t[-n | --window-num ]\n" \ "\t\t[-w | --window-size M]\n" \ -"\t\t-f | --flash [K|M]\n\n" \ +"\t\t-f | --flash [K|M]\n" \ +"\t\t-i | --file \n\n" \ "\t-v | --verbose\t\tBe [more] verbose\n" \ "\t-s | --syslog\t\tLog output to syslog (pointless without -v)\n" \ "\t-n | --window-num\tThe number of windows\n" \ "\t\t\t\t(default: fill the reserved memory region)\n" \ "\t-w | --window-size\tThe window size (power of 2) in MB\n" \ "\t\t\t\t(default: 1MB)\n" \ -"\t-f | --flash\t\tSize of flash in [K|M] bytes\n\n" +"\t-f | --flash\t\tSize of flash in [K|M] bytes\n" \ +"\t-i | --file\t\tEmulate the flash device with the specified file\n\n" static int poll_loop(struct mbox_context *context) { @@ -191,6 +193,7 @@ static bool parse_cmdline(int argc, char **argv, static const struct option long_options[] = { { "flash", required_argument, 0, 'f' }, + { "file", required_argument, 0, 'i' }, { "window-size", optional_argument, 0, 'w' }, { "window-num", optional_argument, 0, 'n' }, { "verbose", no_argument, 0, 'v' }, @@ -205,7 +208,7 @@ static bool parse_cmdline(int argc, char **argv, context->current = NULL; /* No current window */ - while ((opt = getopt_long(argc, argv, "f:w::n::vsVh", long_options, NULL)) + while ((opt = getopt_long(argc, argv, "f:i:w::n::vsVh", long_options, NULL)) != -1) { switch (opt) { case 0: @@ -230,6 +233,9 @@ static bool parse_cmdline(int argc, char **argv, return false; } break; + case 'i': + context->filename = strdup(optarg); + break; case 'n': context->windows.num = strtol(argv[optind], &endptr, 10); @@ -278,6 +284,9 @@ static bool parse_cmdline(int argc, char **argv, } MSG_INFO("Flash size: 0x%.8x\n", context->flash_size); + if (context->filename) { + MSG_INFO("Backing file: %s\n", context->filename); + } if (verbosity) { MSG_INFO("%s logging\n", verbosity == MBOX_LOG_DEBUG ? "Debug" : @@ -375,6 +384,9 @@ finish: #ifdef VIRTUAL_PNOR_ENABLED destroy_vpnor(context); #endif + if(context->filename) { + free((void*)context->filename); + } free(context); return rc; diff --git a/mboxd_flash_physical.c b/mboxd_flash_physical.c index 69d2f3c..9b68d02 100644 --- a/mboxd_flash_physical.c +++ b/mboxd_flash_physical.c @@ -48,8 +48,15 @@ int init_flash_dev(struct mbox_context *context) { - char *filename = get_dev_mtd(); + const char *filename = context->filename; int fd, rc = 0; + int mtd = 0; + + if(!filename) + { + filename = get_dev_mtd(); + mtd = 1; + } if (!filename) { MSG_ERR("Couldn't find the PNOR /dev/mtd partition\n"); @@ -69,11 +76,20 @@ int init_flash_dev(struct mbox_context *context) context->fds[MTD_FD].fd = fd; /* Read the Flash Info */ - if (ioctl(fd, MEMGETINFO, &context->mtd_info) == -1) { - MSG_ERR("Couldn't get information about MTD: %s\n", - strerror(errno)); - rc = -1; - goto out; + if (mtd) + { + if (ioctl(fd, MEMGETINFO, &context->mtd_info) == -1) { + MSG_ERR("Couldn't get information about MTD: %s\n", + strerror(errno)); + rc = -1; + goto out; + } + } + else + { + context->mtd_info.size = context->flash_size; + /* Assume a 4K sector size. */ + context->mtd_info.erasesize = 4 * 1024; } if (context->flash_size == 0) { @@ -109,7 +125,9 @@ int init_flash_dev(struct mbox_context *context) MSG_DBG("Flash erase size: 0x%.8x\n", context->mtd_info.erasesize); out: - free(filename); + if (mtd) { + free((void*)filename); + } return rc; } @@ -197,8 +215,27 @@ int erase_flash(struct mbox_context *context, uint32_t offset, uint32_t count) /* Erase the previous run which just ended */ MSG_DBG("Erase flash @ 0x%.8x for 0x%.8x\n", erase_info.start, erase_info.length); - rc = ioctl(context->fds[MTD_FD].fd, MEMERASE, - &erase_info); + + + if(!context->filename) + { + /* MTD Device */ + rc = ioctl(context->fds[MTD_FD].fd, MEMERASE, + &erase_info); + } + else + { + uint8_t* erase_buf = (uint8_t*)malloc(erase_size); + if (!erase_buf) { + MSG_ERR("Couldn't malloc erase buffer. %s\n", strerror(errno)); + return -MBOX_R_SYSTEM_ERROR; + } + + memset(erase_buf, 0xFF, erase_size); + rc = pwrite(context->fds[MTD_FD].fd, erase_buf, erase_info.length, erase_info.start); + free(erase_buf); + } + if (rc < 0) { MSG_ERR("Couldn't erase flash at 0x%.8x\n", erase_info.start); @@ -218,7 +255,28 @@ int erase_flash(struct mbox_context *context, uint32_t offset, uint32_t count) if (erase_info.length) { MSG_DBG("Erase flash @ 0x%.8x for 0x%.8x\n", erase_info.start, erase_info.length); - rc = ioctl(context->fds[MTD_FD].fd, MEMERASE, &erase_info); + + + if(!context->filename) + { + /* MTD Device */ + rc = ioctl(context->fds[MTD_FD].fd, MEMERASE, + &erase_info); + } + else + { + uint8_t* erase_buf = (uint8_t*)malloc(erase_size); + if (!erase_buf) { + MSG_ERR("Couldn't malloc erase buffer. %s\n", strerror(errno)); + return -MBOX_R_SYSTEM_ERROR; + } + + memset(erase_buf, 0xFF, erase_size); + rc = pwrite(context->fds[MTD_FD].fd, erase_buf, erase_info.length, erase_info.start); + free(erase_buf); + } + + if (rc < 0) { MSG_ERR("Couldn't erase flash at 0x%.8x\n", erase_info.start); -- 2.11.0