Subject: port-i386/6468: MBR/primary boot INT13 extensions lossage with Phoenix BIOS
To: None <gnats-bugs@gnats.netbsd.org>
From: None <tls@cp.net>
List: netbsd-bugs
Date: 11/20/1998 00:44:08
>Number:         6468
>Category:       port-i386
>Synopsis:       Use of INT13 extensions makes MBR lose with Phoenix BIOS
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 20 00:50:01 1998
>Last-Modified:
>Originator:     tls@cp.net
>Organization:
Critical Path, Inc.
>Release:        19981105
>Environment:
Intel NLX motherboard with Phoenix 6.0, and an OLD ide disk.
>Description:
	On an Intel NLX form-factor Pentium II motherboard with Phoenix/Intel
BIOS identified as Phoenix BIOS 6.0, the BIOS incorrectly reports INT 13
extensions for drives on which they are not supported.  This was observed
on a machine with two disks: a new, UDMA Seagate disk, which booted and ran
NetBSD just fine, and an ATA Flash card, which acts like a very old IDE disk;
it supports LBA mode, but not any fast PIO modes and only 1-sector PIO
transfers.  Several other ATA Flash cards wouldn't boot NetBSD either, and
neither would a very old IDE disk I dug up.

	I'm not sure if the problem is that the BIOS reports INT 13 extensions
for all drives but only supports them for drives >1024 cylinders, or if it
only supports them for drives which support multi-sector transfers, or some
other such lossage is going on.  The fact remains, the BIOS appears to be
reporting that it supports INT 13 extensions for drives which it doesn't
actually support them on, and this makes both the NetBSD MBR and the NetBSD
primary boot loader fail, because any read using the INT 13 extensions fails.

	I wasn't sure what to do about this, aside from make Intel fix the
BIOS.  I conditionalized things in the MBR and primary boot loader so that
it was at least possible to build them to not use INT 13 extensions, but
I don't think that's a good solution.  A better thing to do might be to use
the old interface to check the geometry of the drive, and only try to use
the extensions if the drive is big enough that they would be necessary.

	I've enclosed a patch below that at least conditionalizes the
use of the extensions.  I'm also reporting this bug to Phoenix and to Intel,
but this motherboard and BIOS are becoming quite common, as are ATA Flash
cards, and I expect we'll see this again before the vendors fix their BIOS
bug, if they ever do.

>How-To-Repeat:
	Try to install NetBSD on a small, dumb IDE disk (a 30MB SanDisk
CompactFlash card works nicely -- use an ATA, not a PCMCIA, flash card
adapter caddy) on an Intel NLX form factor Pentium II motherboard.  Most
NLX motherboards have Phoenix BIOS 6.0 or 6.1 so this bug is probably
there, too.

>Fix:
	Here's the patch for my workaround.  It's really not good enough
since it doesn't work for a fresh NetBSD install... to rebuild the boot
blocks, you already have to *have* NetBSD installed somewhere.


? mbr
Index: mbr.S
===================================================================
RCS file: /cvsroot/src/sbin/fdisk/mbr/mbr.S,v
retrieving revision 1.1
diff -c -r1.1 mbr.S
*** mbr.S	1998/10/15 15:22:14	1.1
--- mbr.S	1998/11/20 08:31:32
***************
*** 116,122 ****
--- 116,126 ----
  	cmpl	%eax, %ebx
  	jnz	noext
  	testb	$1, %cl
+ #if (defined INT13_EXT) && (INT13_EXT > 0)
  	jz	noext
