Re: 2.6.22-rc1-mm1: boot failure under qemu

From: H. Peter Anvin
Date: Wed May 16 2007 - 15:08:09 EST


Jeremy Fitzhardinge wrote:
> H. Peter Anvin wrote:
>> Okay, I've established that this is a bug in the Qemu kernel loader: the
>> Qemu loader puts zero in the loadflags, which is wrong no matter how you
>> slice it.
>>
>> I have checked in a workaround in the git.newsetup tree; the workaround
>> is to rely on a compile-time value for load low/load high instead of
>> looking at loadflags.
>>
>
> Can you post a patch to try?
>

Cumulative diff from -rc1-mm1.

-hpa
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
index 6792d09..a2b3f93 100644
--- a/arch/i386/boot/Makefile
+++ b/arch/i386/boot/Makefile
@@ -62,6 +62,7 @@ AFLAGS := $(CFLAGS) -D__ASSEMBLY__
$(obj)/zImage: IMAGE_OFFSET := 0x1000
$(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
$(obj)/bzImage: IMAGE_OFFSET := 0x100000
+$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
$(obj)/bzImage: BUILDFLAGS := -b

diff --git a/arch/i386/boot/main.c b/arch/i386/boot/main.c
index 5f4d99d..873c777 100644
--- a/arch/i386/boot/main.c
+++ b/arch/i386/boot/main.c
@@ -112,6 +112,10 @@ void main(void)
if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
heap_end = (char *)(boot_params.hdr.heap_end_ptr
+0x200-STACK_SIZE);
+ } else {
+ /* Boot protocol 2.00 only, no heap available */
+ puts("WARNING: Ancient bootloader, some functionality "
+ "may be limited!\n");
}

/* Make sure we have all the proper CPU support */
diff --git a/arch/i386/boot/memory.c b/arch/i386/boot/memory.c
index 8a82aa9..d7b250b 100644
--- a/arch/i386/boot/memory.c
+++ b/arch/i386/boot/memory.c
@@ -30,7 +30,7 @@ static int detect_memory_e820(void)
size = sizeof(struct e820entry);
id = SMAP;
asm("int $0x15; setc %0"
- : "=dm" (err), "+b" (next), "+d" (id), "+c" (size),
+ : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
"=m" (*desc)
: "D" (desc), "a" (0xe820));

diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c
index 1c586f1..7af65f9 100644
--- a/arch/i386/boot/pm.c
+++ b/arch/i386/boot/pm.c
@@ -41,12 +41,13 @@ static void realmode_switch_hook(void)
*/
static void move_kernel_around(void)
{
+ /* Note: rely on the compile-time option here rather than
+ the LOADED_HIGH flag. The Qemu kernel loader unconditionally
+ sets the loadflags to zero. */
+#ifndef __BIG_KERNEL__
u16 dst_seg, src_seg;
u32 syssize;

- if (boot_params.hdr.loadflags & LOADED_HIGH)
- return;
-
dst_seg = 0x1000 >> 4;
src_seg = 0x10000 >> 4;
syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraps */
@@ -72,6 +73,7 @@ static void move_kernel_around(void)
dst_seg += paras;
src_seg += paras;
}
+#endif
}

/*