Commit 47f5fcfb4169a8ff6e8c81738b77f8572f972e75
1 parent
b2a668b523
Exists in
v2017.01-smarct4x
and in
48 other branches
sandbox: Add os_jump_to_image() to run another executable
For some tests it is useful to be able to run U-Boot again but pass on the same memory contents. Add a function to achieve this. Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 2 changed files with 108 additions and 0 deletions Side-by-side Diff
arch/sandbox/cpu/os.c
... | ... | @@ -443,4 +443,93 @@ |
443 | 443 | |
444 | 444 | return 0; |
445 | 445 | } |
446 | + | |
447 | +static int make_exec(char *fname, const void *data, int size) | |
448 | +{ | |
449 | + int fd; | |
450 | + | |
451 | + strcpy(fname, "/tmp/u-boot.jump.XXXXXX"); | |
452 | + fd = mkstemp(fname); | |
453 | + if (fd < 0) | |
454 | + return -ENOENT; | |
455 | + if (write(fd, data, size) < 0) | |
456 | + return -EIO; | |
457 | + close(fd); | |
458 | + if (chmod(fname, 0777)) | |
459 | + return -ENOEXEC; | |
460 | + | |
461 | + return 0; | |
462 | +} | |
463 | + | |
464 | +static int add_args(char ***argvp, const char *add_args[], int count) | |
465 | +{ | |
466 | + char **argv; | |
467 | + int argc; | |
468 | + | |
469 | + for (argv = *argvp, argc = 0; (*argvp)[argc]; argc++) | |
470 | + ; | |
471 | + | |
472 | + argv = malloc((argc + count + 1) * sizeof(char *)); | |
473 | + if (!argv) { | |
474 | + printf("Out of memory for %d argv\n", count); | |
475 | + return -ENOMEM; | |
476 | + } | |
477 | + memcpy(argv, *argvp, argc * sizeof(char *)); | |
478 | + memcpy(argv + argc, add_args, count * sizeof(char *)); | |
479 | + argv[argc + count] = NULL; | |
480 | + | |
481 | + *argvp = argv; | |
482 | + return 0; | |
483 | +} | |
484 | + | |
485 | +int os_jump_to_image(const void *dest, int size) | |
486 | +{ | |
487 | + struct sandbox_state *state = state_get_current(); | |
488 | + char fname[30], mem_fname[30]; | |
489 | + int fd, err; | |
490 | + const char *extra_args[4]; | |
491 | + char **argv = state->argv; | |
492 | +#ifdef DEBUG | |
493 | + int argc, i; | |
494 | +#endif | |
495 | + | |
496 | + err = make_exec(fname, dest, size); | |
497 | + if (err) | |
498 | + return err; | |
499 | + | |
500 | + strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX"); | |
501 | + fd = mkstemp(mem_fname); | |
502 | + if (fd < 0) | |
503 | + return -ENOENT; | |
504 | + close(fd); | |
505 | + err = os_write_ram_buf(mem_fname); | |
506 | + if (err) | |
507 | + return err; | |
508 | + | |
509 | + os_fd_restore(); | |
510 | + | |
511 | + extra_args[0] = "-j"; | |
512 | + extra_args[1] = fname; | |
513 | + extra_args[2] = "-m"; | |
514 | + extra_args[3] = mem_fname; | |
515 | + err = add_args(&argv, extra_args, | |
516 | + sizeof(extra_args) / sizeof(extra_args[0])); | |
517 | + if (err) | |
518 | + return err; | |
519 | + | |
520 | +#ifdef DEBUG | |
521 | + for (i = 0; argv[i]; i++) | |
522 | + printf("%d %s\n", i, argv[i]); | |
523 | +#endif | |
524 | + | |
525 | + if (state_uninit()) | |
526 | + os_exit(2); | |
527 | + | |
528 | + err = execv(fname, argv); | |
529 | + free(argv); | |
530 | + if (err) | |
531 | + return err; | |
532 | + | |
533 | + return unlink(fname); | |
534 | +} |
include/os.h
... | ... | @@ -253,5 +253,24 @@ |
253 | 253 | */ |
254 | 254 | int os_read_ram_buf(const char *fname); |
255 | 255 | |
256 | +/** | |
257 | + * Jump to a new executable image | |
258 | + * | |
259 | + * This uses exec() to run a new executable image, after putting it in a | |
260 | + * temporary file. The same arguments and environment are passed to this | |
261 | + * new image, with the addition of: | |
262 | + * | |
263 | + * -j <filename> Specifies the filename the image was written to. The | |
264 | + * calling image may want to delete this at some point. | |
265 | + * -m <filename> Specifies the file containing the sandbox memory | |
266 | + * (ram_buf) from this image, so that the new image can | |
267 | + * have access to this. It also means that the original | |
268 | + * memory filename passed to U-Boot will be left intact. | |
269 | + * | |
270 | + * @param dest Buffer containing executable image | |
271 | + * @param size Size of buffer | |
272 | + */ | |
273 | +int os_jump_to_image(const void *dest, int size); | |
274 | + | |
256 | 275 | #endif |