2 * Copyright (c) 1999 Robert Nordier
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
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
16 * $FreeBSD: src/sys/boot/i386/mbr/mbr.s,v 1.6 2000/06/27 20:04:10 jhb Exp $
17 * $DragonFly: src/sys/boot/pc32/mbr/mbr.s,v 1.3 2003/11/10 06:08:36 dillon Exp $
21 * A 512 byte MBR boot manager that simply boots the active partition.
24 .set LOAD,0x7c00 # Load address
25 .set EXEC,0x600 # Execution address
26 .set PT_OFF,0x1be # Partition table
27 .set MAGIC,0xaa55 # Magic: bootable
29 .set NHRDRV,0x475 # Number of hard drives
31 .globl start # Entry point
35 * Setup the segment registers for flat addressing and setup the stack.
37 start: cld # String ops inc
39 movw %ax,%es # Address
42 movw $LOAD,%sp # stack
44 * Relocate ourself to a lower address so that we are out of the way when
45 * we load in the bootstrap from the partition to boot.
47 movw $main-EXEC+LOAD,%si # Source
48 movw $main,%di # Destination
49 movw $0x200-(main-start),%cx # Byte count
53 * Jump to the relocated code.
55 jmp main-LOAD+EXEC # To relocated code
57 * Scan the partition table looking for an active entry. Note that %ch is
58 * zero from the repeated string instruction above. We save the offset of
59 * the active partition in %si and scan the entire table to ensure that only
60 * one partition is marked active.
62 main: xorw %si,%si # No active partition
63 movw $partbl,%bx # Partition table
64 movb $0x4,%cl # Number of entries
65 main.1: cmpb %ch,(%bx) # Null entry?
67 jg err_pt # If 0x1..0x7f
68 testw %si,%si # Active already found?
70 movw %bx,%si # Point to active
71 main.2: addb $0x10,%bl # Till
73 testw %si,%si # Active found?
75 int $0x18 # BIOS: Diskless boot
77 * Ok, we've found a possible active partition. Check to see that the drive
78 * is a valid hard drive number.
80 main.3: cmpb $0x80,%dl # Drive valid?
82 movb NHRDRV,%dh # Calculate the highest
83 addb $0x80,%dh # drive number available
84 cmpb %dh,%dl # Within range?
86 main.4: movb (%si),%dl # Load drive
88 * Ok, now that we have a valid drive and partition entry, load the CHS from
89 * the partition entry and read the sector from the disk.
91 main.5: movw %sp,%di # Save stack pointer
92 movb 0x1(%si),%dh # Load head
93 movw 0x2(%si),%cx # Load cylinder:sector
94 movw $LOAD,%bx # Transfer buffer
95 #ifdef AVOID_PACKET_MODE
96 cmpb $0xff,%dh # Might we need to use LBA?
98 cmpw $0xffff,%cx # Do we need to use LBA?
103 movw $0x55aa,%bx # Magic
104 movb $0x41,%ah # BIOS: EDD extensions
107 cmpw $0xaa55,%bx # Magic ok?
109 testb $0x1,%cl # Packet mode present?
111 popw %bx # Restore %bx
112 pushl $0x0 # Set the LBA
113 pushl 0x8(%si) # address
114 pushw %es # Set the address of
115 pushw %bx # the transfer buffer
116 pushw $0x1 # Read 1 sector
117 pushw $0x10 # Packet length
118 movw %sp,%si # Packer pointer
119 movw $0x4200,%ax # BIOS: LBA Read from disk
120 jmp main.8 # Skip the CHS setup
121 main.6: popw %bx # Restore %bx
122 popw %cx # Restore %cx
123 main.7: movw $0x201,%ax # BIOS: Read from disk
124 main.8: int $0x13 # Call the BIOS
125 movw %di,%sp # Restore stack
128 * Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it
129 * is present, execute the bootstrap we just loaded.
131 cmpw $MAGIC,0x1fe(%bx) # Bootable?
133 jmp *%bx # Invoke bootstrap
135 * Various error message entry points.
137 err_pt: movw $msg_pt,%si # "Invalid partition
140 err_rd: movw $msg_rd,%si # "Error loading
141 jmp putstr # operating system"
143 err_os: movw $msg_os,%si # "Missing operating
146 * Output an ASCIZ string to the console via the BIOS.
148 putstr.0: movw $0x7,%bx # Page:attribute
149 movb $0xe,%ah # BIOS: Display
150 int $0x10 # character
151 putstr: lodsb # Get character
152 testb %al,%al # End of string?
154 putstr.1: jmp putstr.1 # Await reset
156 msg_pt: .asciz "Invalid partition table"
157 msg_rd: .asciz "Error loading operating system"
158 msg_os: .asciz "Missing operating system"
162 partbl: .fill 0x10,0x4,0x0 # Partition table
163 .word MAGIC # Magic number