Fully synchronize sys/boot from FreeBSD-5.x, but add / to the module path
[dragonfly.git] / sys / boot / i386 / mbr / mbr.s
CommitLineData
984263bc
MD
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
5ee58eed
MD
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/i386/mbr/Attic/mbr.s,v 1.3 2003/11/10 06:08:36 dillon Exp $
984263bc
MD
18
19# A 512 byte MBR boot manager that simply boots the active partition.
20
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
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 cmpb $0xff,%dh # Might we need to use LBA?
93 jnz main.7 # No.
94 cmpw $0xffff,%cx # Do we need to use LBA?
95 jnz main.7 # No.
96 pushw %cx # Save %cx
97 pushw %bx # Save %bx
98 movw $0x55aa,%bx # Magic
99 movb $0x41,%ah # BIOS: EDD extensions
100 int $0x13 # present?
101 jc main.6 # No.
102 cmpw $0xaa55,%bx # Magic ok?
103 jne main.6 # No.
104 testb $0x1,%cl # Packet mode present?
105 jz main.6 # No.
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
116main.6: popw %bx # Restore %bx
117 popw %cx # Restore %cx
118main.7: movw $0x201,%ax # BIOS: Read from disk
119main.8: int $0x13 # Call the BIOS
120 movw %di,%sp # Restore stack
121 jc err_rd # If error
122#
123# Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it
124# is present, execute the bootstrap we just loaded.
125#
126 cmpw $MAGIC,0x1fe(%bx) # Bootable?
127 jne err_os # No
128 jmp *%bx # Invoke bootstrap
129#
130# Various error message entry points.
131#
132err_pt: movw $msg_pt,%si # "Invalid partition
133 jmp putstr # table"
134
135err_rd: movw $msg_rd,%si # "Error loading
136 jmp putstr # operating system"
137
138err_os: movw $msg_os,%si # "Missing operating
139 jmp putstr # system"
140#
141# Output an ASCIZ string to the console via the BIOS.
142#
143putstr.0: movw $0x7,%bx # Page:attribute
144 movb $0xe,%ah # BIOS: Display
145 int $0x10 # character
146putstr: lodsb # Get character
147 testb %al,%al # End of string?
148 jnz putstr.0 # No
149putstr.1: jmp putstr.1 # Await reset
150
151msg_pt: .asciz "Invalid partition table"
152msg_rd: .asciz "Error loading operating system"
153msg_os: .asciz "Missing operating system"
154
155 .org PT_OFF
156
157partbl: .fill 0x10,0x4,0x0 # Partition table
158 .word MAGIC # Magic number