From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1OSGRi-0007KJ-5M for mharc-grub-devel@gnu.org; Fri, 25 Jun 2010 17:28:22 -0400 Received: from [140.186.70.92] (port=54369 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OSGRd-0007Il-P9 for grub-devel@gnu.org; Fri, 25 Jun 2010 17:28:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OSGRY-0004rE-Jn for grub-devel@gnu.org; Fri, 25 Jun 2010 17:28:17 -0400 Received: from relay1-d.mail.gandi.net ([217.70.183.193]:54327 helo=mrelay1-d.mgt.gandi.net) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OSGRY-0004qx-9H for grub-devel@gnu.org; Fri, 25 Jun 2010 17:28:12 -0400 X-Originating-IP: 217.70.178.38 Received: from mfilter4-v.gandi.net (mfilter4-v.gandi.net [217.70.178.38]) by mrelay1-d.mgt.gandi.net (Postfix) with ESMTP id 28E262552FA; Fri, 25 Jun 2010 23:28:10 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter4-v.gandi.net Received: from mrelay1-d.mgt.gandi.net ([217.70.183.193]) by mfilter4-v.gandi.net (mfilter4-v.gandi.net [217.70.178.38]) (amavisd-new, port 10024) with ESMTP id BCtugsAGaMQU; Fri, 25 Jun 2010 23:28:09 +0200 (CEST) X-Originating-IP: 74.107.143.84 Received: from feather (pool-74-107-143-84.ptldor.fios.verizon.net [74.107.143.84]) (Authenticated sender: josh@joshtriplett.org) by mrelay1-d.mgt.gandi.net (Postfix) with ESMTPSA id 475B82552F9; Fri, 25 Jun 2010 23:28:05 +0200 (CEST) Date: Fri, 25 Jun 2010 14:28:01 -0700 From: Josh Triplett To: grub-devel@gnu.org Message-ID: <20100625212757.GA25312@feather> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: 584846@bugs.debian.org Subject: [PATCH] grub2 int15 hook for e820/e801 does not return CF correctly; makes recent Linux detect only 64MB (via BIOS-88) X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jun 2010 21:28:19 -0000 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. === 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 21:03:04 +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,19 @@ 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 + jmp LOCAL (iret_cf) + +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 * 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