[U-Boot] [PATCH 28/32] sandbox: Add os_jump_to_image() to run another executable

Simon Glass sjg at chromium.org
Sun Nov 10 18:27:14 CET 2013


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.

Signed-off-by: Simon Glass <sjg at chromium.org>

Signed-off-by: Simon Glass <sjg at chromium.org>
Reviewed-by: Simon Glass <sjg at chromium.org>
---
 arch/sandbox/cpu/os.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/os.h          | 19 +++++++++++
 2 files changed, 108 insertions(+)

diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 725b505..d811f74 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -438,3 +438,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);
+}
diff --git a/include/os.h b/include/os.h
index b65fba4..8039e93 100644
--- a/include/os.h
+++ b/include/os.h
@@ -245,4 +245,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
-- 
1.8.4.1



More information about the U-Boot mailing list