199767f8919635c4928607450d9e0abb932109ceToomas Soome#-
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Copyright (c) 2007 Yahoo!, Inc.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Written by: John Baldwin <jhb@FreeBSD.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome# modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome# are met:
199767f8919635c4928607450d9e0abb932109ceToomas Soome# 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome# notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome# notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome# documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# 3. Neither the name of the author nor the names of any co-contributors
199767f8919635c4928607450d9e0abb932109ceToomas Soome# may be used to endorse or promote products derived from this software
199767f8919635c4928607450d9e0abb932109ceToomas Soome# without specific prior written permission.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199767f8919635c4928607450d9e0abb932109ceToomas Soome# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199767f8919635c4928607450d9e0abb932109ceToomas Soome# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199767f8919635c4928607450d9e0abb932109ceToomas Soome# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199767f8919635c4928607450d9e0abb932109ceToomas Soome# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199767f8919635c4928607450d9e0abb932109ceToomas Soome# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
199767f8919635c4928607450d9e0abb932109ceToomas Soome# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
199767f8919635c4928607450d9e0abb932109ceToomas Soome# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
199767f8919635c4928607450d9e0abb932109ceToomas Soome# SUCH DAMAGE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# $FreeBSD$
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Partly from: src/sys/boot/i386/mbr/mbr.s 1.7
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome# A 512 byte PMBR boot manager to read a boot program and run it.
199767f8919635c4928607450d9e0abb932109ceToomas Soome# The embedded MBR is set up for PMBR and default bootblock sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome# is hardcoded to 256 and size 1. The actual values are supposed to be
199767f8919635c4928607450d9e0abb932109ceToomas Soome# updated by installboot.
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set LOAD,0x7c00 # Load address
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set EXEC,0x600 # Execution address
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set MAGIC,0xaa55 # Magic: bootable
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set SECSIZE,0x200 # Size of a single disk sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DISKSIG,440 # Disk signature offset
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set STACK,EXEC+SECSIZE*4 # Stack address
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set DPBUF,STACK
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome .set NHRDRV,0x475 # Number of hard drives
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome .globl start # Entry point
199767f8919635c4928607450d9e0abb932109ceToomas Soome .code16
199767f8919635c4928607450d9e0abb932109ceToomas Soome .text
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestart: jmp real_code
199767f8919635c4928607450d9e0abb932109ceToomas Soome .fill 0x3c,0x1,0x90 # fill with nop to ease disasm
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# BIOS Parameter Block. Reserved space from 0xb to 0x3e, the FAT32 BPB
199767f8919635c4928607450d9e0abb932109ceToomas Soome# is 60 (3Ch) bytes.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome . = start + 0x3e
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Setup the segment registers for flat addressing and setup the stack.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomereal_code: cld # String ops inc
199767f8919635c4928607450d9e0abb932109ceToomas Soome xorw %ax,%ax # Zero
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw %ax,%es # Address
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw %ax,%ds # data
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw %ax,%ss # Set up
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $STACK,%sp # stack
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Relocate ourself to a lower address so that we have more room to load
199767f8919635c4928607450d9e0abb932109ceToomas Soome# other sectors.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $main-EXEC+LOAD,%si # Source
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $main,%di # Destination
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $SECSIZE-(main-start),%cx # Byte count
199767f8919635c4928607450d9e0abb932109ceToomas Soome rep # Relocate
199767f8919635c4928607450d9e0abb932109ceToomas Soome movsb # code
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Jump to the relocated code.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp main-LOAD+EXEC # To relocated code
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Validate drive number in %dl.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomemain: cmpb $0x80,%dl # Drive valid?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jb main.1 # No
199767f8919635c4928607450d9e0abb932109ceToomas Soome movb NHRDRV,%dh # Calculate the highest
199767f8919635c4928607450d9e0abb932109ceToomas Soome addb $0x80,%dh # drive number available
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpb %dh,%dl # Within range?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jb main.2 # Yes
199767f8919635c4928607450d9e0abb932109ceToomas Soomemain.1: movb $0x80,%dl # Assume drive 0x80
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Load stage2 and start it. location and size is written by installboot
199767f8919635c4928607450d9e0abb932109ceToomas Soome# and if size is 0, we can not do anything...
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomemain.2: movw stage2_size, %ax
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpw $0, %ax
199767f8919635c4928607450d9e0abb932109ceToomas Soome je err_noboot # the stage2 size is not set
199767f8919635c4928607450d9e0abb932109ceToomas Soome pushw %dx # save drive
199767f8919635c4928607450d9e0abb932109ceToomas Soome movb $0x41, %ah # check extensions
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $0x55aa, %bx
199767f8919635c4928607450d9e0abb932109ceToomas Soome int $0x13
199767f8919635c4928607450d9e0abb932109ceToomas Soome popw %dx # restore drive
199767f8919635c4928607450d9e0abb932109ceToomas Soome jc err_rd # need lba mode for now
199767f8919635c4928607450d9e0abb932109ceToomas Soome cmpw $0xaa55, %bx # chs support is not
199767f8919635c4928607450d9e0abb932109ceToomas Soome jne err_rd # implemented.
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $stage2_sector, %si # pointer to lba
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $LOAD/16,%bx # set buffer segment
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw %bx,%es
199767f8919635c4928607450d9e0abb932109ceToomas Soome xorw %bx,%bx # and offset
199767f8919635c4928607450d9e0abb932109ceToomas Soomeload_boot: push %si # Save %si
199767f8919635c4928607450d9e0abb932109ceToomas Soome call read
199767f8919635c4928607450d9e0abb932109ceToomas Soome pop %si # Restore
199767f8919635c4928607450d9e0abb932109ceToomas Soome decw stage2_size # stage2_size--
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz next_boot
199767f8919635c4928607450d9e0abb932109ceToomas Soomeboot: mov %bx,%es # Reset %es to zero
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp LOAD # Jump to boot code
199767f8919635c4928607450d9e0abb932109ceToomas Soomenext_boot: incl (%si) # Next LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome adcl $0,4(%si)
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %es,%ax # Adjust segment for next
199767f8919635c4928607450d9e0abb932109ceToomas Soome addw $SECSIZE/16,%ax # sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome mov %ax,%es #
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp load_boot
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Load a sector (64-bit LBA at %si) from disk %dl into %es:%bx by creating
199767f8919635c4928607450d9e0abb932109ceToomas Soome# a EDD packet on the stack and passing it to the BIOS. Trashes %ax and %si.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeread: pushl 0x4(%si) # Set the LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome pushl 0x0(%si) # address
199767f8919635c4928607450d9e0abb932109ceToomas Soome pushw %es # Set the address of
199767f8919635c4928607450d9e0abb932109ceToomas Soome pushw %bx # the transfer buffer
199767f8919635c4928607450d9e0abb932109ceToomas Soome pushw $0x1 # Read 1 sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome pushw $0x10 # Packet length
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw %sp,%si # Packer pointer
199767f8919635c4928607450d9e0abb932109ceToomas Soome movw $0x4200,%ax # BIOS: LBA Read from disk
199767f8919635c4928607450d9e0abb932109ceToomas Soome int $0x13 # Call the BIOS
199767f8919635c4928607450d9e0abb932109ceToomas Soome add $0x10,%sp # Restore stack
199767f8919635c4928607450d9e0abb932109ceToomas Soome jc err_rd # If error
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Various error message entry points.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeerr_rd: movw $msg_rd,%si # "I/O error loading
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp putstr # boot loader"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeerr_noboot: movw $msg_noboot,%si # "Missing boot
199767f8919635c4928607450d9e0abb932109ceToomas Soome jmp putstr # loader"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soome# Output an ASCIZ string to the console via the BIOS.
199767f8919635c4928607450d9e0abb932109ceToomas Soome#
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputstr.0: movw $0x7,%bx # Page:attribute
199767f8919635c4928607450d9e0abb932109ceToomas Soome movb $0xe,%ah # BIOS: Display
199767f8919635c4928607450d9e0abb932109ceToomas Soome int $0x10 # character
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputstr: lodsb # Get character
199767f8919635c4928607450d9e0abb932109ceToomas Soome testb %al,%al # End of string?
199767f8919635c4928607450d9e0abb932109ceToomas Soome jnz putstr.0 # No
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputstr.1: jmp putstr.1 # Await reset
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_rd: .asciz "I/O error"
199767f8919635c4928607450d9e0abb932109ceToomas Soomemsg_noboot: .asciz "No boot loader"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome nop
199767f8919635c4928607450d9e0abb932109ceToomas Soomembr_version: .byte 1, 1 # 1.1
199767f8919635c4928607450d9e0abb932109ceToomas Soome .align 4
199767f8919635c4928607450d9e0abb932109ceToomas Soomestage2_size: .word 1 # bootblock size in sectors
199767f8919635c4928607450d9e0abb932109ceToomas Soomestage2_sector: .quad 256 # lba of bootblock
199767f8919635c4928607450d9e0abb932109ceToomas Soomedisk_uuid: .quad 0 # uuid
199767f8919635c4928607450d9e0abb932109ceToomas Soome .quad 0
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome# this is the end of the code block we can use, next is space for
199767f8919635c4928607450d9e0abb932109ceToomas Soome# signature, partition table 4 entries and signature.
199767f8919635c4928607450d9e0abb932109ceToomas Soome .org DISKSIG,0x1b8 #
199767f8919635c4928607450d9e0abb932109ceToomas Soomesig: .long 0 # OS Disk Signature
199767f8919635c4928607450d9e0abb932109ceToomas Soome .word 0 # "Unknown" in PMBR
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomepartbl: .byte 0x00 # non-bootable
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0x00 # head 0
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0x02 # sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0x00 # cylinder
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0xEE # ID
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0xFF # ending head
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0xFF # ending sector
199767f8919635c4928607450d9e0abb932109ceToomas Soome .byte 0xFF # ending cylinder
199767f8919635c4928607450d9e0abb932109ceToomas Soome .long 0x00000001 # starting LBA
199767f8919635c4928607450d9e0abb932109ceToomas Soome .long 0xFFFFFFFF # size
199767f8919635c4928607450d9e0abb932109ceToomas Soome .fill 0x10,0x3,0x0 # other 3 entries
199767f8919635c4928607450d9e0abb932109ceToomas Soome .word MAGIC # Magic number