[PATCH 07/22] sandbox: Support executables for more phases

Simon Glass sjg at chromium.org
Tue Jul 6 00:32:45 CEST 2021


The SPL header has a function for obtaining the phase in capital letters,
e.g. 'SPL'. Add one for lower-case also, as used by sandbox.

Use this to generalise the sandbox logic for determining the filename of
the next sandbox executable. This can provide support for VPL.

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

 arch/sandbox/cpu/os.c          | 63 +++++++++++++++-------------------
 arch/sandbox/cpu/spl.c         | 18 ++++++++--
 arch/sandbox/include/asm/spl.h | 13 +++++++
 include/os.h                   |  5 ++-
 include/spl.h                  | 23 +++++++++++++
 test/image/spl_load.c          |  6 +++-
 6 files changed, 89 insertions(+), 39 deletions(-)

diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 0d21827e1b7..a8aa9def27f 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -783,12 +783,14 @@ int os_jump_to_image(const void *dest, int size)
 	return os_jump_to_file(fname, true);
 }
 
-int os_find_u_boot(char *fname, int maxlen, bool use_img)
+int os_find_u_boot(char *fname, int maxlen, bool use_img,
+		   const char *cur_prefix, const char *next_prefix)
 {
 	struct sandbox_state *state = state_get_current();
 	const char *progname = state->argv[0];
 	int len = strlen(progname);
-	const char *suffix;
+	char subdir[10];
+	char *suffix;
 	char *p;
 	int fd;
 
@@ -798,45 +800,36 @@ int os_find_u_boot(char *fname, int maxlen, bool use_img)
 	strcpy(fname, progname);
 	suffix = fname + len - 4;
 
-	/* If we are TPL, boot to SPL */
-	if (!strcmp(suffix, "-tpl")) {
-		fname[len - 3] = 's';
-		fd = os_open(fname, O_RDONLY);
-		if (fd >= 0) {
-			close(fd);
-			return 0;
-		}
-
-		/* Look for 'u-boot-spl' in the spl/ directory */
-		p = strstr(fname, "/spl/");
-		if (p) {
-			p[1] = 's';
-			fd = os_open(fname, O_RDONLY);
-			if (fd >= 0) {
-				close(fd);
-				return 0;
-			}
-		}
-		return -ENOENT;
-	}
+	/* Change the existing suffix to the new one */
+	if (*suffix != '-')
+		return -EINVAL;
 
-	/* Look for 'u-boot' in the same directory as 'u-boot-spl' */
-	if (!strcmp(suffix, "-spl")) {
-		fname[len - 4] = '\0';
-		fd = os_open(fname, O_RDONLY);
-		if (fd >= 0) {
-			close(fd);
-			return 0;
-		}
+	if (*next_prefix)
+		strcpy(suffix + 1, next_prefix);  /* e.g. "-tpl" to "-spl" */
+	else
+		*suffix = '\0';  /* e.g. "-spl" to "" */
+	fd = os_open(fname, O_RDONLY);
+	if (fd >= 0) {
+		close(fd);
+		return 0;
 	}
 
-	/* Look for 'u-boot' in the parent directory of spl/ */
-	p = strstr(fname, "spl/");
+	/*
+	 * We didn't find it, so try looking for 'u-boot-xxx' in the xxx/
+	 * directory. Replace the old dirname with the new one.
+	 */
+	snprintf(subdir, sizeof(subdir), "/%s/", cur_prefix);
+	p = strstr(fname, subdir);
 	if (p) {
-		/* Remove the "spl" characters */
-		memmove(p, p + 4, strlen(p + 4) + 1);
+		if (*next_prefix)
+			/* e.g. ".../tpl/u-boot-spl"  to "../spl/u-boot-spl" */
+			memcpy(p + 1, next_prefix, strlen(next_prefix));
+		else
+			/* e.g. ".../spl/u-boot" to ".../u-boot" */
+			strcpy(p, p + 1 + strlen(cur_prefix));
 		if (use_img)
 			strcat(p, ".img");
+
 		fd = os_open(fname, O_RDONLY);
 		if (fd >= 0) {
 			close(fd);
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index f82b0d3de16..be86182fd85 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -17,7 +17,21 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* SPL / TPL init function */
+int sandbox_find_next_phase(char *fname, int maxlen, bool use_img)
+{
+	const char *cur_prefix, *next_prefix;
+	int ret;
+
+	cur_prefix = spl_phase_prefix(spl_phase());
+	next_prefix = spl_phase_prefix(spl_next_phase());
+	ret = os_find_u_boot(fname, maxlen, use_img, cur_prefix, next_prefix);
+	if (ret)
+		return log_msg_ret("find", ret);
+
+	return 0;
+}
+
+/* SPL / TPL / VPL init function */
 void board_init_f(ulong flag)
 {
 	struct sandbox_state *state = state_get_current();
@@ -37,7 +51,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
 	char fname[256];
 	int ret;
 
-	ret = os_find_u_boot(fname, sizeof(fname), false);
+	ret = sandbox_find_next_phase(fname, sizeof(fname), false);
 	if (ret) {
 		printf("(%s not found, error %d)\n", fname, ret);
 		return ret;
diff --git a/arch/sandbox/include/asm/spl.h b/arch/sandbox/include/asm/spl.h
index 51e9d95d557..d25dc7c82a0 100644
--- a/arch/sandbox/include/asm/spl.h
+++ b/arch/sandbox/include/asm/spl.h
@@ -12,4 +12,17 @@ enum {
 	BOOT_DEVICE_BOARD,
 };
 
+/**
+ * sandbox_find_next_phase() - Find the next phase of U-Boot
+ *
+ * This function is intended to be called from within sandbox SPL. It uses
+ * a few rules to find the filename of the next U-Boot phase. See also
+ * os_find_u_boot().
+ *
+ * @fname:	place to put full path to U-Boot
+ * @maxlen:	maximum size of @fname
+ * @use_img:	select the 'u-boot.img' file instead of the 'u-boot' ELF file
+ */
+int sandbox_find_next_phase(char *fname, int maxlen, bool use_img);
+
 #endif
diff --git a/include/os.h b/include/os.h
index bd1096eb8b3..7b20d606dd0 100644
--- a/include/os.h
+++ b/include/os.h
@@ -327,9 +327,12 @@ int os_jump_to_image(const void *dest, int size);
  * @fname:	place to put full path to U-Boot
  * @maxlen:	maximum size of @fname
  * @use_img:	select the 'u-boot.img' file instead of the 'u-boot' ELF file
+ * @cur_prefix:	prefix of current executable, e.g. "spl" or "tpl"
+ * @next_prefix: prefix of executable to find, e.g. "spl" or ""
  * Return:	0 if OK, -NOSPC if the filename is too large, -ENOENT if not found
  */
-int os_find_u_boot(char *fname, int maxlen, bool use_img);
+int os_find_u_boot(char *fname, int maxlen, bool use_img,
+		   const char *cur_prefix, const char *next_prefix);
 
 /**
  * os_spl_to_uboot() - Run U-Boot proper
diff --git a/include/spl.h b/include/spl.h
index d9fe4e1bfd4..cf77d379da2 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -188,6 +188,29 @@ static inline const char *spl_phase_name(enum u_boot_phase phase)
 	}
 }
 
+/**
+ * spl_phase_prefix() - Get the prefix  of the current phase
+ *
+ * @phase: Phase to look up
+ * @return phase prefix ("spl", "tpl", etc.)
+ */
+static inline const char *spl_phase_prefix(enum u_boot_phase phase)
+{
+	switch (phase) {
+	case PHASE_TPL:
+		return "tpl";
+	case PHASE_VPL:
+		return "vpl";
+	case PHASE_SPL:
+		return "spl";
+	case PHASE_BOARD_F:
+	case PHASE_BOARD_R:
+		return "";
+	default:
+		return "phase?";
+	}
+}
+
 /* A string name for SPL or TPL */
 #ifdef CONFIG_SPL_BUILD
 # ifdef CONFIG_TPL_BUILD
diff --git a/test/image/spl_load.c b/test/image/spl_load.c
index 851603ddd75..e7cabf5680c 100644
--- a/test/image/spl_load.c
+++ b/test/image/spl_load.c
@@ -56,6 +56,7 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
 
 static int spl_test_load(struct unit_test_state *uts)
 {
+	const char *cur_prefix, *next_prefix;
 	struct spl_image_info image;
 	struct image_header *header;
 	struct text_ctx text_ctx;
@@ -68,7 +69,10 @@ static int spl_test_load(struct unit_test_state *uts)
 	load.bl_len = 512;
 	load.read = read_fit_image;
 
-	ret = os_find_u_boot(fname, sizeof(fname), true);
+	cur_prefix = spl_phase_prefix(spl_phase());
+	next_prefix = spl_phase_prefix(spl_next_phase());
+	ret = os_find_u_boot(fname, sizeof(fname), true, cur_prefix,
+			     next_prefix);
 	if (ret) {
 		printf("(%s not found, error %d)\n", fname, ret);
 		return ret;
-- 
2.32.0.93.g670b81a890-goog



More information about the U-Boot mailing list