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 $
19 # A 512 byte MBR boot manager that simply boots the active partition.
21 .set LOAD,0x7c00 # Load address
22 .set EXEC,0x600 # Execution address
23 .set PT_OFF,0x1be # Partition table
24 .set MAGIC,0xaa55 # Magic: bootable
26 .set NHRDRV,0x475 # Number of hard drives
28 .globl start # Entry point
32 # Setup the segment registers for flat addressing and setup the stack.
34 start
: cld
# String ops inc
36 movw
%ax
,%es
# Address
39 movw $LOAD
,%sp
# stack
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.
44 movw $main-EXEC+LOAD
,%si
# Source
45 movw $main
,%di
# Destination
46 movw $
0x200-(main-start
),%cx
# Byte count
50 # Jump to the relocated code.
52 jmp main-LOAD+EXEC
# To relocated code
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.
59 main
: xorw
%si
,%si
# No active partition
60 movw $partbl
,%bx
# Partition table
61 movb $
0x4,%cl
# Number of entries
62 main.1
: cmpb
%ch
,(%bx
) # Null entry?
64 jg err_pt
# If 0x1..0x7f
65 testw
%si
,%si
# Active already found?
67 movw
%bx
,%si
# Point to active
68 main.2
: addb $
0x10,%bl # Till
70 testw
%si
,%si
# Active found?
72 int $
0x18 # BIOS: Diskless boot
74 # Ok, we've found a possible active partition. Check to see that the drive
75 # is a valid hard drive number.
77 main.3
: cmpb $
0x80,%dl
# Drive valid?
79 movb NHRDRV
,%dh
# Calculate the highest
80 addb $
0x80,%dh
# drive number available
81 cmpb
%dh
,%dl
# Within range?
83 main.4
: movb
(%si
),%dl
# Load drive
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.
88 main.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 cmpb $
0xff,%dh
# Might we need to use LBA?
94 cmpw $
0xffff,%cx
# Do we need to use LBA?
98 movw $
0x55aa,%bx
# Magic
99 movb $
0x41,%ah
# BIOS: EDD extensions
102 cmpw $
0xaa55,%bx
# Magic ok?
104 testb $
0x1,%cl
# Packet mode present?
106 popw
%bx
# Restore %bx
107 pushl $
0x0 # Set the LBA
108 pushl
0x8(%si
) # address
109 pushw
%es
# Set the address of
110 pushw
%bx
# the transfer buffer
111 pushw $
0x1 # Read 1 sector
112 pushw $
0x10 # Packet length
113 movw
%sp
,%si
# Packer pointer
114 movw $
0x4200,%ax
# BIOS: LBA Read from disk
115 jmp main.8
# Skip the CHS setup
116 main.6
: popw
%bx
# Restore %bx
117 popw
%cx
# Restore %cx
118 main.7
: movw $
0x201,%ax
# BIOS: Read from disk
119 main.8
: int $
0x13 # Call the BIOS
120 movw
%di
,%sp
# Restore stack
123 # Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it
124 # is present, execute the bootstrap we just loaded.
126 cmpw $MAGIC
,0x1fe(%bx
) # Bootable?
128 jmp
*%bx
# Invoke bootstrap
130 # Various error message entry points.
132 err_pt
: movw $msg_pt
,%si
# "Invalid partition
135 err_rd
: movw $msg_rd
,%si
# "Error loading
136 jmp putstr
# operating system"
138 err_os
: movw $msg_os
,%si
# "Missing operating
141 # Output an ASCIZ string to the console via the BIOS.
143 putstr.0
: movw $
0x7,%bx
# Page:attribute
144 movb $
0xe,%ah
# BIOS: Display
145 int $
0x10 # character
146 putstr
: lodsb
# Get character
147 testb
%al
,%al
# End of string?
149 putstr.1
: jmp putstr.1
# Await reset
151 msg_pt
: .asciz "Invalid partition table"
152 msg_rd
: .asciz "Error loading operating system"
153 msg_os
: .asciz "Missing operating system"
157 partbl
: .fill 0x10,0x4,0x0 # Partition table
158 .word MAGIC # Magic number