diff options
Diffstat (limited to 'stand/i386/mbr')
-rw-r--r-- | stand/i386/mbr/Makefile | 17 | ||||
-rw-r--r-- | stand/i386/mbr/Makefile.depend | 11 | ||||
-rw-r--r-- | stand/i386/mbr/mbr.s | 157 |
3 files changed, 185 insertions, 0 deletions
diff --git a/stand/i386/mbr/Makefile b/stand/i386/mbr/Makefile new file mode 100644 index 0000000..9bfa0bd --- /dev/null +++ b/stand/i386/mbr/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +PROG= mbr +STRIP= +BINMODE=${NOBINMODE} +MAN= +SRCS= ${PROG}.s + +# MBR flags: 0x80 -- try packet interface (also known as EDD or LBA) +BOOT_MBR_FLAGS?= 0x80 + +ORG= 0x600 + +AFLAGS+=--defsym FLAGS=${BOOT_MBR_FLAGS} +LDFLAGS+=${LDFLAGS_BIN} + +.include <bsd.prog.mk> diff --git a/stand/i386/mbr/Makefile.depend b/stand/i386/mbr/Makefile.depend new file mode 100644 index 0000000..f80275d --- /dev/null +++ b/stand/i386/mbr/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/i386/mbr/mbr.s b/stand/i386/mbr/mbr.s new file mode 100644 index 0000000..3cfc20d --- /dev/null +++ b/stand/i386/mbr/mbr.s @@ -0,0 +1,157 @@ +# +# Copyright (c) 1999 Robert Nordier +# All rights reserved. +# +# Redistribution and use in source and binary forms are freely +# permitted provided that the above copyright notice and this +# paragraph and the following disclaimer are duplicated in all +# such forms. +# +# This software is provided "AS IS" and without any express or +# implied warranties, including, without limitation, the implied +# warranties of merchantability and fitness for a particular +# purpose. +# + +# $FreeBSD$ + +# A 512 byte MBR boot manager that simply boots the active partition. + + .set LOAD,0x7c00 # Load address + .set EXEC,0x600 # Execution address + .set PT_OFF,0x1be # Partition table + .set MAGIC,0xaa55 # Magic: bootable + .set FL_PACKET,0x80 # Flag: try EDD + + .set NHRDRV,0x475 # Number of hard drives + + .globl start # Entry point + .code16 + +# +# Setup the segment registers for flat addressing and setup the stack. +# +start: cld # String ops inc + xorw %ax,%ax # Zero + movw %ax,%es # Address + movw %ax,%ds # data + movw %ax,%ss # Set up + movw $LOAD,%sp # stack +# +# 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. +# + movw $main-EXEC+LOAD,%si # Source + movw $main,%di # Destination + movw $0x200-(main-start),%cx # Byte count + rep # Relocate + movsb # code +# +# Jump to the relocated code. +# + jmp main-LOAD+EXEC # To relocated code +# +# Scan the partition table looking for an active entry. Note that %ch is +# zero from the repeated string instruction above. We save the offset of +# the active partition in %si and scan the entire table to ensure that only +# one partition is marked active. +# +main: xorw %si,%si # No active partition + movw $partbl,%bx # Partition table + movb $0x4,%cl # Number of entries +main.1: cmpb %ch,(%bx) # Null entry? + je main.2 # Yes + jg err_pt # If 0x1..0x7f + testw %si,%si # Active already found? + jnz err_pt # Yes + movw %bx,%si # Point to active +main.2: addb $0x10,%bl # Till + loop main.1 # done + testw %si,%si # Active found? + jnz main.3 # Yes + 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. +# +main.3: cmpb $0x80,%dl # Drive valid? + jb main.4 # No + 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.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 + testb $FL_PACKET,flags # Try EDD? + jz 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 +# is present, execute the bootstrap we just loaded. +# + cmpw $MAGIC,0x1fe(%bx) # Bootable? + jne err_os # No + jmp *%bx # Invoke bootstrap +# +# Various error message entry points. +# +err_pt: movw $msg_pt,%si # "Invalid partition + jmp putstr # table" + +err_rd: movw $msg_rd,%si # "Error loading + jmp putstr # operating system" + +err_os: movw $msg_os,%si # "Missing operating + jmp putstr # system" +# +# Output an ASCIZ string to the console via the BIOS. +# +putstr.0: movw $0x7,%bx # Page:attribute + movb $0xe,%ah # BIOS: Display + int $0x10 # character +putstr: lodsb # Get character + testb %al,%al # End of string? + jnz putstr.0 # No +putstr.1: jmp putstr.1 # Await reset + +msg_pt: .asciz "Invalid partition table" +msg_rd: .asciz "Error loading operating system" +msg_os: .asciz "Missing operating system" + + .org PT_OFF-1,0x90 +flags: .byte FLAGS # Flags + +partbl: .fill 0x10,0x4,0x0 # Partition table + .word MAGIC # Magic number |