Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Apr 2001 09:18:33 -0700 (PDT)
From:      Doug Ambrisko <ambrisko@whistle.com>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   i386/26382: Fix for CDROM boot for IBM PC desktops
Message-ID:  <200104061618.JAA72839@whistle.com>

next in thread | raw e-mail | index | archive | help

>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:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 06 09:30:01 PDT 2001
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:
 Doug Ambrisko

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200104061618.JAA72839>