summaryrefslogtreecommitdiffstats
path: root/arch/x86/lib/bootm.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2014-10-10 08:21:56 -0600
committerSimon Glass <sjg@chromium.org>2014-10-28 20:43:58 -0600
commit76539383ea0288985dc6216a92e3d7961df958b3 (patch)
tree20972aa414b45af84a56fcc4d7ec3965df57d705 /arch/x86/lib/bootm.c
parent200182a748afd430da97b707dc5dff53c3147b5f (diff)
downloadtalos-obmc-uboot-76539383ea0288985dc6216a92e3d7961df958b3.tar.gz
talos-obmc-uboot-76539383ea0288985dc6216a92e3d7961df958b3.zip
x86: Move kernel boot function to arch/x86/lib/bootm.c
The boot_zimage() function is badly named it can also boot a raw kernel. Rename it, and try to avoid pointers for memory addresses as it involves lots of casting. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch/x86/lib/bootm.c')
-rw-r--r--arch/x86/lib/bootm.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 4c5c7f5aa7..b90ca653fd 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <command.h>
+#include <errno.h>
#include <fdt_support.h>
#include <image.h>
#include <u-boot/zlib.h>
@@ -109,11 +110,11 @@ static int boot_prep_linux(bootm_headers_t *images)
}
if (is_zimage) {
- void *load_address;
+ ulong load_address;
char *base_ptr;
base_ptr = (char *)load_zimage(data, len, &load_address);
- images->os.load = (ulong)load_address;
+ images->os.load = load_address;
cmd_line_dest = base_ptr + COMMAND_LINE_OFFSET;
images->ep = (ulong)base_ptr;
} else if (images->ep) {
@@ -139,16 +140,45 @@ error:
return 1;
}
+int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
+{
+ bootm_announce_and_cleanup();
+
+#ifdef CONFIG_SYS_COREBOOT
+ timestamp_add_now(TS_U_BOOT_START_KERNEL);
+#endif
+ if (image_64bit) {
+ /* TODO(boot 64-bit kernel) */
+ } else {
+ /*
+ * Set %ebx, %ebp, and %edi to 0, %esi to point to the
+ * boot_params structure, and then jump to the kernel. We
+ * assume that %cs is 0x10, 4GB flat, and read/execute, and
+ * the data segments are 0x18, 4GB flat, and read/write.
+ * U-boot is setting them up that way for itself in
+ * arch/i386/cpu/cpu.c.
+ */
+ __asm__ __volatile__ (
+ "movl $0, %%ebp\n"
+ "cli\n"
+ "jmp *%[kernel_entry]\n"
+ :: [kernel_entry]"a"(load_address),
+ [boot_params] "S"(setup_base),
+ "b"(0), "D"(0)
+ );
+ }
+
+ /* We can't get to here */
+ return -EFAULT;
+}
+
/* Subcommand: GO */
static int boot_jump_linux(bootm_headers_t *images)
{
debug("## Transferring control to Linux (at address %08lx, kernel %08lx) ...\n",
images->ep, images->os.load);
- boot_zimage((struct boot_params *)images->ep, (void *)images->os.load);
- /* does not return */
-
- return 1;
+ return boot_linux_kernel(images->ep, images->os.load, false);
}
int do_bootm_linux(int flag, int argc, char * const argv[],
@@ -161,10 +191,8 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
if (flag & BOOTM_STATE_OS_PREP)
return boot_prep_linux(images);
- if (flag & BOOTM_STATE_OS_GO) {
- boot_jump_linux(images);
- return 0;
- }
+ if (flag & BOOTM_STATE_OS_GO)
+ return boot_jump_linux(images);
return boot_jump_linux(images);
}
OpenPOWER on IntegriCloud