[PATCH] cmd: add FDT setup for bootelf by flag

Added the ability to use FDT for ELF applications, required to run some OS. To make FDT setup, you need to set the elf_needed_fdt environment variable to a value like y or yes.
Signed-off-by: Maxim Moskalets Maxim.Moskalets@kaspersky.com
Cc: Tom Rini trini@konsulko.com ---
cmd/elf.c | 14 ++++++++++++++ env/common.c | 5 +++++ include/env.h | 7 +++++++ 3 files changed, 26 insertions(+)
diff --git a/cmd/elf.c b/cmd/elf.c index b7b9f506a5..1ee86c03de 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -38,6 +38,8 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), /* Interpreter command to boot an arbitrary ELF image from memory */ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct bootm_headers img = {0}; + unsigned long fdt_addr; /* Address of the FDT */ unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ char *sload = NULL; @@ -68,6 +70,18 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) else addr = load_elf_image_shdr(addr);
+ if (env_get_elf_need_fdt()) { + if (argc >= 1 && strict_strtoul(argv[0], 16, &fdt_addr) != -EINVAL) { + printf("Got FDT at 0x%08lx ...\n", fdt_addr); + + if (image_setup_libfdt(&img, (void *)fdt_addr, NULL)) { + printf("ERROR: Failed to process device tree\n"); + return 1; + } + } + } + + if (!env_get_autostart()) return rcode;
diff --git a/env/common.c b/env/common.c index 48a565107c..8cd8558c3f 100644 --- a/env/common.c +++ b/env/common.c @@ -346,6 +346,11 @@ bool env_get_autostart(void) return env_get_yesno("autostart") == 1; }
+bool env_get_elf_need_fdt(void) +{ + return env_get_yesno("elf_need_fdt") == 1; +} + /* * Look up the variable from the default environment */ diff --git a/include/env.h b/include/env.h index d2a5954ded..384c312d2e 100644 --- a/include/env.h +++ b/include/env.h @@ -148,6 +148,13 @@ int env_get_yesno(const char *var); */ bool env_get_autostart(void);
+/** + * env_get_elf_need_fdt() - Check if FDT is needed for ELF image + * + * Return: true if the "elf_need_fdt" env var exists and is set to "yes" + */ +bool env_get_elf_need_fdt(void); + /** * env_set() - set an environment variable *

On Mon, Feb 12, 2024 at 09:41:17PM +0300, Maxim Moskalets wrote:
Added the ability to use FDT for ELF applications, required to run some OS. To make FDT setup, you need to set the elf_needed_fdt environment variable to a value like y or yes.
Signed-off-by: Maxim Moskalets Maxim.Moskalets@kaspersky.com
Cc: Tom Rini trini@konsulko.com
cmd/elf.c | 14 ++++++++++++++ env/common.c | 5 +++++ include/env.h | 7 +++++++ 3 files changed, 26 insertions(+)
Is there some change compared with the last version of this patch? And, I was thinking of how to reply to the previous one and I think my question is why don't we just use a flag being passed to bootelf instead of this? Doing bootelf addr -d fdt_addr seems clearer than bootelf addr1 addr2 and checking the environment.

Added the ability to use FDT for ELF applications, required to run some OS. To make FDT setup, you need to set the -d fdt_addr_r cmd option for bootelf command
Signed-off-by: Maxim Moskalets Maxim.Moskalets@kaspersky.com
Cc: Tom Rini trini@konsulko.com ---
cmd/elf.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/cmd/elf.c b/cmd/elf.c index b7b9f506a5..adf8536909 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -38,6 +38,8 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), /* Interpreter command to boot an arbitrary ELF image from memory */ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct bootm_headers img = {0}; + unsigned long fdt_addr = 0; /* Address of the FDT */ unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ char *sload = NULL; @@ -46,13 +48,23 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* Consume 'bootelf' */ argc--; argv++;
- /* Check for flag. */ + /* Check for [-p|-s] flag. */ if (argc >= 1 && (argv[0][0] == '-' && \ (argv[0][1] == 'p' || argv[0][1] == 's'))) { sload = argv[0]; /* Consume flag. */ argc--; argv++; } + + /* Check for [-d fdt_addr_r] option. */ + if ((argc >= 2) && (argv[0][0] == '-') && (argv[0][1] == 'd')) { + if (strict_strtoul(argv[1], 16, &fdt_addr) == -EINVAL) + return CMD_RET_USAGE; + /* Consume option. */ + argc -= 2; + argv += 2; + } + /* Check for address. */ if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) != -EINVAL) { /* Consume address */ @@ -68,6 +80,14 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) else addr = load_elf_image_shdr(addr);
+ if (fdt_addr) { + printf("## Setting up FDT at 0x%08lx ...\n", fdt_addr); + flush(); + + if (image_setup_libfdt(&img, (void *)fdt_addr, NULL)) + return 1; + } + if (!env_get_autostart()) return rcode;
@@ -298,7 +318,7 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) U_BOOT_CMD( bootelf, CONFIG_SYS_MAXARGS, 0, do_bootelf, "Boot from an ELF image in memory", - "[-p|-s] [address]\n" + "[-p|-s] [-d fdt_addr_r] [address]\n" "\t- load ELF image at [address] via program headers (-p)\n" "\t or via section headers (-s)" );

Added the ability to use FDT for ELF applications, required to run some OS. To make FDT setup, you need to set the -d fdt_addr_r cmd option for bootelf command
Signed-off-by: Maxim Moskalets Maxim.Moskalets@kaspersky.com
Cc: Tom Rini trini@konsulko.com ---
cmd/elf.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/cmd/elf.c b/cmd/elf.c index b7b9f506a5..c525618a39 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -38,6 +38,8 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), /* Interpreter command to boot an arbitrary ELF image from memory */ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct bootm_headers img = {0}; + unsigned long fdt_addr = 0; /* Address of the FDT */ unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ char *sload = NULL; @@ -46,13 +48,23 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* Consume 'bootelf' */ argc--; argv++;
- /* Check for flag. */ + /* Check for [-p|-s] flag. */ if (argc >= 1 && (argv[0][0] == '-' && \ (argv[0][1] == 'p' || argv[0][1] == 's'))) { sload = argv[0]; /* Consume flag. */ argc--; argv++; } + + /* Check for [-d fdt_addr_r] option. */ + if ((argc >= 2) && (argv[0][0] == '-') && (argv[0][1] == 'd')) { + if (strict_strtoul(argv[1], 16, &fdt_addr) != 0) + return CMD_RET_USAGE; + /* Consume option. */ + argc -= 2; + argv += 2; + } + /* Check for address. */ if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) != -EINVAL) { /* Consume address */ @@ -68,6 +80,14 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) else addr = load_elf_image_shdr(addr);
+ if (fdt_addr) { + printf("## Setting up FDT at 0x%08lx ...\n", fdt_addr); + flush(); + + if (image_setup_libfdt(&img, (void *)fdt_addr, NULL)) + return 1; + } + if (!env_get_autostart()) return rcode;
@@ -298,7 +318,7 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) U_BOOT_CMD( bootelf, CONFIG_SYS_MAXARGS, 0, do_bootelf, "Boot from an ELF image in memory", - "[-p|-s] [address]\n" + "[-p|-s] [-d fdt_addr_r] [address]\n" "\t- load ELF image at [address] via program headers (-p)\n" "\t or via section headers (-s)" );
participants (2)
-
Maxim Moskalets
-
Tom Rini