summaryrefslogtreecommitdiffstats
path: root/sys/boot/i386/mbr
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2000-06-27 20:04:10 +0000
committerjhb <jhb@FreeBSD.org>2000-06-27 20:04:10 +0000
commite1ff78731ad01f85afcecf591d27d92b831e77f5 (patch)
tree3d95fcb5e8df6188fafe6677d92e5100c1ce47b9 /sys/boot/i386/mbr
parente4ec9bc987b83294929e1bdb59f552f9f97a6322 (diff)
downloadFreeBSD-src-e1ff78731ad01f85afcecf591d27d92b831e77f5.zip
FreeBSD-src-e1ff78731ad01f85afcecf591d27d92b831e77f5.tar.gz
- Don't blindly assume that there are 8 hard drives installed. Instead,
use the BIOS Equipment List to determine how many hard drives are installed and if the drive number we received in %dl is valid. - Don't bother to disable interrupts when setting up the stack. The 8086 and beyond implicitly disable interrupts after an instruction that sets %ss (for example, a pop or a mov) so that you can safely set %ss and %sp in two consecutive instructions. An exception to this is the lss instruction, which can set both registers simultaneously and thus doesn't need this hack. - Add support for EDD BIOS extensions to support booting off of hard drives of nearly arbitrary length.
Diffstat (limited to 'sys/boot/i386/mbr')
-rw-r--r--sys/boot/i386/mbr/mbr.s47
1 files changed, 37 insertions, 10 deletions
diff --git a/sys/boot/i386/mbr/mbr.s b/sys/boot/i386/mbr/mbr.s
index c8a55b6..9cd39d2 100644
--- a/sys/boot/i386/mbr/mbr.s
+++ b/sys/boot/i386/mbr/mbr.s
@@ -22,7 +22,7 @@
.set PT_OFF,0x1be # Partition table
.set MAGIC,0xaa55 # Magic: bootable
- .set NDRIVE,0x8 # Drives to support
+ .set NHRDRV,0x475 # Number of hard drives
.globl start # Entry point
.code16
@@ -34,10 +34,8 @@ start: cld # String ops inc
xorw %ax,%ax # Zero
movw %ax,%es # Address
movw %ax,%ds # data
- cli # Disable interrupts
movw %ax,%ss # Set up
movw $LOAD,%sp # stack
- sti # Enable interrupts
#
# Relocate ourself to a lower address so that we are out of the way when
# we load in the bootstrap from the partition to boot.
@@ -73,23 +71,52 @@ main.2: addb $0x10,%bl # Till
int $0x18 # BIOS: Diskless boot
#
# Ok, we've found a possible active partition. Check to see that the drive
-# is a valid hard drive number. XXX - We assume that there are up to 8 valid
-# hard drives, regardless of how many are actually installed. Yuck.
+# is a valid hard drive number.
#
main.3: cmpb $0x80,%dl # Drive valid?
jb main.4 # No
- cmpb $0x80+NDRIVE,%dl # Within range?
+ movb NHRDRV,%dh # Calculate the highest
+ addb $0x80,%dh # drive number available
+ cmpb %dh,%dl # Within range?
jb main.5 # Yes
+main.4: movb (%si),%dl # Load drive
#
# Ok, now that we have a valid drive and partition entry, load the CHS from
# the partition entry and read the sector from the disk.
#
-main.4: movb (%si),%dl # Load drive
-main.5: movb 0x1(%si),%dh # Load head
+main.5: movw %sp,%di # Save stack pointer
+ movb 0x1(%si),%dh # Load head
movw 0x2(%si),%cx # Load cylinder:sector
movw $LOAD,%bx # Transfer buffer
- movw $0x201,%ax # BIOS: Read from
- int $0x13 # disk
+ cmpb $0xff,%dh # Might we need to use LBA?
+ jnz main.7 # No.
+ cmpw $0xffff,%cx # Do we need to use LBA?
+ jnz main.7 # No.
+ pushw %cx # Save %cx
+ pushw %bx # Save %bx
+ movw $0x55aa,%bx # Magic
+ movb $0x41,%ah # BIOS: EDD extensions
+ int $0x13 # present?
+ jc main.6 # No.
+ cmpw $0xaa55,%bx # Magic ok?
+ jne main.6 # No.
+ testb $0x1,%cl # Packet mode present?
+ jz main.6 # No.
+ popw %bx # Restore %bx
+ pushl $0x0 # Set the LBA
+ pushl 0x8(%si) # address
+ pushw %es # Set the address of
+ pushw %bx # the transfer buffer
+ pushw $0x1 # Read 1 sector
+ pushw $0x10 # Packet length
+ movw %sp,%si # Packer pointer
+ movw $0x4200,%ax # BIOS: LBA Read from disk
+ jmp main.8 # Skip the CHS setup
+main.6: popw %bx # Restore %bx
+ popw %cx # Restore %cx
+main.7: movw $0x201,%ax # BIOS: Read from disk
+main.8: int $0x13 # Call the BIOS
+ movw %di,%sp # Restore stack
jc err_rd # If error
#
# Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it
OpenPOWER on IntegriCloud