diff options
Diffstat (limited to 'utils/rknanoutils/rkboottool/rkboottool.c')
-rw-r--r-- | utils/rknanoutils/rkboottool/rkboottool.c | 123 |
1 files changed, 101 insertions, 22 deletions
diff --git a/utils/rknanoutils/rkboottool/rkboottool.c b/utils/rknanoutils/rkboottool/rkboottool.c index f913b12377..06763f86e3 100644 --- a/utils/rknanoutils/rkboottool/rkboottool.c +++ b/utils/rknanoutils/rkboottool/rkboottool.c | |||
@@ -4,7 +4,9 @@ | |||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <string.h> | 5 | #include <string.h> |
6 | #include <getopt.h> | 6 | #include <getopt.h> |
7 | #include <stdarg.h> | ||
7 | #include "misc.h" | 8 | #include "misc.h" |
9 | #include "elf.h" | ||
8 | 10 | ||
9 | #define cprintf(col, ...) do {color(col); printf(__VA_ARGS__); }while(0) | 11 | #define cprintf(col, ...) do {color(col); printf(__VA_ARGS__); }while(0) |
10 | 12 | ||
@@ -150,7 +152,10 @@ static void save_blob(const struct rknano_blob_t *b, void *buf, uint32_t size, | |||
150 | if(g_out_prefix == NULL || b->size == 0 || b->offset + b->size > size) | 152 | if(g_out_prefix == NULL || b->size == 0 || b->offset + b->size > size) |
151 | return; | 153 | return; |
152 | char *path = malloc(strlen(g_out_prefix) + strlen(name) + 32); | 154 | char *path = malloc(strlen(g_out_prefix) + strlen(name) + 32); |
153 | sprintf(path, "%s%s%d.bin", g_out_prefix, name, suffix); | 155 | if(suffix >= 0) |
156 | sprintf(path, "%s%s%d.bin", g_out_prefix, name, suffix); | ||
157 | else | ||
158 | sprintf(path, "%s%s.bin", g_out_prefix, name); | ||
154 | FILE *f = fopen(path, "wb"); | 159 | FILE *f = fopen(path, "wb"); |
155 | uint8_t *ptr = buf + b->offset; | 160 | uint8_t *ptr = buf + b->offset; |
156 | if(enc_mode != NO_ENC) | 161 | if(enc_mode != NO_ENC) |
@@ -274,57 +279,131 @@ static int do_nanofw_image(uint8_t *buf, unsigned long size) | |||
274 | struct rknano_stage_header_t | 279 | struct rknano_stage_header_t |
275 | { | 280 | { |
276 | uint32_t addr; | 281 | uint32_t addr; |
282 | uint32_t count; | ||
277 | } __attribute__((packed)); | 283 | } __attribute__((packed)); |
278 | 284 | ||
285 | /* | ||
286 | * The [code_pa,code_pa+code_sz[ and [data_pa,data_pa+data_sz[ ranges | ||
287 | * are consitent: they never overlap and have no gaps and fill the | ||
288 | * entire space. Furthermore they match the code sequences so it's | ||
289 | * reasonable to assume these fields are correct. | ||
290 | * The other fields are still quite unsure. */ | ||
291 | |||
279 | struct rknano_stage_section_t | 292 | struct rknano_stage_section_t |
280 | { | 293 | { |
281 | uint32_t a; | ||
282 | uint32_t code_pa; | 294 | uint32_t code_pa; |
283 | uint32_t code_va; | 295 | uint32_t code_va; |
284 | uint32_t code_sz; | 296 | uint32_t code_sz; |
285 | uint32_t data_pa; | 297 | uint32_t data_pa; |
286 | uint32_t data_va; | 298 | uint32_t data_va; |
287 | uint32_t data_sz; | 299 | uint32_t data_sz; |
288 | uint32_t bss_end_va; | 300 | uint32_t bss_va; |
301 | uint32_t bss_sz; | ||
289 | } __attribute__((packed)); | 302 | } __attribute__((packed)); |
290 | 303 | ||
304 | static void elf_printf(void *user, bool error, const char *fmt, ...) | ||
305 | { | ||
306 | if(!g_debug && !error) | ||
307 | return; | ||
308 | (void) user; | ||
309 | va_list args; | ||
310 | va_start(args, fmt); | ||
311 | vprintf(fmt, args); | ||
312 | va_end(args); | ||
313 | } | ||
314 | |||
315 | static void elf_write(void *user, uint32_t addr, const void *buf, size_t count) | ||
316 | { | ||
317 | FILE *f = user; | ||
318 | fseek(f, addr, SEEK_SET); | ||
319 | fwrite(buf, count, 1, f); | ||
320 | } | ||
321 | |||
322 | static void extract_elf_section(struct elf_params_t *elf, int count) | ||
323 | { | ||
324 | char *filename = xmalloc(strlen(g_out_prefix) + 32); | ||
325 | sprintf(filename, "%s%d.elf", g_out_prefix, count); | ||
326 | if(g_debug) | ||
327 | printf("Write entry %d to %s\n", count, filename); | ||
328 | |||
329 | FILE *fd = fopen(filename, "wb"); | ||
330 | free(filename); | ||
331 | |||
332 | if(fd == NULL) | ||
333 | return ; | ||
334 | elf_write_file(elf, elf_write, elf_printf, fd); | ||
335 | fclose(fd); | ||
336 | } | ||
337 | |||
291 | static int do_nanostage_image(uint8_t *buf, unsigned long size) | 338 | static int do_nanostage_image(uint8_t *buf, unsigned long size) |
292 | { | 339 | { |
293 | if(size < sizeof(struct rknano_stage_section_t)) | 340 | if(size < sizeof(struct rknano_stage_section_t)) |
294 | return 1; | 341 | return 1; |
295 | struct rknano_stage_header_t *hdr = (void *)buf; | 342 | struct rknano_stage_header_t *hdr = (void *)buf; |
296 | 343 | ||
344 | uint32_t *buf32 = (void *)buf; | ||
345 | cprintf(BLUE, "Dump\n"); | ||
346 | for(int j = 0; j < 2; j++) | ||
347 | cprintf(YELLOW, "%8x ", buf32[j]); | ||
348 | printf("\n"); | ||
349 | for(unsigned i = 0; i < hdr->count; i++) | ||
350 | { | ||
351 | for(int j = 0; j < 8; j++) | ||
352 | cprintf(YELLOW, "%8x ", buf32[i * 8 + j + 2]); | ||
353 | printf("\n"); | ||
354 | } | ||
355 | printf("\n"); | ||
356 | |||
297 | cprintf(BLUE, "Header\n"); | 357 | cprintf(BLUE, "Header\n"); |
298 | cprintf(GREEN, " Base Address: "); | 358 | cprintf(GREEN, " Base Address: "); |
299 | cprintf(YELLOW, "%#x\n", hdr->addr); | 359 | cprintf(YELLOW, "%#08x\n", hdr->addr); |
360 | cprintf(GREEN, " Load count: "); | ||
361 | cprintf(YELLOW, "%d\n", hdr->count); | ||
300 | 362 | ||
301 | struct rknano_stage_section_t *sec = (void *)(hdr + 1); | 363 | struct rknano_stage_section_t *sec = (void *)(hdr + 1); |
302 | void *end = buf + size; | ||
303 | 364 | ||
304 | int i = 0; | 365 | for(unsigned i = 0; i < hdr->count; i++, sec++) |
305 | while((void *)sec < end && (sec->code_sz || sec->bss_end_va)) | ||
306 | { | 366 | { |
307 | cprintf(BLUE, "Section %d\n", i); | 367 | cprintf(BLUE, "Section %d\n", i); |
308 | cprintf(GREEN, " Something: "); | ||
309 | cprintf(YELLOW, "%#x\n", sec->a); | ||
310 | cprintf(GREEN, " Code: "); | 368 | cprintf(GREEN, " Code: "); |
311 | cprintf(YELLOW, "%#x", sec->code_pa); | 369 | cprintf(YELLOW, "0x%08x", sec->code_pa); |
370 | cprintf(RED, "-(txt)-"); | ||
371 | cprintf(YELLOW, "0x%08x", sec->code_pa + sec->code_sz); | ||
312 | cprintf(BLUE, " |--> "); | 372 | cprintf(BLUE, " |--> "); |
313 | cprintf(YELLOW, "%#x", sec->code_va); | 373 | cprintf(YELLOW, "0x%08x", sec->code_va); |
314 | cprintf(RED, "-(code)-"); | 374 | cprintf(RED, "-(txt)-"); |
315 | cprintf(YELLOW, "%#x\n", sec->code_va + sec->code_sz); | 375 | cprintf(YELLOW, "0x%08x\n", sec->code_va + sec->code_sz); |
316 | 376 | ||
317 | cprintf(GREEN, " Data: "); | 377 | cprintf(GREEN, " Data: "); |
318 | cprintf(YELLOW, "%#x", sec->data_pa); | 378 | cprintf(YELLOW, "0x%08x", sec->data_pa); |
379 | cprintf(RED, "-(dat)-"); | ||
380 | cprintf(YELLOW, "0x%08x", sec->data_pa + sec->data_sz); | ||
319 | cprintf(BLUE, " |--> "); | 381 | cprintf(BLUE, " |--> "); |
320 | cprintf(YELLOW, "%#x", sec->data_va); | 382 | cprintf(YELLOW, "0x%08x", sec->data_va); |
321 | cprintf(RED, "-(data)-"); | 383 | cprintf(RED, "-(dat)-"); |
322 | cprintf(YELLOW, "%#x", sec->data_va + sec->data_sz); | 384 | cprintf(YELLOW, "0x%08x\n", sec->data_va + sec->data_sz); |
385 | |||
386 | cprintf(GREEN, " Data: "); | ||
387 | cprintf(RED, " "); | ||
388 | cprintf(BLUE, " |--> "); | ||
389 | cprintf(YELLOW, "0x%08x", sec->bss_va); | ||
323 | cprintf(RED, "-(bss)-"); | 390 | cprintf(RED, "-(bss)-"); |
324 | cprintf(YELLOW, "%#x\n", sec->bss_end_va); | 391 | cprintf(YELLOW, "0x%08x\n", sec->bss_va + sec->bss_sz); |
325 | 392 | ||
326 | sec++; | 393 | #if 0 |
327 | i++; | 394 | struct rknano_blob_t blob; |
395 | blob.offset = sec->code_pa - hdr->addr; | ||
396 | blob.size = sec->code_sz; | ||
397 | save_blob(&blob, buf, size, "entry.", i, NO_ENC); | ||
398 | #else | ||
399 | struct elf_params_t elf; | ||
400 | elf_init(&elf); | ||
401 | elf_add_load_section(&elf, sec->code_va, sec->code_sz, buf + sec->code_pa - hdr->addr); | ||
402 | elf_add_load_section(&elf, sec->data_va, sec->data_sz, buf + sec->data_pa - hdr->addr); | ||
403 | elf_add_fill_section(&elf, sec->bss_va, sec->bss_sz, 0); | ||
404 | extract_elf_section(&elf, i); | ||
405 | elf_release(&elf); | ||
406 | #endif | ||
328 | } | 407 | } |
329 | 408 | ||
330 | return 0; | 409 | return 0; |
@@ -487,8 +566,8 @@ static int do_boot_desc(uint8_t *buf, unsigned long size, | |||
487 | blob.offset = entry->offset; | 566 | blob.offset = entry->offset; |
488 | blob.size = entry->size; | 567 | blob.size = entry->size; |
489 | char name[128]; | 568 | char name[128]; |
490 | sprintf(name, "desc_%d_ent_%S_", desc_idx, from_uni16(entry->name)); | 569 | sprintf(name, "%d.%S", desc_idx, from_uni16(entry->name)); |
491 | save_blob(&blob, buf, size, name, i, PAGE_ENC); | 570 | save_blob(&blob, buf, size, name, -1, PAGE_ENC); |
492 | } | 571 | } |
493 | 572 | ||
494 | return 0; | 573 | return 0; |