Due to space constraints, the UFS boot2 and boot1 use an evil hack where

boot2 calls back into boot1 to perform disk reads.  The ZFS MBR boot blocks
do not have the same space constraints, so remove this hack for ZFS.
While here, remove commented out code to support C/H/S addressing from
zfsldr.  The ZFS and GPT bootstraps always just use EDD LBA addressing.

MFC after:	2 weeks
This commit is contained in:
John Baldwin 2011-04-28 17:44:24 +00:00
parent 466a71d75e
commit ed10c810db
4 changed files with 33 additions and 129 deletions

View File

@ -32,6 +32,7 @@ CFLAGS= -Os \
-mno-align-long-strings \
-mrtd \
-mregparm=3 \
-DUSE_XREAD \
-D${BOOT2_UFS} \
-DFLAGS=${BOOT_BOOT1_FLAGS} \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \

View File

@ -26,7 +26,7 @@ __FBSDID("$FreeBSD$");
#include "rbx.h"
#include "util.h"
#include "drv.h"
#ifndef GPT
#ifdef USE_XREAD
#include "xreadorg.h"
#endif
@ -58,7 +58,7 @@ drvsize(struct dsk *dskp)
}
#endif /* GPT */
#ifdef GPT
#ifndef USE_XREAD
static struct {
uint16_t len;
uint16_t count;
@ -66,7 +66,7 @@ static struct {
uint16_t seg;
uint64_t lba;
} packet;
#endif /* GPT */
#endif
int
drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
@ -75,7 +75,7 @@ drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
if (!OPT_CHECK(RBX_QUIET))
printf("%c\b", c = c << 8 | c >> 24);
#ifdef GPT
#ifndef USE_XREAD
packet.len = 0x10;
packet.count = nblk;
packet.off = VTOPOFF(buf);
@ -87,7 +87,7 @@ drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
v86.edx = dskp->drive;
v86.ds = VTOPSEG(&packet);
v86.esi = VTOPOFF(&packet);
#else /* !GPT */
#else /* USE_XREAD */
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
v86.addr = XREADORG; /* call to xread in boot1 */
v86.es = VTOPSEG(buf);
@ -95,7 +95,7 @@ drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
v86.ebx = VTOPOFF(buf);
v86.ecx = lba >> 32;
v86.edx = nblk << 8 | dskp->drive;
#endif /* !GPT */
#endif /* USE_XREAD */
v86int();
if (V86_CY(v86.efl)) {
printf("%s: error %u lba %u\n",

View File

@ -6,9 +6,6 @@ FILES= zfsboot
NM?= nm
# A value of 0x80 enables LBA support.
BOOT_BOOT1_FLAGS?= 0x80
BOOT_COMCONSOLE_PORT?= 0x3f8
BOOT_COMCONSOLE_SPEED?= 9600
B2SIOFMT?= 0x3
@ -25,7 +22,6 @@ CFLAGS= -DBOOTPROG=\"zfsboot\" \
-mno-align-long-strings \
-mrtd \
-DBOOT2 \
-DFLAGS=${BOOT_BOOT1_FLAGS} \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
-DSIOFMT=${B2SIOFMT} \
-DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
@ -64,8 +60,7 @@ zfsldr.out: zfsldr.o
${LD} ${LDFLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} zfsldr.o
CLEANFILES+= zfsboot2 zfsboot.ld zfsboot.ldr zfsboot.bin zfsboot.out \
zfsboot.o zfsboot.s zfsboot.s.tmp xreadorg.h sio.o cons.o \
drv.o util.o
zfsboot.o zfsboot.s zfsboot.s.tmp sio.o cons.o drv.o util.o
# We currently allow 65536 bytes for zfsboot - in practice it could be
# any size up to 3.5Mb but keeping it fixed size simplifies zfsldr.
@ -92,20 +87,13 @@ zfsboot.out: ${BTXCRT} zfsboot.o sio.o drv.o cons.o util.o
zfsboot.o: zfsboot.s
SRCS= zfsboot.c xreadorg.h
SRCS= zfsboot.c
zfsboot.s: zfsboot.c xreadorg.h ${.CURDIR}/../../zfs/zfsimpl.c
zfsboot.s: zfsboot.c ${.CURDIR}/../../zfs/zfsimpl.c
${CC} ${CFLAGS} -S -o zfsboot.s.tmp ${.CURDIR}/zfsboot.c
sed -e '/align/d' -e '/nop/d' < zfsboot.s.tmp > zfsboot.s
rm -f zfsboot.s.tmp
xreadorg.h: zfsldr.out
${NM} -t d ${.ALLSRC} | awk '/([0-9])+ T xread/ \
{ x = $$1 - ORG1; \
printf("#define XREADORG %#x\n", REL1 + x) }' \
ORG1=`printf "%d" ${ORG1}` \
REL1=`printf "%d" ${REL1}` > ${.TARGET}
.if ${MACHINE_CPUARCH} == "amd64"
beforedepend zfsboot.s: machine
CLEANFILES+= machine

View File

@ -30,16 +30,12 @@
.set PRT_NUM,0x4 # Partitions
.set PRT_BSD,0xa5 # Partition type
/* Flag Bits */
.set FL_PACKET,0x80 # Packet mode
/* Misc. Constants */
.set SIZ_PAG,0x1000 # Page size
.set SIZ_SEC,0x200 # Sector size
.set NSECT,0x80
.globl start
.globl xread
.code16
start: jmp main # Start recognizably
@ -49,7 +45,7 @@ start: jmp main # Start recognizably
* 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.
* written into our code, 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
@ -80,34 +76,7 @@ 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:
*
* %ecx:%eax - long - LBA to read in
* %es:(%bx) - caddr_t - buffer to read data into
* %dl - byte - drive to read from
* %dh - byte - num sectors to read
*/
xread: push %ss # Address
pop %ds # data
/*
* Setup an EDD disk packet and pass it to read
*/
xread.1: pushl %ecx # Starting absolute block
pushl %eax # block number
push %es # Address of
push %bx # transfer buffer
xor %ax,%ax # Number of
movb %dh,%al # blocks to
push %ax # transfer
push $0x10 # Size of packet
mov %sp,%bp # Packet pointer
callw read # Read from disk
lea 0x10(%bp),%sp # Clear stack
lret # To far caller
/*
* Load the rest of boot2 and BTX up, copy the parts to the right locations,
* Load the rest of zfsboot2 and BTX up, copy the parts to the right locations,
* and start it all up.
*/
@ -181,7 +150,7 @@ main.4: xor %dx,%dx # Partition:drive
* itself to 0x9000 - doing it in this order means that none of the
* memcpy regions overlap which would corrupt the copy. Normally, BTX
* clients start at MEM_USR, or 0xa000, but when we use btxld to
* create boot2, we use an entry point of 0x2000. That entry point is
* create zfsboot2, we use an entry point of 0x2000. That entry point is
* relative to MEM_USR; thus boot2.bin starts at 0xc000.
*
* The load area and the target area for the client overlap so we have
@ -241,15 +210,29 @@ seta20.3: sti # Enable interrupts
/*
* Trampoline used to call read from within boot1.
* Trampoline used to call read from within zfsldr. Sets up an EDD
* packet on the stack and passes it to read.
*
* %eax - int - LBA to read in relative to partition start
* %dl - byte - drive to read from
* %dh - byte - num sectors to read
* %si - ptr - MBR partition entry
*/
nread: xor %eax,%eax # Sector offset in partition
nread.1: mov $MEM_BUF,%bx # Transfer buffer
xor %ecx,%ecx # Get
nread.1: xor %ecx,%ecx # Get
addl 0x8(%si),%eax # LBA
adc $0,%ecx
push %cs # Read from
callw xread.1 # disk
pushl %ecx # Starting absolute block
pushl %eax # block number
push %es # Address of
push $MEM_BUF # transfer buffer
xor %ax,%ax # Number of
movb %dh,%al # blocks to
push %ax # transfer
push $0x10 # Size of packet
mov %sp,%bp # Packet pointer
callw read # Read from disk
lea 0x10(%bp),%sp # Clear stack
jnc return # If success, return
mov $msg_read,%si # Otherwise, set the error
# message and fall through to
@ -293,9 +276,7 @@ return: retw # To caller
* %dl - byte - drive number
* stack - 10 bytes - EDD Packet
*/
read: testb $FL_PACKET,%cs:MEM_REL+flags-start # LBA support enabled?
jz read.1 # No, use CHS
cmpb $0x80,%dl # Hard drive?
read: cmpb $0x80,%dl # Hard drive?
jb read.1 # No, use CHS
mov $0x55aa,%bx # Magic
push %dx # Save
@ -311,73 +292,9 @@ read: testb $FL_PACKET,%cs:MEM_REL+flags-start # LBA support enabled?
movb $0x42,%ah # BIOS: Extended
int $0x13 # read
retw # To caller
#if 0
read.1: push %dx # Save
movb $0x8,%ah # BIOS: Get drive
int $0x13 # parameters
movb %dh,%ch # Max head number
pop %dx # Restore
jc return # If error
andb $0x3f,%cl # Sectors per track
jz ereturn # If zero
cli # Disable interrupts
mov 0x8(%bp),%eax # Get LBA
push %dx # Save
movzbl %cl,%ebx # Divide by
xor %edx,%edx # sectors
div %ebx # per track
movb %ch,%bl # Max head number
movb %dl,%ch # Sector number
inc %bx # Divide by
xorb %dl,%dl # number
div %ebx # of heads
movb %dl,%bh # Head number
pop %dx # Restore
cmpl $0x3ff,%eax # Cylinder number supportable?
sti # Enable interrupts
ja ereturn # No, return an error
xchgb %al,%ah # Set up cylinder
rorb $0x2,%al # number
orb %ch,%al # Merge
inc %ax # sector
xchg %ax,%cx # number
movb %bh,%dh # Head number
subb %ah,%al # Sectors this track
mov 0x2(%bp),%ah # Blocks to read
cmpb %ah,%al # To read
jb read.2 # this
#ifdef TRACK_AT_A_TIME
movb %ah,%al # track
#else
movb $1,%al # one sector
#endif
read.2: mov $0x5,%di # Try count
read.3: les 0x4(%bp),%bx # Transfer buffer
push %ax # Save
movb $0x2,%ah # BIOS: Read
int $0x13 # from disk
pop %bx # Restore
jnc read.4 # If success
dec %di # Retry?
jz read.6 # No
xorb %ah,%ah # BIOS: Reset
int $0x13 # disk system
xchg %bx,%ax # Block count
jmp read.3 # Continue
read.4: movzbw %bl,%ax # Sectors read
add %ax,0x8(%bp) # Adjust
jnc read.5 # LBA,
incw 0xa(%bp) # transfer
read.5: shlb %bl # buffer
add %bl,0x5(%bp) # pointer,
sub %al,0x2(%bp) # block count
ja read.1 # If not done
read.6: retw # To caller
#else
read.1: mov $msg_chs,%si
jmp error
msg_chs: .asciz "CHS not supported"
#endif
/* Messages */
@ -386,8 +303,6 @@ msg_part: .asciz "Boot"
prompt: .asciz " error\r\n"
flags: .byte FLAGS # Flags
.org PRT_OFF,0x90
/* Partition table */