[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCHv2] grub2 int15 hook for e820/e801 does not return CF correctl
From: |
Vladimir 'φ-coder/phcoder' Serbinenko |
Subject: |
Re: [PATCHv2] grub2 int15 hook for e820/e801 does not return CF correctly; makes recent Linux detect only 64MB (via BIOS-88) |
Date: |
Mon, 28 Jun 2010 10:18:42 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100515 Icedove/3.0.4 |
On 06/26/2010 12:20 AM, Josh Triplett wrote:
> On Fri, Jun 25, 2010 at 02:28:01PM -0700, Josh Triplett wrote:
>
>> As I originally reported in http://bugs.debian.org/584846 , and later
>> tracked down, grub2's int15 hook, used to augment functions e820/e801/88
>> for additional reserved memory (such as for drivemap), fails to return
>> its error status correctly, causing recent Linux (and possibly other
>> OSes) to detect only 64MB via BIOS-88, ignoring e820 and e801.
>>
>> This occurs because the interrupt must return a status in CF, but after
>> using clc or stc to clear or set CF, it calls iret, which restores the
>> flags from the stack. Since recent Linux has CF set when it calls
>> int15, CF remains set when the interrupt returns, indicating an error.
>> Linux's detect_memory_e820 and detect_memory_e801 functions thus cannot
>> retrieve any memory map, and Linux must fall back to function 88, which
>> cannot return more than 64MB.
>>
>> To reproduce this problem, just use the "drivemap" command and then boot
>> a recent Linux kernel (git commit
>> c549e71d073a6e9a4847497344db28a784061455 or newer, meaning v2.6.30-rc1
>> or newer). In my case, I booted a USB drive with grub2 on it, used
>> "drivemap -s (hd1) (hd0)", then chainloaded the hard drive.
>>
>> The following patch against latest bzr fixes this problem. (Thanks to
>> H. Peter Anvin for noticing a bug in my original patch and suggesting a
>> fix.) With this patch, Linux's memory detection can use e820 again, and
>> detect all memory.
>>
> Revised patch, incorporating suggestion from phcoder to eliminate the
> unnecessary jmp right before the iret_cf label:
>
>
Comitted. Thanks
> === modified file 'mmap/i386/pc/mmap_helper.S'
> --- mmap/i386/pc/mmap_helper.S 2010-03-26 23:04:14 +0000
> +++ mmap/i386/pc/mmap_helper.S 2010-06-25 22:16:53 +0000
> @@ -59,7 +59,7 @@
> movw %bx, %dx
> pop %ds
> clc
> - iret
> + jmp LOCAL (iret_cf)
>
> LOCAL (h88):
> popf
> @@ -69,7 +69,7 @@
> movw DS (LOCAL (kbin16mb)), %ax
> pop %ds
> clc
> - iret
> + jmp LOCAL (iret_cf)
>
> LOCAL (e820):
> popf
> @@ -101,12 +101,18 @@
> mov $0x534d4150, %eax
> pop %ds
> clc
> - iret
> + jmp LOCAL (iret_cf)
> LOCAL (errexit):
> mov $0x534d4150, %eax
> pop %ds
> + xor %bx, %bx
> stc
> - xor %bx, %bx
> +
> +LOCAL (iret_cf):
> + push %bp
> + mov %sp, %bp
> + setc 6(%bp)
> + pop %bp
> iret
>
> VARIABLE(grub_machine_mmaphook_mmap_num)
>
>
> ChangeLog entry for this patch:
>
>
> 2010-06-25 Josh Triplett <address@hidden>
>
> * mmap/i386/pc/mmap_helper.S: Preserve CF by propagating it into the
> flags on the stack before popping them with iret. Add a new iret_cf
> label implementing this logic, and make the e820, e801, and 88
> handlers jump to it after setting or clearing CF. This fixes memory
> detection with recent Linux (git commit
> c549e71d073a6e9a4847497344db28a784061455 or newer, meaning v2.6.30-rc1
> or newer), which sets CF on entry to int15, and treats the preserved
> CF on exit as an error in e820 and e801; without this change, it can
> only successfully use BIOS-88 and detect only up to 64MB of RAM.
> Originally reported as Debian bug #584846.
>
>
> - Josh Triplett
>
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
signature.asc
Description: OpenPGP digital signature