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