From b0606ca15f7125aae556b976ba6ece36f622147b Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 31 Jul 2001 19:50:09 +0000 Subject: [PATCH] Add in a hack to support IBM "El Torito" CD-ROM booting BIOS's which expect the first sector of the emulated floppy to contain a valid MS-DOS BPB that it can modify. Since boot1 is the first sector of boot.flp, this resulted in the BIOS overwriting part of boot1: specifically the function used to read in sectors from the disk. Submitted by: Mark Peek Submitted by: Doug Ambrisko PR: i386/26382 Obtained from: NetBSD, OpenBSD (the example BPB) MFC after: 1 month --- sys/boot/i386/boot2/Makefile | 11 ++++++++++- sys/boot/i386/boot2/boot1.S | 35 ++++++++++++++++++++++++++++++++- sys/boot/i386/boot2/boot1.s | 35 ++++++++++++++++++++++++++++++++- sys/boot/i386/boot2/boot2.c | 3 ++- sys/boot/i386/gptboot/Makefile | 11 ++++++++++- sys/boot/i386/gptboot/gptboot.c | 3 ++- 6 files changed, 92 insertions(+), 6 deletions(-) diff --git a/sys/boot/i386/boot2/Makefile b/sys/boot/i386/boot2/Makefile index 35e7d89caeb1..5425c08707fe 100644 --- a/sys/boot/i386/boot2/Makefile +++ b/sys/boot/i386/boot2/Makefile @@ -6,9 +6,11 @@ STRIP= BINDIR?= /boot BINMODE= 444 CLEANFILES+= boot1 boot1.out boot1.o \ - boot2.ldr boot2.bin boot2.ld boot2.out boot2.o \ + boot2.ldr boot2.bin boot2.ld boot2.out boot2.o boot2.h \ sio.o +NM?= nm + # A value of 0x80 enables LBA support. B1FLAGS= 0x80 @@ -46,6 +48,11 @@ boot1.out: boot1.o boot1.o: boot1.s ${AS} ${AFLAGS} --defsym FLAGS=${B1FLAGS} ${.IMPSRC} -o ${.TARGET} +boot2.h: boot1.out + ${NM} -t d ${.ALLSRC} | awk '/([0-9])+ T xread/ \ + { x = $$1 - ORG1; printf("#define XREADORG 0x7%x\n", x) }' \ + ORG1=`printf "%d" ${ORG1}` > boot2.h + boot2: boot2.ldr boot2.bin ${BTX}/btx/btx btxld -v -E ${ORG2} -f bin -b ${BTX}/btx/btx -l boot2.ldr \ -o boot2.ld -P 1 boot2.bin @@ -63,6 +70,8 @@ boot2.out: boot2.o sio.o ${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} \ ${BTX}/lib/crt0.o boot2.o sio.o +boot2.o: boot2.h + sio.o: sio.s ${AS} ${AFLAGS} --defsym SIOPRT=${BOOT_COMCONSOLE_PORT} \ --defsym SIOFMT=${B2SIOFMT} \ diff --git a/sys/boot/i386/boot2/boot1.S b/sys/boot/i386/boot2/boot1.S index 3b34041efd1a..99eef3a3790c 100644 --- a/sys/boot/i386/boot2/boot1.S +++ b/sys/boot/i386/boot2/boot1.S @@ -43,7 +43,40 @@ start: jmp main # Start recognizably - .org 0x4,0x90 +# This is the start of a standard BIOS Parameter Block (BPB). Most bootable +# FAT disks have this at the start of their MBR. While normal BIOS's will +# work fine without this section, IBM's El Torito emulation "fixes" up the +# BPB by writing into the memory copy of the MBR. Rather than have data +# written into our xread routine, we'll define a BPB to work around it. +# The data marked with (T) indicates a field required for a ThinkPad to +# recognize the disk and (W) indicates fields written from IBM BIOS code. +# The use of the BPB is based on what OpenBSD and NetBSD implemented in +# their boot code but the required fields were determined by trial and error. +# +# Note: If additional space is needed in boot1, one solution would be to +# move the "prompt" message data (below) to replace the OEM ID. + + .org 0x03, 0x00 +oemid: .space 0x08, 0x00 # OEM ID + + .org 0x0b, 0x00 +bpb: .word 512 # sector size (T) + .byte 0 # sectors/clustor + .word 0 # reserved sectors + .byte 0 # number of FATs + .word 0 # root entries + .word 0 # small sectors + .byte 0 # media type (W) + .word 0 # sectors/fat + .word 18 # sectors per track (T) + .word 2 # number of heads (T) + .long 0 # hidden sectors (W) + .long 0 # large sectors + + .org 0x24, 0x00 +ebpb: .byte 0 # BIOS physical drive number (W) + + .org 0x25,0x90 # # Trampoline used by boot2 to call read to read data from the disk via # the BIOS. Call with: diff --git a/sys/boot/i386/boot2/boot1.s b/sys/boot/i386/boot2/boot1.s index 3b34041efd1a..99eef3a3790c 100644 --- a/sys/boot/i386/boot2/boot1.s +++ b/sys/boot/i386/boot2/boot1.s @@ -43,7 +43,40 @@ start: jmp main # Start recognizably - .org 0x4,0x90 +# This is the start of a standard BIOS Parameter Block (BPB). Most bootable +# FAT disks have this at the start of their MBR. While normal BIOS's will +# work fine without this section, IBM's El Torito emulation "fixes" up the +# BPB by writing into the memory copy of the MBR. Rather than have data +# written into our xread routine, we'll define a BPB to work around it. +# The data marked with (T) indicates a field required for a ThinkPad to +# recognize the disk and (W) indicates fields written from IBM BIOS code. +# The use of the BPB is based on what OpenBSD and NetBSD implemented in +# their boot code but the required fields were determined by trial and error. +# +# Note: If additional space is needed in boot1, one solution would be to +# move the "prompt" message data (below) to replace the OEM ID. + + .org 0x03, 0x00 +oemid: .space 0x08, 0x00 # OEM ID + + .org 0x0b, 0x00 +bpb: .word 512 # sector size (T) + .byte 0 # sectors/clustor + .word 0 # reserved sectors + .byte 0 # number of FATs + .word 0 # root entries + .word 0 # small sectors + .byte 0 # media type (W) + .word 0 # sectors/fat + .word 18 # sectors per track (T) + .word 2 # number of heads (T) + .long 0 # hidden sectors (W) + .long 0 # large sectors + + .org 0x24, 0x00 +ebpb: .byte 0 # BIOS physical drive number (W) + + .org 0x25,0x90 # # Trampoline used by boot2 to call read to read data from the disk via # the BIOS. Call with: diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c index ef3f504d65b7..d7f5721abd60 100644 --- a/sys/boot/i386/boot2/boot2.c +++ b/sys/boot/i386/boot2/boot2.c @@ -34,6 +34,7 @@ #include +#include "boot2.h" #include "lib.h" #define RBX_ASKNAME 0x0 /* -a */ @@ -739,7 +740,7 @@ drvread(void *buf, unsigned lba, unsigned nblk) 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.addr = XREADORG; /* call to xread in boot1 */ v86.es = VTOPSEG(buf); v86.eax = lba; v86.ebx = VTOPOFF(buf); diff --git a/sys/boot/i386/gptboot/Makefile b/sys/boot/i386/gptboot/Makefile index 35e7d89caeb1..5425c08707fe 100644 --- a/sys/boot/i386/gptboot/Makefile +++ b/sys/boot/i386/gptboot/Makefile @@ -6,9 +6,11 @@ STRIP= BINDIR?= /boot BINMODE= 444 CLEANFILES+= boot1 boot1.out boot1.o \ - boot2.ldr boot2.bin boot2.ld boot2.out boot2.o \ + boot2.ldr boot2.bin boot2.ld boot2.out boot2.o boot2.h \ sio.o +NM?= nm + # A value of 0x80 enables LBA support. B1FLAGS= 0x80 @@ -46,6 +48,11 @@ boot1.out: boot1.o boot1.o: boot1.s ${AS} ${AFLAGS} --defsym FLAGS=${B1FLAGS} ${.IMPSRC} -o ${.TARGET} +boot2.h: boot1.out + ${NM} -t d ${.ALLSRC} | awk '/([0-9])+ T xread/ \ + { x = $$1 - ORG1; printf("#define XREADORG 0x7%x\n", x) }' \ + ORG1=`printf "%d" ${ORG1}` > boot2.h + boot2: boot2.ldr boot2.bin ${BTX}/btx/btx btxld -v -E ${ORG2} -f bin -b ${BTX}/btx/btx -l boot2.ldr \ -o boot2.ld -P 1 boot2.bin @@ -63,6 +70,8 @@ boot2.out: boot2.o sio.o ${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} \ ${BTX}/lib/crt0.o boot2.o sio.o +boot2.o: boot2.h + sio.o: sio.s ${AS} ${AFLAGS} --defsym SIOPRT=${BOOT_COMCONSOLE_PORT} \ --defsym SIOFMT=${B2SIOFMT} \ diff --git a/sys/boot/i386/gptboot/gptboot.c b/sys/boot/i386/gptboot/gptboot.c index ef3f504d65b7..d7f5721abd60 100644 --- a/sys/boot/i386/gptboot/gptboot.c +++ b/sys/boot/i386/gptboot/gptboot.c @@ -34,6 +34,7 @@ #include +#include "boot2.h" #include "lib.h" #define RBX_ASKNAME 0x0 /* -a */ @@ -739,7 +740,7 @@ drvread(void *buf, unsigned lba, unsigned nblk) 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.addr = XREADORG; /* call to xread in boot1 */ v86.es = VTOPSEG(buf); v86.eax = lba; v86.ebx = VTOPOFF(buf);