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
 }
 
 /*

Reply via email to