summaryrefslogtreecommitdiff
path: root/utils/nwztools
diff options
context:
space:
mode:
Diffstat (limited to 'utils/nwztools')
-rw-r--r--utils/nwztools/emmctools/emmctool.c60
-rw-r--r--utils/nwztools/emmctools/nvp.c23
-rw-r--r--utils/nwztools/emmctools/nvp.h2
-rw-r--r--utils/nwztools/scsitools/scsitool.c3
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 @@
32#include "nvp.h" 32#include "nvp.h"
33 33
34bool g_debug = false; 34bool g_debug = false;
35char *g_out_prefix = NULL; 35static char *g_out_prefix = NULL;
36FILE *g_in_file = NULL; 36static FILE *g_in_file = NULL;
37bool g_force = false; 37bool g_force = false;
38static int g_nvp_node = -1;
38 39
39#define let_the_force_flow(x) do { if(!g_force) return x; } while(0) 40#define let_the_force_flow(x) do { if(!g_force) return x; } while(0)
40#define continue_the_force(x) if(x) let_the_force_flow(x) 41#define continue_the_force(x) if(x) let_the_force_flow(x)
@@ -164,15 +165,52 @@ static int do_emmc(void)
164 return 0; 165 return 0;
165} 166}
166 167
168static int do_nvp_extract(void)
169{
170 if(!g_out_prefix)
171 {
172 cprintf(GREY, "You must specify an output prefix to extract a NVP node\n");
173 return 1;
174 }
175 if(!nvp_is_valid_node(g_nvp_node))
176 {
177 cprintf(GREY, "Invalid NVP node %d\n", g_nvp_node);
178 return 3;
179 }
180
181 FILE *f = fopen(g_out_prefix, "wb");
182 if(!f)
183 {
184 cprintf(GREY, "Cannot open output file: %m\n");
185 return 2;
186 }
187
188 int size = nvp_get_node_size(g_nvp_node);
189 void *buffer = malloc(size);
190 int ret = nvp_read_node(g_nvp_node, 0, buffer, size);
191 if(ret < 0)
192 cprintf(GREY, "NVP read error: %d\n", ret);
193 else
194 {
195 cprintf(YELLOW, "%d ", ret);
196 cprintf(GREEN, "bytes written\n");
197 fwrite(buffer, 1, ret, f);
198 }
199 free(buffer);
200 fclose(f);
201 return 0;
202}
203
167static void usage(void) 204static void usage(void)
168{ 205{
169 printf("Usage: emmctool [options] img\n"); 206 printf("Usage: emmctool [options] img\n");
170 printf("Options:\n"); 207 printf("Options:\n");
171 printf(" -o <prefix>\tSet output prefix\n"); 208 printf(" -o <prefix>\t\tSet output prefix\n");
172 printf(" -f/--force\tForce to continue on errors\n"); 209 printf(" -f/--force\t\tForce to continue on errors\n");
173 printf(" -?/--help\tDisplay this message\n"); 210 printf(" -?/--help\t\tDisplay this message\n");
174 printf(" -d/--debug\tDisplay debug messages\n"); 211 printf(" -d/--debug\t\tDisplay debug messages\n");
175 printf(" -c/--no-color\tDisable color output\n"); 212 printf(" -c/--no-color\t\tDisable color output\n");
213 printf(" -e/--nvp-ex <node>\tExtract a NVP node\n");
176 exit(1); 214 exit(1);
177} 215}
178 216
@@ -186,10 +224,11 @@ int main(int argc, char **argv)
186 {"debug", no_argument, 0, 'd'}, 224 {"debug", no_argument, 0, 'd'},
187 {"no-color", no_argument, 0, 'c'}, 225 {"no-color", no_argument, 0, 'c'},
188 {"force", no_argument, 0, 'f'}, 226 {"force", no_argument, 0, 'f'},
227 {"nvp-ex", required_argument, 0, 'e'},
189 {0, 0, 0, 0} 228 {0, 0, 0, 0}
190 }; 229 };
191 230
192 int c = getopt_long(argc, argv, "?dcfo:", long_options, NULL); 231 int c = getopt_long(argc, argv, "?dcfo:e:", long_options, NULL);
193 if(c == -1) 232 if(c == -1)
194 break; 233 break;
195 switch(c) 234 switch(c)
@@ -211,6 +250,9 @@ int main(int argc, char **argv)
211 case 'o': 250 case 'o':
212 g_out_prefix = optarg; 251 g_out_prefix = optarg;
213 break; 252 break;
253 case 'e':
254 g_nvp_node = strtoul(optarg, NULL, 0);
255 break;
214 default: 256 default:
215 abort(); 257 abort();
216 } 258 }
@@ -232,6 +274,8 @@ int main(int argc, char **argv)
232 int ret = nvp_init(EMMC_NVP_SIZE, &nvp_read, g_debug); 274 int ret = nvp_init(EMMC_NVP_SIZE, &nvp_read, g_debug);
233 if(ret) return ret; 275 if(ret) return ret;
234 ret = do_emmc(); 276 ret = do_emmc();
277 if(ret == 0 && g_nvp_node >= 0)
278 ret = do_nvp_extract();
235 279
236 fclose(g_in_file); 280 fclose(g_in_file);
237 281
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
279{ 279{
280 int large = nvp_area_info[area].kind == NVP_AREA_LARGE_KIND; 280 int large = nvp_area_info[area].kind == NVP_AREA_LARGE_KIND;
281 int unit_size = large ? NVP_LARGE_AREA_SIZE : NVP_SMALL_AREA_SIZE; 281 int unit_size = large ? NVP_LARGE_AREA_SIZE : NVP_SMALL_AREA_SIZE;
282 int read_size = 0;
282 283
283 while(size > 0) 284 while(size > 0)
284 { 285 {
@@ -288,17 +289,23 @@ int nvp_read_data(int shadow, int area, int zone, int offset, void *buf, int siz
288 nvp_get_cluster_number(shadow, area, zone, index) : 289 nvp_get_cluster_number(shadow, area, zone, index) :
289 nvp_get_sector_number(shadow, area, zone, index); 290 nvp_get_sector_number(shadow, area, zone, index);
290 if(sec_cluster == 0) 291 if(sec_cluster == 0)
291 return -1; 292 break;
292 //cprintf(GREY, "[sec_cluster=%d]", sec_cluster);
293 int read = MIN(size, unit_size - unit_offset); 293 int read = MIN(size, unit_size - unit_offset);
294 //cprintf(GREY, "[sec_cluster=%d read=%d]", sec_cluster, read);
294 int ret = nvp_read(sec_cluster * unit_size, read, buf); 295 int ret = nvp_read(sec_cluster * unit_size, read, buf);
295 if(ret) 296 if(ret)
296 return ret; 297 return ret;
297 buf += read; 298 buf += read;
298 offset += read; 299 offset += read;
299 size -= read; 300 size -= read;
301 read_size += read;
300 } 302 }
301 return 0; 303 return read_size;
304}
305
306bool nvp_is_valid_node(int node)
307{
308 return node >= 0 && node < nr_nodes && node_info[node].area != -1;
302} 309}
303 310
304struct nvp_node_info_t nvp_get_node_info(int node) 311struct nvp_node_info_t nvp_get_node_info(int node)
@@ -527,16 +534,18 @@ int nvp_info(void)
527 cprintf_field(" Zone ", "%s", zones[j].name); 534 cprintf_field(" Zone ", "%s", zones[j].name);
528 cprintf(BLUE, " ->"); 535 cprintf(BLUE, " ->");
529 uint8_t buf[0x20]; 536 uint8_t buf[0x20];
530 int ret = nvp_read_data(0, i, j, 0, buf, MIN(0x20, zones[j].size)); 537 int sz = 0x20;
531 if(ret) 538 int ret = nvp_read_data(0, i, j, 0, buf, MIN(sz, zones[j].size));
539 if(ret <= 0)
532 { 540 {
533 cprintf(RED, " No data\n"); 541 cprintf(RED, " No data\n");
534 continue; 542 continue;
535 } 543 }
536 for(int i = 0; i < MIN(0x20, zones[j].size); i++) 544 sz = MIN(sz, ret);
545 for(int i = 0; i < MIN(sz, zones[j].size); i++)
537 cprintf(YELLOW, " %02x", buf[i]); 546 cprintf(YELLOW, " %02x", buf[i]);
538 cprintf(BLUE, " -> "); 547 cprintf(BLUE, " -> ");
539 for(int i = 0; i < MIN(0x20, zones[j].size); i++) 548 for(int i = 0; i < MIN(sz, zones[j].size); i++)
540 cprintf(YELLOW, "%c", isprint(buf[i]) ? buf[i] : '.'); 549 cprintf(YELLOW, "%c", isprint(buf[i]) ? buf[i] : '.');
541 printf("\n"); 550 printf("\n");
542 } 551 }
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];
74typedef int (*nvp_read_fn_t)(uint32_t offset, uint32_t size, void *buf); 74typedef int (*nvp_read_fn_t)(uint32_t offset, uint32_t size, void *buf);
75 75
76int nvp_init(int nvp_size, nvp_read_fn_t read, bool debug); 76int nvp_init(int nvp_size, nvp_read_fn_t read, bool debug);
77bool nvp_is_valid_node(int node);
77struct nvp_node_info_t nvp_get_node_info(int node); 78struct nvp_node_info_t nvp_get_node_info(int node);
78int nvp_get_node_size(int node); 79int nvp_get_node_size(int node);
79const char *nvp_get_node_name(int node); 80const char *nvp_get_node_name(int node);
@@ -88,6 +89,7 @@ int nvp_get_sector_status(int sector);
88int nvp_set_sector_status(int sector, int status); 89int nvp_set_sector_status(int sector, int status);
89int nvp_get_cluster_number(int shadow, int area, int zone, int index); 90int nvp_get_cluster_number(int shadow, int area, int zone, int index);
90int nvp_get_sector_number(int shadow, int area, int zone, int index); 91int nvp_get_sector_number(int shadow, int area, int zone, int index);
92/* returns amount of read data or -1 */
91int nvp_read_data(int shadow, int area, int zone, int offset, void *buffer, int size); 93int nvp_read_data(int shadow, int area, int zone, int offset, void *buffer, int size);
92 94
93#endif /* __NVP_H__ */ 95#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)
393 printf("Node usage: <node>\n"); 393 printf("Node usage: <node>\n");
394 printf("Nodes:\n"); 394 printf("Nodes:\n");
395 for(unsigned i = 0; i < NR_NVP_PROPS; i++) 395 for(unsigned i = 0; i < NR_NVP_PROPS; i++)
396 printf(" %s\t%s", nvp_prop_list[i].name, nvp_prop_list[i].desc); 396 printf(" %s\t%s\n", nvp_prop_list[i].name, nvp_prop_list[i].desc);
397 printf("\n");
398 return 1; 397 return 1;
399 } 398 }
400 399