Skip to content

Commit

Permalink
Fix long-standing bug in boot1 code - can read junk from fake partiti…
Browse files Browse the repository at this point in the history
…on table

boot1 reads the MBR to locate the BSD partition type (0xA5).  However, to
reduce the size of the boot1 code the 32 bit LBA for the MBR was being
loaded via the fake partition table at label 'part4', which was assumed to
contain a LBA of 0.  Unfortunately this portion of the boot1 code is not
usually written by the disklabel program and may contain garbage.

For the last few years we have worked around the issue by zeroing out
the label area before installing a new label.  We still have to do this
to avoid disklabel32/disklabel64 confusion, but with this fix forgetting
to zero the area should not cause a properly installed disklabel to fail
to boot properly.

To fix the problem, add the necessary instructions to generate a 32 bit
LBA of 0 directly for reading the MBR.  They barely fit.
  • Loading branch information
Matthew Dillon committed Feb 11, 2009
1 parent d07a93d commit 76adb3c
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions sys/boot/pc32/boot2/boot1.S
Expand Up @@ -143,6 +143,9 @@ xread.1: // Starting
// Setup the segment registers to flat addressing (segment 0) and setup the
// stack to end just below the start of our code.
//
// XXX note - our origin (start) points to the MEM_BIOS_LADDR. We run
// from there but boot2 later on calls xread at BOOT1_ORIGIN.
//
main: cld // String ops inc
xor %cx,%cx // Zero
mov %cx,%es // Address
Expand All @@ -160,16 +163,18 @@ main: cld // String ops inc
movsw // code
//
// If we are on a hard drive, then load the MBR and look for the first
// FreeBSD slice. We use the fake partition entry below that points to
// the MBR when we call nread. The first pass looks for the first active
// FreeBSD slice. The second pass looks for the first non-active FreeBSD
// slice if the first one fails.
// FreeBSD slice.
//
// Note, we can't use the fake partition entry (part4), as it may contain
// garbage if this is a normal boot1 on a slice, verses a dangerously
// dedicated disk. Hardwire sector 0 to acquire the MBR
//
mov $part4,%si // Partition
xor %ax,%ax
xor %cx,%cx
cmpb $0x80,%dl // Hard drive?
jb main.4 // No
movb $0x1,%dh // Block count
callw nread // Read MBR
callw nread_alt // Read MBR
mov $0x1,%cx // Two passes
main.1: mov $BOOT2_LOAD_BUF+PRT_OFF,%si // Partition table
movb $0x1,%dh // Partition
Expand Down Expand Up @@ -273,9 +278,11 @@ seta20.2: inb $0x64,%al // Get status
//
// Trampoline used to call read from within boot1.
//
nread: mov $BOOT2_LOAD_BUF,%bx // Transfer buffer
nread:
mov 0x8(%si),%ax // Get
mov 0xa(%si),%cx // LBA
nread_alt:
mov $BOOT2_LOAD_BUF,%bx // Transfer buffer
push %cs // Read from
callw xread.1 // disk
jnc return // If success, return
Expand Down Expand Up @@ -430,6 +437,10 @@ flags: .byte FLAGS // Flags
.org PRT_OFF,0x90

// Partition table
//
// THIS MAY NOT BE WRITTEN OUT TO THE BOOT1 AREA OF THE DISKLABEL. This
// section is only written out when the disklabel is placed on the raw
// disk instead of in a slice, when creating a dangerously dedicated disk.

.fill 0x30,0x1,0x0
part4: .byte 0x80, 0x00, 0x01, 0x00
Expand Down

0 comments on commit 76adb3c

Please sign in to comment.