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 <s...@chromium.org>

Signed-off-by: Simon Glass <s...@chromium.org>
Reviewed-by: Simon Glass <s...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to