From ambrisko@whistle.com  Fri Apr  6 09:20:02 2001
Return-Path: <ambrisko@whistle.com>
Received: from alpo.whistle.com (s206m1.whistle.com [207.76.206.1])
	by hub.freebsd.org (Postfix) with ESMTP id B1DB737B424
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  6 Apr 2001 09:20:02 -0700 (PDT)
	(envelope-from ambrisko@whistle.com)
Received: from whistle.com (crab.whistle.com [207.76.205.112])
	by alpo.whistle.com (8.9.1a/8.9.1) with ESMTP id JAA28786
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 6 Apr 2001 09:18:44 -0700 (PDT)
Received: (from ambrisko@localhost)
	by whistle.com (8.9.3/8.9.1) id JAA72839;
	Fri, 6 Apr 2001 09:18:33 -0700 (PDT)
	(envelope-from ambrisko)
Message-Id: <200104061618.JAA72839@whistle.com>
Date: Fri, 6 Apr 2001 09:18:33 -0700 (PDT)
From: Doug Ambrisko <ambrisko@whistle.com>
Reply-To: ambrisko@whistle.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: Fix for CDROM boot for IBM PC desktops
X-Send-Pr-Version: 3.2

>Number:         26382
>Category:       i386
>Synopsis:       FreeBSD Bootable CDROM won't boot on IBM PC Desktops
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 06 09:30:01 PDT 2001
>Closed-Date:    Tue Jul 31 12:50:32 PDT 2001
>Last-Modified:  Tue Jul 31 12:50:53 PDT 2001
>Originator:     Doug Ambrisko
>Release:        FreeBSD any i386
>Organization:
Whistle/IBM
>Environment:

On on IBM PC desktop a bootable CDROM won't boot and it hangs.

>Description:

The problem is that some BIOSes namely IBM's writes to the boot sector
of the floppy to potentially update the parameters for the emulated
floppy used for the El Torrito boot.  Since we do not allocate space
for a typical MSDOS "Boot Sector" when the BIOS updates this area
it then ends up modifying the boot code which is not a good thing.
The boot code then fails in random ways.

>How-To-Repeat:

Stick any FreeBSD CDROM that is bootable into an IBM PC and it won't
boot of the CDROM currectly (For example IDE CDROM on IntelliStations
and other IDE based models).  This does not fix failures on ThinkPads
(770Z & 600E for sure).  That seems to be yet a different problem. 

>Fix:

This is relative to /sys/boot/i386/boot2 and was generated against 
-stable.  Hints were obtained from OpenBSD & NetBSD.  

Space in boot1 was allocated so the BIOS could non-destructively update the
MSDOS Boot Sector in boot1 without nuking code.

I added a hack since "xread" was being called from boot2 with a hard
coded value.  Since this can change and lead me on a wild goose chase
I added a perl script and modified the Makefile to determine the
offset for "xread" and then patch that into boot2.c  So whenever boot1
changes boot2.c will be patched with a potentially new value.  This
also means that xread can be moved around the boot1.s code without
breaking things.

I did not put in the full label from OpenBSD since boot1 started to 
overflow.  So I only did it for the size that NetBSD did.

We can now boot CDROM on several different IBM desktops.

Index: Makefile
===================================================================
RCS file: /cvs/freebsd/src/sys/boot/i386/boot2/Makefile,v
retrieving revision 1.16.2.3
diff -c -r1.16.2.3 Makefile
*** Makefile	2000/07/07 21:12:29	1.16.2.3
--- Makefile	2001/04/05 23:11:14
***************
*** 25,31 ****
  ORG1=	0x7c00
  ORG2=	0x1000
  
! CFLAGS=	-elf -I${.CURDIR}/../btx/lib -I. \
  	-Os -fno-builtin -fforce-addr -fdata-sections \
  	-malign-functions=0 -malign-jumps=0 -malign-loops=0 -mrtd \
  	-mpreferred-stack-boundary=2 \
--- 25,31 ----
  ORG1=	0x7c00
  ORG2=	0x1000
  
! CFLAGS=	-elf -I${.CURDIR}/../btx/lib -I. -I${.CURDIR} \
  	-Os -fno-builtin -fforce-addr -fdata-sections \
  	-malign-functions=0 -malign-jumps=0 -malign-loops=0 -mrtd \
  	-mpreferred-stack-boundary=2 \
***************
*** 59,67 ****
  boot2.bin: boot2.out
  	objcopy -S -O binary boot2.out ${.TARGET}
  
! boot2.out: boot2.o sio.o
  	${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} \
! 		${BTX}/lib/crt0.o boot2.o sio.o
  
  sio.o: sio.s
  	${AS} ${AFLAGS} --defsym SIOPRT=${BOOT_COMCONSOLE_PORT} \
--- 59,72 ----
  boot2.bin: boot2.out
  	objcopy -S -O binary boot2.out ${.TARGET}
  
! boot2.out: boot2_patched.o sio.o
  	${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} \
! 		${BTX}/lib/crt0.o boot2_patched.o sio.o
! 
! boot2_patched.c: boot1.out boot2.c
! 	RESULT=`nm boot1.out | perl ${.CURDIR}/patch.pl ${ORG1}` ; \
! 	sed -e "s/__XREAD_OFFSET__/$$RESULT/" < ${.CURDIR}/boot2.c \
! 		> ${.TARGET}
  
  sio.o: sio.s
  	${AS} ${AFLAGS} --defsym SIOPRT=${BOOT_COMCONSOLE_PORT} \
