#1# Copyright (c) 1999 Robert Nordier2# All rights reserved.3#4# Redistribution and use in source and binary forms are freely5# permitted provided that the above copyright notice and this6# paragraph and the following disclaimer are duplicated in all7# such forms.8#9# This software is provided "AS IS" and without any express or10# implied warranties, including, without limitation, the implied11# warranties of merchantability and fitness for a particular12# purpose.13#1415# A 512 byte MBR boot manager that simply boots the active partition.1617.set LOAD,0x7c00 # Load address18.set EXEC,0x600 # Execution address19.set PT_OFF,0x1be # Partition table20.set MAGIC,0xaa55 # Magic: bootable21.set FL_PACKET,0x80 # Flag: try EDD2223.set NHRDRV,0x475 # Number of hard drives2425.globl start # Entry point26.code162728#29# Setup the segment registers for flat addressing and setup the stack.30#31start: cld # String ops inc32xorw %ax,%ax # Zero33movw %ax,%es # Address34movw %ax,%ds # data35movw %ax,%ss # Set up36movw $LOAD,%sp # stack37#38# Relocate ourself to a lower address so that we are out of the way when39# we load in the bootstrap from the partition to boot.40#41movw $main-EXEC+LOAD,%si # Source42movw $main,%di # Destination43movw $0x200-(main-start),%cx # Byte count44rep # Relocate45movsb # code46#47# Jump to the relocated code.48#49jmp main-LOAD+EXEC # To relocated code50#51# Scan the partition table looking for an active entry. Note that %ch is52# zero from the repeated string instruction above. We save the offset of53# the active partition in %si and scan the entire table to ensure that only54# one partition is marked active.55#56main: xorw %si,%si # No active partition57movw $partbl,%bx # Partition table58movb $0x4,%cl # Number of entries59main.1: cmpb %ch,(%bx) # Null entry?60je main.2 # Yes61jg err_pt # If 0x1..0x7f62testw %si,%si # Active already found?63jnz err_pt # Yes64movw %bx,%si # Point to active65main.2: addb $0x10,%bl # Till66loop main.1 # done67testw %si,%si # Active found?68jnz main.3 # Yes69int $0x18 # BIOS: Diskless boot70#71# Ok, we've found a possible active partition. Check to see that the drive72# is a valid hard drive number.73#74main.3: cmpb $0x80,%dl # Drive valid?75jb main.4 # No76movb NHRDRV,%dh # Calculate the highest77addb $0x80,%dh # drive number available78cmpb %dh,%dl # Within range?79jb main.5 # Yes80main.4: movb (%si),%dl # Load drive81#82# Ok, now that we have a valid drive and partition entry, load the CHS from83# the partition entry and read the sector from the disk.84#85main.5: movw %sp,%di # Save stack pointer86movb 0x1(%si),%dh # Load head87movw 0x2(%si),%cx # Load cylinder:sector88movw $LOAD,%bx # Transfer buffer89testb $FL_PACKET,flags # Try EDD?90jz main.7 # No.91pushw %cx # Save %cx92pushw %bx # Save %bx93movw $0x55aa,%bx # Magic94movb $0x41,%ah # BIOS: EDD extensions95int $0x13 # present?96jc main.6 # No.97cmpw $0xaa55,%bx # Magic ok?98jne main.6 # No.99testb $0x1,%cl # Packet mode present?100jz main.6 # No.101popw %bx # Restore %bx102pushl $0x0 # Set the LBA103pushl 0x8(%si) # address104pushw %es # Set the address of105pushw %bx # the transfer buffer106pushw $0x1 # Read 1 sector107pushw $0x10 # Packet length108movw %sp,%si # Packer pointer109movw $0x4200,%ax # BIOS: LBA Read from disk110jmp main.8 # Skip the CHS setup111main.6: popw %bx # Restore %bx112popw %cx # Restore %cx113main.7: movw $0x201,%ax # BIOS: Read from disk114main.8: int $0x13 # Call the BIOS115movw %di,%sp # Restore stack116jc err_rd # If error117#118# Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it119# is present, execute the bootstrap we just loaded.120#121cmpw $MAGIC,0x1fe(%bx) # Bootable?122jne err_os # No123jmp *%bx # Invoke bootstrap124#125# Various error message entry points.126#127err_pt: movw $msg_pt,%si # "Invalid partition128jmp putstr # table"129130err_rd: movw $msg_rd,%si # "Error loading131jmp putstr # operating system"132133err_os: movw $msg_os,%si # "Missing operating134jmp putstr # system"135#136# Output an ASCIZ string to the console via the BIOS.137#138putstr.0: movw $0x7,%bx # Page:attribute139movb $0xe,%ah # BIOS: Display140int $0x10 # character141putstr: lodsb # Get character142testb %al,%al # End of string?143jnz putstr.0 # No144putstr.1: jmp putstr.1 # Await reset145146msg_pt: .asciz "Invalid partition table"147msg_rd: .asciz "Error loading operating system"148msg_os: .asciz "Missing operating system"149150.org PT_OFF-1,0x90151flags: .byte FLAGS # Flags152153partbl: .fill 0x10,0x4,0x0 # Partition table154.word MAGIC # Magic number155156157