mbr.s revision 62146
1239324Simp# 2239324Simp# Copyright (c) 1999 Robert Nordier 3239324Simp# All rights reserved. 4239324Simp# 5239324Simp# Redistribution and use in source and binary forms are freely 6239324Simp# permitted provided that the above copyright notice and this 7239324Simp# paragraph and the following disclaimer are duplicated in all 8239324Simp# such forms. 9239324Simp# 10239324Simp# This software is provided "AS IS" and without any express or 11239324Simp# implied warranties, including, without limitation, the implied 12239324Simp# warranties of merchantability and fitness for a particular 13239324Simp# purpose. 14239324Simp# 15239324Simp 16239324Simp# $FreeBSD: head/sys/boot/i386/mbr/mbr.s 62146 2000-06-26 23:58:04Z jhb $ 17239324Simp 18239324Simp# A 512 byte MBR boot manager that simply boots the active partition. 19239324Simp 20239324Simp .set LOAD,0x7c00 # Load address 21239324Simp .set EXEC,0x600 # Execution address 22239324Simp .set PT_OFF,0x1be # Partition table 23266328Sian .set MAGIC,0xaa55 # Magic: bootable 24239324Simp 25239324Simp .set NDRIVE,0x8 # Drives to support 26239324Simp 27266328Sian .globl start # Entry point 28266328Sian .code16 29266328Sian 30266328Sian# 31266328Sian# Setup the segment registers for flat addressing and setup the stack. 32266328Sian# 33266328Sianstart: cld # String ops inc 34266328Sian xorw %ax,%ax # Zero 35239324Simp movw %ax,%es # Address 36239324Simp movw %ax,%ds # data 37266328Sian cli # Disable interrupts 38266328Sian movw %ax,%ss # Set up 39266328Sian movw $LOAD,%sp # stack 40266328Sian sti # Enable interrupts 41239324Simp# 42239324Simp# Relocate ourself to a lower address so that we are out of the way when 43239324Simp# we load in the bootstrap from the partition to boot. 44266328Sian# 45266328Sian movw $main-EXEC+LOAD,%si # Source 46266328Sian movw $main,%di # Destination 47266328Sian movw $0x200-(main-start),%cx # Byte count 48266328Sian rep # Relocate 49266328Sian movsb # code 50266328Sian# 51266328Sian# Jump to the relocated code. 52266328Sian# 53266328Sian jmp main-LOAD+EXEC # To relocated code 54266328Sian# 55266328Sian# Scan the partition table looking for an active entry. Note that %ch is 56266328Sian# zero from the repeated string instruction above. We save the offset of 57239324Simp# the active partition in %si and scan the entire table to ensure that only 58239324Simp# one partition is marked active. 59239324Simp# 60239324Simpmain: xorw %si,%si # No active partition 61239324Simp movw $partbl,%bx # Partition table 62239324Simp movb $0x4,%cl # Number of entries 63239324Simpmain.1: cmpb %ch,(%bx) # Null entry? 64239324Simp je main.2 # Yes 65239324Simp jg err_pt # If 0x1..0x7f 66239324Simp testw %si,%si # Active already found? 67239324Simp jnz err_pt # Yes 68239324Simp movw %bx,%si # Point to active 69239324Simpmain.2: addb $0x10,%bl # Till 70239324Simp loop main.1 # done 71239324Simp testw %si,%si # Active found? 72239324Simp jnz main.3 # Yes 73239324Simp int $0x18 # BIOS: Diskless boot 74239324Simp# 75239324Simp# Ok, we've found a possible active partition. Check to see that the drive 76239324Simp# is a valid hard drive number. XXX - We assume that there are up to 8 valid 77266328Sian# hard drives, regardless of how many are actually installed. Yuck. 78266328Sian# 79266328Sianmain.3: cmpb $0x80,%dl # Drive valid? 80266328Sian jb main.4 # No 81266328Sian cmpb $0x80+NDRIVE,%dl # Within range? 82239324Simp jb main.5 # Yes 83239324Simp# 84239324Simp# Ok, now that we have a valid drive and partition entry, load the CHS from 85239324Simp# the partition entry and read the sector from the disk. 86239324Simp# 87239324Simpmain.4: movb (%si),%dl # Load drive 88239324Simpmain.5: movb 0x1(%si),%dh # Load head 89239324Simp movw 0x2(%si),%cx # Load cylinder:sector 90239324Simp movw $LOAD,%bx # Transfer buffer 91239324Simp movw $0x201,%ax # BIOS: Read from 92239324Simp int $0x13 # disk 93239324Simp jc err_rd # If error 94239324Simp# 95239324Simp# Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it 96239324Simp# is present, execute the bootstrap we just loaded. 97239324Simp# 98266328Sian cmpw $MAGIC,0x1fe(%bx) # Bootable? 99266328Sian jne err_os # No 100266328Sian jmp *%bx # Invoke bootstrap 101266328Sian# 102239324Simp# Various error message entry points. 103266328Sian# 104266328Sianerr_pt: movw $msg_pt,%si # "Invalid partition 105266328Sian jmp putstr # table" 106266328Sian 107239324Simperr_rd: movw $msg_rd,%si # "Error loading 108239324Simp jmp putstr # operating system" 109266328Sian 110266328Sianerr_os: movw $msg_os,%si # "Missing operating 111266328Sian jmp putstr # system" 112266328Sian# 113# Output an ASCIZ string to the console via the BIOS. 114# 115putstr.0: movw $0x7,%bx # Page:attribute 116 movb $0xe,%ah # BIOS: Display 117 int $0x10 # character 118putstr: lodsb # Get character 119 testb %al,%al # End of string? 120 jnz putstr.0 # No 121putstr.1: jmp putstr.1 # Await reset 122 123msg_pt: .asciz "Invalid partition table" 124msg_rd: .asciz "Error loading operating system" 125msg_os: .asciz "Missing operating system" 126 127 .org PT_OFF 128 129partbl: .fill 0x10,0x4,0x0 # Partition table 130 .word MAGIC # Magic number 131