Bug#614348: grub-legacy: Debian version of GRUB 0.97 won't boot Windows 7 (reboots computer)
Laszlo Madarassy
lmadarassy at mik.bme.hu
Mon Feb 21 08:42:19 UTC 2011
Package: grub-legacy
Severity: important
Tags: patch
I installed debian on /dev/sda1 and Windows 7 on /dev/sda2.
Installed and configured grub corretly, but the computer rebooted when selected Windows 7.
I did a lof of research and found the opensuse version of the grub can boot windows 7, but the debian (and the unpatched 0.97 version can't).
I started to test the opensuse patches and found the patch, waht makes grub to work with win7. It's an A20 gate patch(called 14_grub-a20.diff),
but it's strange, because this patch is used for some keyboard problem.
My computer config: Interl 915GUX chipset, pentium 4 3GHz CPU, 1GB RAM. 80GB SATA HDD.
Your description is a bit long; please enter a shorter subject. (An empty response will retain the existing subject.)
I also have this reboot problem with grub2,'m trin' to investigate that too. Windows XP, MAC OSX Snow leopard and Linux boots without any problem.
Windows 7 is on NTFS partition, the partition is MBR style.
-- System Information:
Debian Release: 6.0
APT prefers stable
APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.26-2-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
-------------- next part --------------
--- grub-0.97/stage2/asm.S.orig 2007-08-24 13:03:39.000000000 +0200
+++ grub-0.97/stage2/asm.S 2007-08-24 13:08:37.000000000 +0200
@@ -1620,42 +1620,85 @@ ENTRY(set_vbe_mode)
*
* Gate address-line 20 for high memory.
*
- * This routine is probably overconservative in what it does, but so what?
- *
- * It also eats any keystrokes in the keyboard buffer. :-(
+ * Try to disable the A20 gate by all means. (The argument is ignored)
+ * On success (the memory world is free), a -1 is returned, 0 on failure.
+ * It may also eat any keystrokes in the keyboard buffer. :-(
*/
ENTRY(gateA20)
+ pushl %ebx
+ pushl %edx
+ pushl %ebp
+ call testA20
+ jnz 1f
+ call A20_BIOS
+ call testA20
+ jnz 1f
+ call A20_PORT92
+ call testA20
+ jnz 1f
+ call A20_KBDCTL
+ call testA20
+ jnz 1f
+ movl $0,%eax
+ jmp 2f
+1: movl $-1,%eax
+2: popl %ebp
+ popl %edx
+ popl %ebx
+ ret
+
+testA20:
+ movl 0x500,%eax
+ movl 0x100500,%ebx
+ notl %eax
+ movl %eax,0x100500
+ cmpl %eax,0x500
+ pushfl
+ movl %ebx,0x100500
+ notl %eax
+ movl %eax,0x500
+ popfl
+ ret
+
+A20_BIOS:
/* first, try a BIOS call */
- pushl %ebp
- movl 8(%esp), %edx
call EXT_C(prot_to_real)
.code16
- movw $0x2400, %ax
- testw %dx, %dx
- jz 1f
- incw %ax
+ movw $0x2401, %ax
1: stc
int $0x15
- jnc 2f
-
- /* set non-zero if failed */
- movb $1, %ah
-
- /* save the status */
-2: movb %ah, %dl
DATA32 call EXT_C(real_to_prot)
.code32
-
- popl %ebp
- testb %dl, %dl
- jnz 3f
ret
-3: /* use keyboard controller */
+
+A20_PORT92:
+ /*
+ * try to switch gateA20 using PORT92, the "Fast A20 and Init"
+ * register
+ */
+ mov $0x92, %dx
+ inb %dx, %al
+ /* skip the port92 code if it's unimplemented (read returns 0xff) */
+ cmpb $0xff, %al
+ jz 6f
+
+ /* set bit1, the ALT_A20_GATE bit */
+ orb $2, %al
+/* and $0xfd, %al */
+
+ /* clear the INIT_NOW bit; don't accidently reset the machine */
+ and $0xfe, %al
+ outb %al, %dx
+6: ret
+
+
+A20_KBDCTL:
+ /* use keyboard controller */
pushl %eax
call gloop1
@@ -1669,11 +1710,7 @@ gloopint1:
jnz gloopint1
movb $KB_OUTPUT_MASK, %al
- cmpb $0, 0x8(%esp)
- jz gdoit
-
orb $KB_A20_ENABLE, %al
-gdoit:
outb $K_RDWR
call gloop1
-------------- next part --------------
--- grub-0.97/stage2/asm.S.orig 2007-08-24 13:03:39.000000000 +0200
+++ grub-0.97/stage2/asm.S 2007-08-24 13:08:37.000000000 +0200
@@ -1620,42 +1620,85 @@ ENTRY(set_vbe_mode)
*
* Gate address-line 20 for high memory.
*
- * This routine is probably overconservative in what it does, but so what?
- *
- * It also eats any keystrokes in the keyboard buffer. :-(
+ * Try to disable the A20 gate by all means. (The argument is ignored)
+ * On success (the memory world is free), a -1 is returned, 0 on failure.
+ * It may also eat any keystrokes in the keyboard buffer. :-(
*/
ENTRY(gateA20)
+ pushl %ebx
+ pushl %edx
+ pushl %ebp
+ call testA20
+ jnz 1f
+ call A20_BIOS
+ call testA20
+ jnz 1f
+ call A20_PORT92
+ call testA20
+ jnz 1f
+ call A20_KBDCTL
+ call testA20
+ jnz 1f
+ movl $0,%eax
+ jmp 2f
+1: movl $-1,%eax
+2: popl %ebp
+ popl %edx
+ popl %ebx
+ ret
+
+testA20:
+ movl 0x500,%eax
+ movl 0x100500,%ebx
+ notl %eax
+ movl %eax,0x100500
+ cmpl %eax,0x500
+ pushfl
+ movl %ebx,0x100500
+ notl %eax
+ movl %eax,0x500
+ popfl
+ ret
+
+A20_BIOS:
/* first, try a BIOS call */
- pushl %ebp
- movl 8(%esp), %edx
call EXT_C(prot_to_real)
.code16
- movw $0x2400, %ax
- testw %dx, %dx
- jz 1f
- incw %ax
+ movw $0x2401, %ax
1: stc
int $0x15
- jnc 2f
-
- /* set non-zero if failed */
- movb $1, %ah
-
- /* save the status */
-2: movb %ah, %dl
DATA32 call EXT_C(real_to_prot)
.code32
-
- popl %ebp
- testb %dl, %dl
- jnz 3f
ret
-3: /* use keyboard controller */
+
+A20_PORT92:
+ /*
+ * try to switch gateA20 using PORT92, the "Fast A20 and Init"
+ * register
+ */
+ mov $0x92, %dx
+ inb %dx, %al
+ /* skip the port92 code if it's unimplemented (read returns 0xff) */
+ cmpb $0xff, %al
+ jz 6f
+
+ /* set bit1, the ALT_A20_GATE bit */
+ orb $2, %al
+/* and $0xfd, %al */
+
+ /* clear the INIT_NOW bit; don't accidently reset the machine */
+ and $0xfe, %al
+ outb %al, %dx
+6: ret
+
+
+A20_KBDCTL:
+ /* use keyboard controller */
pushl %eax
call gloop1
@@ -1669,11 +1710,7 @@ gloopint1:
jnz gloopint1
movb $KB_OUTPUT_MASK, %al
- cmpb $0, 0x8(%esp)
- jz gdoit
-
orb $KB_A20_ENABLE, %al
-gdoit:
outb $K_RDWR
call gloop1
More information about the Pkg-grub-devel
mailing list