1
0
Fork 0

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>
utp
Simon Glass 2014-02-27 13:26:15 -07:00
parent b2a668b523
commit 47f5fcfb41
2 changed files with 108 additions and 0 deletions

View File

@ -443,3 +443,92 @@ int os_read_ram_buf(const char *fname)
return 0;
}
static int make_exec(char *fname, const void *data, int size)
{
int fd;
strcpy(fname, "/tmp/u-boot.jump.XXXXXX");
fd = mkstemp(fname);
if (fd < 0)
return -ENOENT;
if (write(fd, data, size) < 0)
return -EIO;
close(fd);
if (chmod(fname, 0777))
return -ENOEXEC;
return 0;
}
static int add_args(char ***argvp, const char *add_args[], int count)
{
char **argv;
int argc;
for (argv = *argvp, argc = 0; (*argvp)[argc]; argc++)
;
argv = malloc((argc + count + 1) * sizeof(char *));
if (!argv) {
printf("Out of memory for %d argv\n", count);
return -ENOMEM;
}
memcpy(argv, *argvp, argc * sizeof(char *));
memcpy(argv + argc, add_args, count * sizeof(char *));
argv[argc + count] = NULL;
*argvp = argv;
return 0;
}
int os_jump_to_image(const void *dest, int size)
{
struct sandbox_state *state = state_get_current();
char fname[30], mem_fname[30];
int fd, err;
const char *extra_args[4];
char **argv = state->argv;
#ifdef DEBUG
int argc, i;
#endif
err = make_exec(fname, dest, size);
if (err)
return err;
strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX");
fd = mkstemp(mem_fname);
if (fd < 0)
return -ENOENT;
close(fd);
err = os_write_ram_buf(mem_fname);
if (err)
return err;
os_fd_restore();
extra_args[0] = "-j";
extra_args[1] = fname;
extra_args[2] = "-m";
extra_args[3] = mem_fname;
err = add_args(&argv, extra_args,
sizeof(extra_args) / sizeof(extra_args[0]));
if (err)
return err;
#ifdef DEBUG
for (i = 0; argv[i]; i++)
printf("%d %s\n", i, argv[i]);
#endif
if (state_uninit())
os_exit(2);
err = execv(fname, argv);
free(argv);
if (err)
return err;
return unlink(fname);
}

View File

@ -253,4 +253,23 @@ int os_write_ram_buf(const char *fname);
*/
int os_read_ram_buf(const char *fname);
/**
* Jump to a new executable image
*
* This uses exec() to run a new executable image, after putting it in a
* temporary file. The same arguments and environment are passed to this
* new image, with the addition of:
*
* -j <filename> Specifies the filename the image was written to. The
* calling image may want to delete this at some point.
* -m <filename> Specifies the file containing the sandbox memory
* (ram_buf) from this image, so that the new image can
* have access to this. It also means that the original
* memory filename passed to U-Boot will be left intact.
*
* @param dest Buffer containing executable image
* @param size Size of buffer
*/
int os_jump_to_image(const void *dest, int size);
#endif