loader: updates from review
[unleashed.git] / usr / src / boot / sys / boot / i386 / pmbr / pmbr.s
blob46088cc78c07f0607724ee28b31aadf603f266a7
1 #-
2 # Copyright (c) 2007 Yahoo!, Inc.
3 # All rights reserved.
4 # Written by: John Baldwin <jhb@FreeBSD.org>
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. Neither the name of the author nor the names of any co-contributors
15 # may be used to endorse or promote products derived from this software
16 # without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 # SUCH DAMAGE.
30 # $FreeBSD$
32 # Partly from: src/sys/boot/i386/mbr/mbr.s 1.7
34 # A 512 byte PMBR boot manager to read a boot program and run it.
35 # The embedded MBR is set up for PMBR and default bootblock sector
36 # is hardcoded to 256 and size 1. The actual values are supposed to be
37 # updated by installboot.
39 .set LOAD,0x7c00 # Load address
40 .set EXEC,0x600 # Execution address
41 .set MAGIC,0xaa55 # Magic: bootable
42 .set SECSIZE,0x200 # Size of a single disk sector
43 .set DISKSIG,440 # Disk signature offset
44 .set STACK,EXEC+SECSIZE*4 # Stack address
45 .set DPBUF,STACK
47 .set NHRDRV,0x475 # Number of hard drives
49 .globl start # Entry point
50 .code16
51 .text
53 start: jmp real_code
54 .fill 0x3c,0x1,0x90 # fill with nop to ease disasm
56 # BIOS Parameter Block. Reserved space from 0xb to 0x3e, the FAT32 BPB
57 # is 60 (3Ch) bytes.
59 . = start + 0x3e
62 # Setup the segment registers for flat addressing and setup the stack.
64 real_code: cld # String ops inc
65 xorw %ax,%ax # Zero
66 movw %ax,%es # Address
67 movw %ax,%ds # data
68 movw %ax,%ss # Set up
69 movw $STACK,%sp # stack
71 # Relocate ourself to a lower address so that we have more room to load
72 # other sectors.
74 movw $main-EXEC+LOAD,%si # Source
75 movw $main,%di # Destination
76 movw $SECSIZE-(main-start),%cx # Byte count
77 rep # Relocate
78 movsb # code
80 # Jump to the relocated code.
82 jmp main-LOAD+EXEC # To relocated code
84 # Validate drive number in %dl.
86 main: cmpb $0x80,%dl # Drive valid?
87 jb main.1 # No
88 movb NHRDRV,%dh # Calculate the highest
89 addb $0x80,%dh # drive number available
90 cmpb %dh,%dl # Within range?
91 jb main.2 # Yes
92 main.1: movb $0x80,%dl # Assume drive 0x80
94 # Load stage2 and start it. location and size is written by installboot
95 # and if size is 0, we can not do anything...
97 main.2: movw stage2_size, %ax
98 cmpw $0, %ax
99 je err_noboot # the stage2 size is not set
100 pushw %dx # save drive
101 movb $0x41, %ah # check extensions
102 movw $0x55aa, %bx
103 int $0x13
104 popw %dx # restore drive
105 jc err_rd # need lba mode for now
106 cmpw $0xaa55, %bx # chs support is not
107 jne err_rd # implemented.
108 movw $stage2_sector, %si # pointer to lba
109 movw $LOAD/16,%bx # set buffer segment
110 movw %bx,%es
111 xorw %bx,%bx # and offset
112 load_boot: push %si # Save %si
113 call read
114 pop %si # Restore
115 decw stage2_size # stage2_size--
116 jnz next_boot
117 boot: mov %bx,%es # Reset %es to zero
118 jmp LOAD # Jump to boot code
119 next_boot: incl (%si) # Next LBA
120 adcl $0,4(%si)
121 mov %es,%ax # Adjust segment for next
122 addw $SECSIZE/16,%ax # sector
123 mov %ax,%es #
124 jmp load_boot
126 # Load a sector (64-bit LBA at %si) from disk %dl into %es:%bx by creating
127 # a EDD packet on the stack and passing it to the BIOS. Trashes %ax and %si.
129 read: pushl 0x4(%si) # Set the LBA
130 pushl 0x0(%si) # address
131 pushw %es # Set the address of
132 pushw %bx # the transfer buffer
133 pushw $0x1 # Read 1 sector
134 pushw $0x10 # Packet length
135 movw %sp,%si # Packer pointer
136 movw $0x4200,%ax # BIOS: LBA Read from disk
137 int $0x13 # Call the BIOS
138 add $0x10,%sp # Restore stack
139 jc err_rd # If error
142 # Various error message entry points.
144 err_rd: movw $msg_rd,%si # "I/O error loading
145 jmp putstr # boot loader"
147 err_noboot: movw $msg_noboot,%si # "Missing boot
148 jmp putstr # loader"
150 # Output an ASCIZ string to the console via the BIOS.
152 putstr.0: movw $0x7,%bx # Page:attribute
153 movb $0xe,%ah # BIOS: Display
154 int $0x10 # character
155 putstr: lodsb # Get character
156 testb %al,%al # End of string?
157 jnz putstr.0 # No
158 putstr.1: jmp putstr.1 # Await reset
160 msg_rd: .asciz "I/O error"
161 msg_noboot: .asciz "No boot loader"
164 mbr_version: .byte 1, 1 # 1.1
165 .align 4
166 stage2_size: .word 1 # bootblock size in sectors
167 stage2_sector: .quad 256 # lba of bootblock
168 disk_uuid: .quad 0 # uuid
169 .quad 0
171 # this is the end of the code block we can use, next is space for
172 # signature, partition table 4 entries and signature.
173 .org DISKSIG,0x1b8 #
174 sig: .long 0 # OS Disk Signature
175 .word 0 # "Unknown" in PMBR
177 partbl: .byte 0x00 # non-bootable
178 .byte 0x00 # head 0
179 .byte 0x02 # sector
180 .byte 0x00 # cylinder
181 .byte 0xEE # ID
182 .byte 0xFF # ending head
183 .byte 0xFF # ending sector
184 .byte 0xFF # ending cylinder
185 .long 0x00000001 # starting LBA
186 .long 0xFFFFFFFF # size
187 .fill 0x10,0x3,0x0 # other 3 entries
188 .word MAGIC # Magic number