mbr.s revision 296373
1# 2# Copyright (c) 1999 Robert Nordier 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms are freely 6# permitted provided that the above copyright notice and this 7# paragraph and the following disclaimer are duplicated in all 8# such forms. 9# 10# This software is provided "AS IS" and without any express or 11# implied warranties, including, without limitation, the implied 12# warranties of merchantability and fitness for a particular 13# purpose. 14# 15 16# $FreeBSD: releng/10.3/sys/boot/i386/mbr/mbr.s 134431 2004-08-28 08:39:35Z yar $ 17 18# A 512 byte MBR boot manager that simply boots the active partition. 19 20 .set LOAD,0x7c00 # Load address 21 .set EXEC,0x600 # Execution address 22 .set PT_OFF,0x1be # Partition table 23 .set MAGIC,0xaa55 # Magic: bootable 24 .set FL_PACKET,0x80 # Flag: try EDD 25 26 .set NHRDRV,0x475 # Number of hard drives 27 28 .globl start # Entry point 29 .code16 30 31# 32# Setup the segment registers for flat addressing and setup the stack. 33# 34start: cld # String ops inc 35 xorw %ax,%ax # Zero 36 movw %ax,%es # Address 37 movw %ax,%ds # data 38 movw %ax,%ss # Set up 39 movw $LOAD,%sp # stack 40# 41# Relocate ourself to a lower address so that we are out of the way when 42# we load in the bootstrap from the partition to boot. 43# 44 movw $main-EXEC+LOAD,%si # Source 45 movw $main,%di # Destination 46 movw $0x200-(main-start),%cx # Byte count 47 rep # Relocate 48 movsb # code 49# 50# Jump to the relocated code. 51# 52 jmp main-LOAD+EXEC # To relocated code 53# 54# Scan the partition table looking for an active entry. Note that %ch is 55# zero from the repeated string instruction above. We save the offset of 56# the active partition in %si and scan the entire table to ensure that only 57# one partition is marked active. 58# 59main: xorw %si,%si # No active partition 60 movw $partbl,%bx # Partition table 61 movb $0x4,%cl # Number of entries 62main.1: cmpb %ch,(%bx) # Null entry? 63 je main.2 # Yes 64 jg err_pt # If 0x1..0x7f 65 testw %si,%si # Active already found? 66 jnz err_pt # Yes 67 movw %bx,%si # Point to active 68main.2: addb $0x10,%bl # Till 69 loop main.1 # done 70 testw %si,%si # Active found? 71 jnz main.3 # Yes 72 int $0x18 # BIOS: Diskless boot 73# 74# Ok, we've found a possible active partition. Check to see that the drive 75# is a valid hard drive number. 76# 77main.3: cmpb $0x80,%dl # Drive valid? 78 jb main.4 # No 79 movb NHRDRV,%dh # Calculate the highest 80 addb $0x80,%dh # drive number available 81 cmpb %dh,%dl # Within range? 82 jb main.5 # Yes 83main.4: movb (%si),%dl # Load drive 84# 85# Ok, now that we have a valid drive and partition entry, load the CHS from 86# the partition entry and read the sector from the disk. 87# 88main.5: movw %sp,%di # Save stack pointer 89 movb 0x1(%si),%dh # Load head 90 movw 0x2(%si),%cx # Load cylinder:sector 91 movw $LOAD,%bx # Transfer buffer 92 testb $FL_PACKET,flags # Try EDD? 93 jz main.7 # No. 94 pushw %cx # Save %cx 95 pushw %bx # Save %bx 96 movw $0x55aa,%bx # Magic 97 movb $0x41,%ah # BIOS: EDD extensions 98 int $0x13 # present? 99 jc main.6 # No. 100 cmpw $0xaa55,%bx # Magic ok? 101 jne main.6 # No. 102 testb $0x1,%cl # Packet mode present? 103 jz main.6 # No. 104 popw %bx # Restore %bx 105 pushl $0x0 # Set the LBA 106 pushl 0x8(%si) # address 107 pushw %es # Set the address of 108 pushw %bx # the transfer buffer 109 pushw $0x1 # Read 1 sector 110 pushw $0x10 # Packet length 111 movw %sp,%si # Packer pointer 112 movw $0x4200,%ax # BIOS: LBA Read from disk 113 jmp main.8 # Skip the CHS setup 114main.6: popw %bx # Restore %bx 115 popw %cx # Restore %cx 116main.7: movw $0x201,%ax # BIOS: Read from disk 117main.8: int $0x13 # Call the BIOS 118 movw %di,%sp # Restore stack 119 jc err_rd # If error 120# 121# Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it 122# is present, execute the bootstrap we just loaded. 123# 124 cmpw $MAGIC,0x1fe(%bx) # Bootable? 125 jne err_os # No 126 jmp *%bx # Invoke bootstrap 127# 128# Various error message entry points. 129# 130err_pt: movw $msg_pt,%si # "Invalid partition 131 jmp putstr # table" 132 133err_rd: movw $msg_rd,%si # "Error loading 134 jmp putstr # operating system" 135 136err_os: movw $msg_os,%si # "Missing operating 137 jmp putstr # system" 138# 139# Output an ASCIZ string to the console via the BIOS. 140# 141putstr.0: movw $0x7,%bx # Page:attribute 142 movb $0xe,%ah # BIOS: Display 143 int $0x10 # character 144putstr: lodsb # Get character 145 testb %al,%al # End of string? 146 jnz putstr.0 # No 147putstr.1: jmp putstr.1 # Await reset 148 149msg_pt: .asciz "Invalid partition table" 150msg_rd: .asciz "Error loading operating system" 151msg_os: .asciz "Missing operating system" 152 153 .org PT_OFF-1,0x90 154flags: .byte FLAGS # Flags 155 156partbl: .fill 0x10,0x4,0x0 # Partition table 157 .word MAGIC # Magic number 158