From 99f20b85f6856fa636e41c6987e34bf343a235ae Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sat, 3 Nov 2012 14:04:27 +0100 Subject: [PATCH] nwztools: various fix and enhancements Change-Id: Iaa89df27b7a0c4eb9fc6603c431de3d1fe791fa1 --- utils/nwztools/emmctools/emmctool.c | 60 ++++++++++++++++++++++++++++++++----- utils/nwztools/emmctools/nvp.c | 23 +++++++++----- utils/nwztools/emmctools/nvp.h | 2 ++ utils/nwztools/scsitools/scsitool.c | 3 +- 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/utils/nwztools/emmctools/emmctool.c b/utils/nwztools/emmctools/emmctool.c index 8fa7b0907b..26226b6f07 100644 --- a/utils/nwztools/emmctools/emmctool.c +++ b/utils/nwztools/emmctools/emmctool.c @@ -32,9 +32,10 @@ #include "nvp.h" bool g_debug = false; -char *g_out_prefix = NULL; -FILE *g_in_file = NULL; +static char *g_out_prefix = NULL; +static FILE *g_in_file = NULL; bool g_force = false; +static int g_nvp_node = -1; #define let_the_force_flow(x) do { if(!g_force) return x; } while(0) #define continue_the_force(x) if(x) let_the_force_flow(x) @@ -164,15 +165,52 @@ static int do_emmc(void) return 0; } +static int do_nvp_extract(void) +{ + if(!g_out_prefix) + { + cprintf(GREY, "You must specify an output prefix to extract a NVP node\n"); + return 1; + } + if(!nvp_is_valid_node(g_nvp_node)) + { + cprintf(GREY, "Invalid NVP node %d\n", g_nvp_node); + return 3; + } + + FILE *f = fopen(g_out_prefix, "wb"); + if(!f) + { + cprintf(GREY, "Cannot open output file: %m\n"); + return 2; + } + + int size = nvp_get_node_size(g_nvp_node); + void *buffer = malloc(size); + int ret = nvp_read_node(g_nvp_node, 0, buffer, size); + if(ret < 0) + cprintf(GREY, "NVP read error: %d\n", ret); + else + { + cprintf(YELLOW, "%d ", ret); + cprintf(GREEN, "bytes written\n"); + fwrite(buffer, 1, ret, f); + } + free(buffer); + fclose(f); + return 0; +} + static void usage(void) { printf("Usage: emmctool [options] img\n"); printf("Options:\n"); - printf(" -o \tSet output prefix\n"); - printf(" -f/--force\tForce to continue on errors\n"); - printf(" -?/--help\tDisplay this message\n"); - printf(" -d/--debug\tDisplay debug messages\n"); - printf(" -c/--no-color\tDisable color output\n"); + printf(" -o \t\tSet output prefix\n"); + printf(" -f/--force\t\tForce to continue on errors\n"); + printf(" -?/--help\t\tDisplay this message\n"); + printf(" -d/--debug\t\tDisplay debug messages\n"); + printf(" -c/--no-color\t\tDisable color output\n"); + printf(" -e/--nvp-ex \tExtract a NVP node\n"); exit(1); } @@ -186,10 +224,11 @@ int main(int argc, char **argv) {"debug", no_argument, 0, 'd'}, {"no-color", no_argument, 0, 'c'}, {"force", no_argument, 0, 'f'}, + {"nvp-ex", required_argument, 0, 'e'}, {0, 0, 0, 0} }; - int c = getopt_long(argc, argv, "?dcfo:", long_options, NULL); + int c = getopt_long(argc, argv, "?dcfo:e:", long_options, NULL); if(c == -1) break; switch(c) @@ -211,6 +250,9 @@ int main(int argc, char **argv) case 'o': g_out_prefix = optarg; break; + case 'e': + g_nvp_node = strtoul(optarg, NULL, 0); + break; default: abort(); } @@ -232,6 +274,8 @@ int main(int argc, char **argv) int ret = nvp_init(EMMC_NVP_SIZE, &nvp_read, g_debug); if(ret) return ret; ret = do_emmc(); + if(ret == 0 && g_nvp_node >= 0) + ret = do_nvp_extract(); fclose(g_in_file); diff --git a/utils/nwztools/emmctools/nvp.c b/utils/nwztools/emmctools/nvp.c index 46515f74db..3adf61f621 100644 --- a/utils/nwztools/emmctools/nvp.c +++ b/utils/nwztools/emmctools/nvp.c @@ -279,6 +279,7 @@ int nvp_read_data(int shadow, int area, int zone, int offset, void *buf, int siz { int large = nvp_area_info[area].kind == NVP_AREA_LARGE_KIND; int unit_size = large ? NVP_LARGE_AREA_SIZE : NVP_SMALL_AREA_SIZE; + int read_size = 0; while(size > 0) { @@ -288,17 +289,23 @@ int nvp_read_data(int shadow, int area, int zone, int offset, void *buf, int siz nvp_get_cluster_number(shadow, area, zone, index) : nvp_get_sector_number(shadow, area, zone, index); if(sec_cluster == 0) - return -1; - //cprintf(GREY, "[sec_cluster=%d]", sec_cluster); + break; int read = MIN(size, unit_size - unit_offset); + //cprintf(GREY, "[sec_cluster=%d read=%d]", sec_cluster, read); int ret = nvp_read(sec_cluster * unit_size, read, buf); if(ret) return ret; buf += read; offset += read; size -= read; + read_size += read; } - return 0; + return read_size; +} + +bool nvp_is_valid_node(int node) +{ + return node >= 0 && node < nr_nodes && node_info[node].area != -1; } struct nvp_node_info_t nvp_get_node_info(int node) @@ -527,16 +534,18 @@ int nvp_info(void) cprintf_field(" Zone ", "%s", zones[j].name); cprintf(BLUE, " ->"); uint8_t buf[0x20]; - int ret = nvp_read_data(0, i, j, 0, buf, MIN(0x20, zones[j].size)); - if(ret) + int sz = 0x20; + int ret = nvp_read_data(0, i, j, 0, buf, MIN(sz, zones[j].size)); + if(ret <= 0) { cprintf(RED, " No data\n"); continue; } - for(int i = 0; i < MIN(0x20, zones[j].size); i++) + sz = MIN(sz, ret); + for(int i = 0; i < MIN(sz, zones[j].size); i++) cprintf(YELLOW, " %02x", buf[i]); cprintf(BLUE, " -> "); - for(int i = 0; i < MIN(0x20, zones[j].size); i++) + for(int i = 0; i < MIN(sz, zones[j].size); i++) cprintf(YELLOW, "%c", isprint(buf[i]) ? buf[i] : '.'); printf("\n"); } diff --git a/utils/nwztools/emmctools/nvp.h b/utils/nwztools/emmctools/nvp.h index 1eff36c19e..c24d0a6375 100644 --- a/utils/nwztools/emmctools/nvp.h +++ b/utils/nwztools/emmctools/nvp.h @@ -74,6 +74,7 @@ extern struct nvp_area_info_entry_t nvp_area_info[NVP_NR_AREAS]; typedef int (*nvp_read_fn_t)(uint32_t offset, uint32_t size, void *buf); int nvp_init(int nvp_size, nvp_read_fn_t read, bool debug); +bool nvp_is_valid_node(int node); struct nvp_node_info_t nvp_get_node_info(int node); int nvp_get_node_size(int node); const char *nvp_get_node_name(int node); @@ -88,6 +89,7 @@ int nvp_get_sector_status(int sector); int nvp_set_sector_status(int sector, int status); int nvp_get_cluster_number(int shadow, int area, int zone, int index); int nvp_get_sector_number(int shadow, int area, int zone, int index); +/* returns amount of read data or -1 */ int nvp_read_data(int shadow, int area, int zone, int offset, void *buffer, int size); #endif /* __NVP_H__ */ diff --git a/utils/nwztools/scsitools/scsitool.c b/utils/nwztools/scsitools/scsitool.c index 97ecee4370..69e3ac8af1 100644 --- a/utils/nwztools/scsitools/scsitool.c +++ b/utils/nwztools/scsitools/scsitool.c @@ -393,8 +393,7 @@ int get_dnk_nvp(int argc, char **argv) printf("Node usage: \n"); printf("Nodes:\n"); for(unsigned i = 0; i < NR_NVP_PROPS; i++) - printf(" %s\t%s", nvp_prop_list[i].name, nvp_prop_list[i].desc); - printf("\n"); + printf(" %s\t%s\n", nvp_prop_list[i].name, nvp_prop_list[i].desc); return 1; } -- 2.11.4.GIT