Index: boot1.s
===================================================================
RCS file: /cvs/freebsd/src/sys/boot/i386/boot2/boot1.s,v
retrieving revision 1.10.2.2
diff -c -r1.10.2.2 boot1.s
*** boot1.s	2000/07/07 21:12:32	1.10.2.2
--- boot1.s	2001/04/05 23:11:14
***************
*** 42,49 ****
  		.code16
  
  start:		jmp main			# Start recognizably
  
! 		.org 0x4,0x90
  # 
  # Trampoline used by boot2 to call read to read data from the disk via
  # the BIOS.  Call with:
--- 42,84 ----
  		.code16
  
  start:		jmp main			# Start recognizably
+ 		nop				# Needed for some BIOS's
  
! /*  From OpenBSD biosboot.S
! */
! 	.org 0x03, 0x00
! 	.asciz	"FreeBSD"
! 	/* BPB */
! 	.org 0x0b, 0x00
! bpb:	.word	2		/* sector size */
! 	.byte	1		/* sectors/cluster */
! 	.word	0		/* reserved sectors */
! 	.byte	0		/* # of FAT */
! 	.word	0		/* root entries */
! 	.word	0		/* small sectors */
! 	.byte	0xf8		/* media type (hd) */
! 	.word	0		/* sectors/fat */
! 	.word	0		/* sectors per track */
! 	.word	0		/* # of heads */
! 
! 	/* EBPB */
! 	.org 0x1c, 0x00
! ebpb:	.long	16		/* hidden sectors */
! 	.long	0		/* large sectors */
! 
! /* NetBSD only does 25 bytes and we start to run out of room in boot1 if
!    we do more
! */
! 	
! #	.word	0		/* physical disk */
! #	.byte	0x29		/* signature, needed by NT */
! #	.space	4, 0		/* volume serial number */
! #	.asciz	"UNIX LABEL"
! #	.asciz	"UFS 4.2"
! #
! 	.org 0x25,0x00			# BIOSes sometimes scribble 
! 					# here such as IBM PC's when
! 					# booting from CDROM
  # 
  # Trampoline used by boot2 to call read to read data from the disk via
  # the BIOS.  Call with:
Index: boot2.c
===================================================================
RCS file: /cvs/freebsd/src/sys/boot/i386/boot2/boot2.c,v
retrieving revision 1.28.2.2
diff -c -r1.28.2.2 boot2.c
*** boot2.c	2000/07/07 21:12:32	1.28.2.2
--- boot2.c	2001/04/05 23:11:14
***************
*** 739,745 ****
  
      printf("%c\b", c = c << 8 | c >> 24);
      v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
!     v86.addr = 0x704;		/* call to xread in boot1 */
      v86.es = VTOPSEG(buf);
      v86.eax = lba;
      v86.ebx = VTOPOFF(buf);
--- 739,745 ----
  
      printf("%c\b", c = c << 8 | c >> 24);
      v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
!     v86.addr = 0x7__XREAD_OFFSET__;		/* call to xread in boot1 */
      v86.es = VTOPSEG(buf);
      v86.eax = lba;
      v86.ebx = VTOPOFF(buf);
*** /dev/null	Thu Apr  5 16:03:38 2001
--- patch.pl	Thu Apr  5 15:52:13 2001
***************
*** 0 ****
--- 1,12 ----
+ 
+ $start=$ARGV[0];
+ 
+ while(<STDIN>){
+   /T xread/ && ( ($address) = split(/\s+/));
+ }
+ 
+ $address_dec=hex $address;
+ $start_dec=eval($start); 
+ 
+ printf ("%x\n",$address_dec-$start_dec);
+ 
>Release-Note:
>Audit-Trail:

From: Doug Ambrisko <ambrisko@whistle.com>
To: freebsd-gnats-submit@FreeBSD.org, ambrisko@whistle.com
Cc:  
Subject: Re: i386/26382: FreeBSD Bootable CDROM won't boot on IBM PC Desktops
Date: Fri, 06 Apr 2001 15:00:55 -0700

 Here is the updated structure in boot1.s to fix FreeBSD CDROM booting on
 ThinkPads 770Z, 600E.
 
   /*  From OpenBSD biosboot.S with tuned values from Doug Ambrisko so
       ThinkPads can boot from CDROM.  I think the critical part
       is setting the media type.
   */
           .org 0x03, 0x00
           .asciz  "FreeBSD"
           /* BPB */
           .org 0x0b, 0x00
   bpb:    .word   512             /* sector size */
           .byte   1               /* sectors/cluster */
           .word   1               /* reserved sectors */
           .byte   2               /* # of FAT */
           .word   224             /* root entries */
           .word   2880            /* small sectors */
           .byte   0xf0            /* media type (fd) */
           .word   144             /* sectors/fat */
           .word   18              /* sectors per track */
           .word   2               /* # of heads */
 
           /* EBPB */
           .org 0x1c, 0x00
   ebpb:   .long   16              /* hidden sectors */
           .long   0               /* large sectors */
 
 
State-Changed-From-To: open->closed 
State-Changed-By: jhb 
State-Changed-When: Tue Jul 31 12:50:32 PDT 2001 
State-Changed-Why:  
Committed, thanks! 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=26382 
>Unformatted:
 Doug Ambrisko