+ #else
+ 	jmp	noext
+ #endif
  
  /*
   * Modify the partition table entry to look like an int13-extension
***************
*** 203,213 ****
  #endif
  
  msinvp:
! 	.asciz	"Invalid partition table"
  noos:
! 	.asciz	"No operating system"
  readerr:
! 	.asciz	"Error loading operating system"
  	. = _C_LABEL(start) + 0x1be
  parttab:
  	. = _C_LABEL(start) + 0x1fe
--- 207,217 ----
  #endif
  
  msinvp:
! 	.asciz	"NetBSD MBR: Invalid partition table"
  noos:
! 	.asciz	"NetBSD MBR: No operating system"
  readerr:
! 	.asciz	"NetBSD MBR: Error loading operating system"
  	. = _C_LABEL(start) + 0x1be
  parttab:
  	. = _C_LABEL(start) + 0x1fe
? biosboot/lib
? biosboot/vers.c
? biosboot/biosboot.list
? biosboot/biosboot.sym
? dosboot/lib
? dosboot/vers.c
? dosboot/dosboot.list
? dosboot/dosboot.sym
? dosboot/dosboot.com
? installboot/installboot
Index: biosboot/Makefile
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/biosboot/Makefile,v
retrieving revision 1.13
diff -c -r1.13 Makefile
*** Makefile	1998/08/13 17:41:10	1.13
--- Makefile	1998/11/20 08:32:11
***************
*** 11,20 ****
--- 11,22 ----
  
  CLEANFILES+= ${BSSTART}
  
+ CPPFLAGS+= -DBIOSDISK_EXT13=0
  CPPFLAGS+= -DCOMPAT_OLDBOOT -DCOMPAT_386BSD_MBRPART
  
  #Sample use of serial line debugger
  #CPPFLAGS+= -DSUPPORT_SERIAL=CONSDEV_COM0KBD
+ CPPFLAGS+= -DSUPPORT_SERIAL=CONSDEV_COM0 -DDIRECT_SERIAL -DCONSPEED=9600
  #	or
  #CPPFLAGS+= -DSUPPORT_SERIAL=CONSDEV_AUTO
  #	and maybe
Index: lib/biosdisk_ll.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosdisk_ll.h,v
retrieving revision 1.3
diff -c -r1.3 biosdisk_ll.h
*** biosdisk_ll.h	1998/10/15 15:28:22	1.3
--- biosdisk_ll.h	1998/11/20 08:32:11
***************
*** 44,51 ****
--- 44,54 ----
  	int             dev;		/* BIOS device number */
  	int             spt, spc;	/* geometry */
  	int		flags;		/* see below */
+ 
  };
+ #ifndef BIOSDISK_EXT13
  #define	BIOSDISK_EXT13	1		/* BIOS supports int13 extension */
+ #endif
  
  #define BIOSDISK_SECSIZE 512
  
Index: lib/crt/bootsect/start_bootsect.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/crt/bootsect/start_bootsect.S,v
retrieving revision 1.6
diff -c -r1.6 start_bootsect.S
*** start_bootsect.S	1998/10/15 15:28:22	1.6
--- start_bootsect.S	1998/11/20 08:32:11
***************
*** 217,223 ****
--- 217,227 ----
  	jnz	tradint13
  	testb	$1, %cl
  	data32
+ #if (defined BIOSDISK_EXT13) && (BIOSDISK_EXT13 > 0)
  	jz	tradint13
+ #else
+ 	jmp	tradint13
+ #endif
  
  /*
  # BIOS call "INT 0x13 Function 0x42", extended read
***************
*** 348,355 ****
  	data32
  	ret
  
! eread:	.asciz		"Read error\r\n"
! enoboot: .asciz		"No bootable partition\r\n"
  
  /* throw in a partition in case we are block0 as well */
  /* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */
--- 352,359 ----
  	data32
  	ret
  
! eread:	.asciz		"Read error (NetBSD boot)\r\n"
! enoboot: .asciz		"No bootable partition (NetBSD boot)\r\n"
  
  /* throw in a partition in case we are block0 as well */
  /* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */
>Audit-Trail:
>Unformatted:
>System: NetBSD edgerton 1.3H NetBSD 1.3H (PUSTULE) #3: Wed Nov 11 02:27:12 PST 1998 root@pustule:/usr/src/sys/arch/i386/compile/PUSTULE i386