
Hmm, that's in an intervening patch. I didn't think that one was necessary but apparently it is. I'll add that to the series and send this out again.
Gabe
On Tue, Nov 29, 2011 at 7:23 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Gabe,
Thanks, I've been itching for this :)
On Wed, Nov 30, 2011 at 2:11 PM, Gabe Black gabeblack@chromium.org wrote:
This change conditionally modifies the zboot command so that it can use
the
32 bit boot protocol. This is necessary because the 16 bit realmode entry point assumes that it can call BIOS services which neither coreboot nor u-boot provide.
Signed-off-by: Gabe Black gabeblack@chromium.org
arch/x86/include/asm/zimage.h | 4 +- arch/x86/lib/bootm.c | 6 +++- arch/x86/lib/zimage.c | 49
+++++++++++++++++++++++++++++++---------
3 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/arch/x86/include/asm/zimage.h
b/arch/x86/include/asm/zimage.h
index 1a77e00..8ee6a74 100644 --- a/arch/x86/include/asm/zimage.h +++ b/arch/x86/include/asm/zimage.h @@ -46,8 +46,8 @@
void *load_zimage(char *image, unsigned long kernel_size, unsigned long initrd_addr, unsigned long initrd_size,
int auto_boot);
int auto_boot, void **load_address);
-void boot_zimage(void *setup_base); +void boot_zimage(void *setup_base, void *load_address);
#endif diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index bac7b4f..0905809 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -38,6 +38,7 @@ int do_bootm_linux(int flag, int argc, char * const
argv[],
void *base_ptr = NULL; ulong os_data, os_len; image_header_t *hdr;
void *load_address;
#if defined(CONFIG_FIT) const void *data; @@ -75,7 +76,8 @@ int do_bootm_linux(int flag, int argc, char * const
argv[],
#ifdef CONFIG_CMD_ZBOOT base_ptr = load_zimage((void *)os_data, os_len,
images->rd_start, images->rd_end -
images->rd_start, 0);
images->rd_start, images->rd_end -
images->rd_start,
0, &load_address);
#endif
if (NULL == base_ptr) {
@@ -92,7 +94,7 @@ int do_bootm_linux(int flag, int argc, char * const
argv[],
/* we assume that the kernel is in place */ printf("\nStarting kernel ...\n\n");
boot_zimage(base_ptr);
boot_zimage(base_ptr, load_address); /* does not return */
error: diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 3b33486..1003929 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -83,13 +83,12 @@ static void build_command_line(char *command_line,
int auto_boot)
void *load_zimage(char *image, unsigned long kernel_size, unsigned long initrd_addr, unsigned long initrd_size,
int auto_boot)
int auto_boot, void **load_address)
{ struct boot_params *setup_base; int setup_size; int bootproto; int big_image;
void *load_address; struct boot_params *params = (struct boot_params *)image; struct setup_header *hdr = ¶ms->hdr;
@@ -136,14 +135,23 @@ void *load_zimage(char *image, unsigned long
kernel_size,
/* Determine load address */ if (big_image)
load_address = (void *)BZIMAGE_LOAD_ADDR;
*load_address = (void *)BZIMAGE_LOAD_ADDR; else
load_address = (void *)ZIMAGE_LOAD_ADDR;
*load_address = (void *)ZIMAGE_LOAD_ADDR;
+#if defined CONFIG_ZBOOT_32
printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
memset(setup_base, 0, sizeof(*setup_base));
setup_base->hdr = params->hdr;
setup_base->e820_entries = install_e820_map(
ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
Where is install_e820_map() defined?
+#else /* load setup */ printf("Moving Real-Mode Code to 0x%8.8lx (%d bytes)\n", (ulong)setup_base, setup_size); memmove(setup_base, image, setup_size); +#endif
printf("Using boot protocol version %x.%02x\n", (bootproto & 0xff00) >> 8, bootproto & 0xff);
@@ -182,7 +190,7 @@ void *load_zimage(char *image, unsigned long
kernel_size,
if (hdr->setup_sects >= 15) { printf("Linux kernel version %s\n",
(char *)setup_base +
(char *)params + hdr->kernel_version + 0x200); } else { printf("Setup Sectors < 15 - "
@@ -237,17 +245,33 @@ void *load_zimage(char *image, unsigned long
kernel_size,
build_command_line((char *)setup_base + COMMAND_LINE_OFFSET,
auto_boot);
printf("Loading %czImage at address 0x%08x (%ld bytes)\n",
big_image ? 'b' : ' ', (u32)load_address, kernel_size);
big_image ? 'b' : ' ', (u32)*load_address, kernel_size);
memmove(load_address, image + setup_size, kernel_size);
memmove(*load_address, image + setup_size, kernel_size); /* ready for booting */ return setup_base;
}
-void boot_zimage(void *setup_base) +void boot_zimage(void *setup_base, void *load_address) { +#if defined CONFIG_ZBOOT_32
/*
* 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]"r"(load_address),
[boot_params] "S"(setup_base),
"b"(0), "D"(0)
);
+#else struct pt_regs regs;
memset(®s, 0, sizeof(struct pt_regs));
@@ -258,12 +282,14 @@ void boot_zimage(void *setup_base) regs.eflags = 0; enter_realmode(((u32)setup_base + SETUP_START_OFFSET) >> 4, 0, ®s, ®s); +#endif }
int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { void *base_ptr; void *bzImage_addr = NULL;
void *load_address; char *s; ulong bzImage_size = 0;
@@ -287,7 +313,8 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
bzImage_size = simple_strtoul(argv[2], NULL, 16); /* Lets look for */
base_ptr = load_zimage(bzImage_addr, bzImage_size, 0, 0, 0);
base_ptr = load_zimage(bzImage_addr, bzImage_size, 0, 0, 0,
&load_address); if (!base_ptr) { printf("## Kernel loading failed ...\n");
@@ -299,7 +326,7 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
/* we assume that the kernel is in place */ printf("\nStarting kernel ...\n\n");
boot_zimage(base_ptr);
boot_zimage(base_ptr, load_address); /* does not return */ }
-- 1.7.3.1
Regards,
Graeme