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>
This commit is contained in:
parent
b2a668b523
commit
47f5fcfb41
@ -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);
|
||||
}
|
||||
|
19
include/os.h
19
include/os.h
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user