summaryrefslogtreecommitdiff
path: root/arch/x86/lib/zimage.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2023-07-12 18:04:43 +0300
committerBin Meng <bmeng@tinylab.org>2023-07-17 08:38:35 +0300
commitc886557c18956dca5819920fd48d0d250c4b76a1 (patch)
treec2b7488fb26854b6eeb3cd6f0e83fa8f6d1ab7c4 /arch/x86/lib/zimage.c
parent33ebcb468109c40ef0dce262be00a4c161265b90 (diff)
downloadu-boot-c886557c18956dca5819920fd48d0d250c4b76a1.tar.xz
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/zimage.c')
-rw-r--r--arch/x86/lib/zimage.c82
1 files changed, 71 insertions, 11 deletions
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index e5ea5129c1..540d4d888b 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 = &params->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);