diff options
author | Simon Glass <sjg@chromium.org> | 2023-07-12 09:04:43 -0600 |
---|---|---|
committer | Bin Meng <bmeng@tinylab.org> | 2023-07-17 13:38:35 +0800 |
commit | c886557c18956dca5819920fd48d0d250c4b76a1 (patch) | |
tree | c2b7488fb26854b6eeb3cd6f0e83fa8f6d1ab7c4 /arch/x86/lib | |
parent | 33ebcb468109c40ef0dce262be00a4c161265b90 (diff) | |
download | u-boot-c886557c18956dca5819920fd48d0d250c4b76a1.zip u-boot-c886557c18956dca5819920fd48d0d250c4b76a1.tar.gz u-boot-c886557c18956dca5819920fd48d0d250c4b76a1.tar.bz2 |
x86: Add a function to boot a zimage
Add a direct interface to booting a zimage, so that bootstd can call it
without going through the command-line interface.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/zimage.c | 82 |
1 files changed, 71 insertions, 11 deletions
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index e5ea512..540d4d8 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -22,6 +22,7 @@ #include <irq_func.h> #include <log.h> #include <malloc.h> +#include <mapmem.h> #include <acpi/acpi_table.h> #include <asm/io.h> #include <asm/ptrace.h> @@ -442,8 +443,7 @@ static int do_zboot_start(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } -static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +static int zboot_load(void) { struct boot_params *base_ptr; @@ -460,31 +460,51 @@ static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc, &state.load_address); if (!base_ptr) { puts("## Kernel loading failed ...\n"); - return CMD_RET_FAILURE; + return -EINVAL; } } state.base_ptr = base_ptr; - if (env_set_hex("zbootbase", (ulong)base_ptr) || + + return 0; +} + +static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (zboot_load()) + return CMD_RET_FAILURE; + + if (env_set_hex("zbootbase", map_to_sysmem(state.base_ptr)) || env_set_hex("zbootaddr", state.load_address)) return CMD_RET_FAILURE; return 0; } +static int zboot_setup(void) +{ + struct boot_params *base_ptr = state.base_ptr; + int ret; + + ret = setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET, + 0, state.initrd_addr, state.initrd_size, + (ulong)state.cmdline); + if (ret) + return -EINVAL; + + return 0; +} + static int do_zboot_setup(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct boot_params *base_ptr = state.base_ptr; - int ret; if (!base_ptr) { printf("base is not set: use 'zboot load' first\n"); return CMD_RET_FAILURE; } - ret = setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET, - 0, state.initrd_addr, state.initrd_size, - (ulong)state.cmdline); - if (ret) { + if (zboot_setup()) { puts("Setting up boot parameters failed ...\n"); return CMD_RET_FAILURE; } @@ -501,8 +521,7 @@ static int do_zboot_info(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } -static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +static int zboot_go(void) { struct boot_params *params = state.base_ptr; struct setup_header *hdr = ¶ms->hdr; @@ -522,11 +541,52 @@ static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc, /* we assume that the kernel is in place */ ret = boot_linux_kernel((ulong)state.base_ptr, entry, image_64bit); + + return ret; +} + +static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + ret = zboot_go(); printf("Kernel returned! (err=%d)\n", ret); return CMD_RET_FAILURE; } +int zboot_start(ulong addr, ulong size, ulong initrd, ulong initrd_size, + ulong base, char *cmdline) +{ + int ret; + + memset(&state, '\0', sizeof(state)); + + if (base) { + state.base_ptr = map_sysmem(base, 0); + state.load_address = addr; + } else { + state.bzimage_addr = addr; + } + state.bzimage_size = size; + state.initrd_addr = initrd; + state.initrd_size = initrd_size; + state.cmdline = cmdline; + + ret = zboot_load(); + if (ret) + return log_msg_ret("ld", ret); + ret = zboot_setup(); + if (ret) + return log_msg_ret("set", ret); + ret = zboot_go(); + if (ret) + return log_msg_ret("set", ret); + + return -EFAULT; +} + static void print_num(const char *name, ulong value) { printf("%-20s: %lx\n", name, value); |