Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/i386/mbr/mbr.S
34860 views
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
16
# A 512 byte MBR boot manager that simply boots the active partition.
17
18
.set LOAD,0x7c00 # Load address
19
.set EXEC,0x600 # Execution address
20
.set PT_OFF,0x1be # Partition table
21
.set MAGIC,0xaa55 # Magic: bootable
22
.set FL_PACKET,0x80 # Flag: try EDD
23
24
.set NHRDRV,0x475 # Number of hard drives
25
26
.globl start # Entry point
27
.code16
28
29
#
30
# Setup the segment registers for flat addressing and setup the stack.
31
#
32
start: cld # String ops inc
33
xorw %ax,%ax # Zero
34
movw %ax,%es # Address
35
movw %ax,%ds # data
36
movw %ax,%ss # Set up
37
movw $LOAD,%sp # stack
38
#
39
# Relocate ourself to a lower address so that we are out of the way when
40
# we load in the bootstrap from the partition to boot.
41
#
42
movw $main-EXEC+LOAD,%si # Source
43
movw $main,%di # Destination
44
movw $0x200-(main-start),%cx # Byte count
45
rep # Relocate
46
movsb # code
47
#
48
# Jump to the relocated code.
49
#
50
jmp main-LOAD+EXEC # To relocated code
51
#
52
# Scan the partition table looking for an active entry. Note that %ch is
53
# zero from the repeated string instruction above. We save the offset of
54
# the active partition in %si and scan the entire table to ensure that only
55
# one partition is marked active.
56
#
57
main: xorw %si,%si # No active partition
58
movw $partbl,%bx # Partition table
59
movb $0x4,%cl # Number of entries
60
main.1: cmpb %ch,(%bx) # Null entry?
61
je main.2 # Yes
62
jg err_pt # If 0x1..0x7f
63
testw %si,%si # Active already found?
64
jnz err_pt # Yes
65
movw %bx,%si # Point to active
66
main.2: addb $0x10,%bl # Till
67
loop main.1 # done
68
testw %si,%si # Active found?
69
jnz main.3 # Yes
70
int $0x18 # BIOS: Diskless boot
71
#
72
# Ok, we've found a possible active partition. Check to see that the drive
73
# is a valid hard drive number.
74
#
75
main.3: cmpb $0x80,%dl # Drive valid?
76
jb main.4 # No
77
movb NHRDRV,%dh # Calculate the highest
78
addb $0x80,%dh # drive number available
79
cmpb %dh,%dl # Within range?
80
jb main.5 # Yes
81
main.4: movb (%si),%dl # Load drive
82
#
83
# Ok, now that we have a valid drive and partition entry, load the CHS from
84
# the partition entry and read the sector from the disk.
85
#
86
main.5: movw %sp,%di # Save stack pointer
87
movb 0x1(%si),%dh # Load head
88
movw 0x2(%si),%cx # Load cylinder:sector
89
movw $LOAD,%bx # Transfer buffer
90
testb $FL_PACKET,flags # Try EDD?
91
jz main.7 # No.
92
pushw %cx # Save %cx
93
pushw %bx # Save %bx
94
movw $0x55aa,%bx # Magic
95
movb $0x41,%ah # BIOS: EDD extensions
96
int $0x13 # present?
97
jc main.6 # No.
98
cmpw $0xaa55,%bx # Magic ok?
99
jne main.6 # No.
100
testb $0x1,%cl # Packet mode present?
101
jz main.6 # No.
102
popw %bx # Restore %bx
103
pushl $0x0 # Set the LBA
104
pushl 0x8(%si) # address
105
pushw %es # Set the address of
106
pushw %bx # the transfer buffer
107
pushw $0x1 # Read 1 sector
108
pushw $0x10 # Packet length
109
movw %sp,%si # Packer pointer
110
movw $0x4200,%ax # BIOS: LBA Read from disk
111
jmp main.8 # Skip the CHS setup
112
main.6: popw %bx # Restore %bx
113
popw %cx # Restore %cx
114
main.7: movw $0x201,%ax # BIOS: Read from disk
115
main.8: int $0x13 # Call the BIOS
116
movw %di,%sp # Restore stack
117
jc err_rd # If error
118
#
119
# Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it
120
# is present, execute the bootstrap we just loaded.
121
#
122
cmpw $MAGIC,0x1fe(%bx) # Bootable?
123
jne err_os # No
124
jmp *%bx # Invoke bootstrap
125
#
126
# Various error message entry points.
127
#
128
err_pt: movw $msg_pt,%si # "Invalid partition
129
jmp putstr # table"
130
131
err_rd: movw $msg_rd,%si # "Error loading
132
jmp putstr # operating system"
133
134
err_os: movw $msg_os,%si # "Missing operating
135
jmp putstr # system"
136
#
137
# Output an ASCIZ string to the console via the BIOS.
138
#
139
putstr.0: movw $0x7,%bx # Page:attribute
140
movb $0xe,%ah # BIOS: Display
141
int $0x10 # character
142
putstr: lodsb # Get character
143
testb %al,%al # End of string?
144
jnz putstr.0 # No
145
putstr.1: jmp putstr.1 # Await reset
146
147
msg_pt: .asciz "Invalid partition table"
148
msg_rd: .asciz "Error loading operating system"
149
msg_os: .asciz "Missing operating system"
150
151
.org PT_OFF-1,0x90
152
flags: .byte FLAGS # Flags
153
154
partbl: .fill 0x10,0x4,0x0 # Partition table
155
.word MAGIC # Magic number
156
157