summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Chaulk <achaulk@chromium.org>2013-03-29 15:02:38 -0700
committerChromeBot <chrome-bot@google.com>2013-04-02 14:13:40 -0700
commit84714a1e8d496b627dbb780c38fb216b9fbd5be6 (patch)
treefd385d52175c8363dca359c7a2e6c9e66bf498f3
parent99676e9e445d17dd3dbe6fa80e35d7b0c58edfe1 (diff)
downloadvboot-84714a1e8d496b627dbb780c38fb216b9fbd5be6.tar.gz
Enables MTD mode via command line option.
Enables MTD mode with a command line option of -N=<write page bytes>,<write pages per erase block>, <erase block offset to fts partition>,<erase block size of fts partition> The problem is that we need to know exactly where the fts store partition is and what the layout of the flash chip is in order to be able to use it properly. This will vary per-device however, so for flexibility and testing purposes, this command line option allows specification of arbitrary layouts. BUG=chromium:221745 BRANCH=cros/embedded TEST=verified during development via prints Change-Id: I88640e777d5ccd4ffd3b39e1f131dc1d362c6b2c Reviewed-on: https://gerrit.chromium.org/gerrit/46920 Commit-Queue: Albert Chaulk <achaulk@chromium.org> Reviewed-by: Albert Chaulk <achaulk@chromium.org> Tested-by: Albert Chaulk <achaulk@chromium.org>
-rw-r--r--cgpt/cgpt.c56
-rw-r--r--cgpt/cgpt.h5
-rw-r--r--cgpt/cgpt_common.c10
3 files changed, 70 insertions, 1 deletions
diff --git a/cgpt/cgpt.c b/cgpt/cgpt.c
index ac7aecdd..0c76df0e 100644
--- a/cgpt/cgpt.c
+++ b/cgpt/cgpt.c
@@ -17,6 +17,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[]);
@@ -46,7 +48,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;
@@ -61,6 +96,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 bed5f5f9..3ac7e744 100644
--- a/cgpt/cgpt.h
+++ b/cgpt/cgpt.h
@@ -64,6 +64,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 73c4f19a..24cfdff6 100644
--- a/cgpt/cgpt_common.c
+++ b/cgpt/cgpt_common.c
@@ -26,6 +26,10 @@
#include "crc32.h"
#include "flash_ts.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;
}