]> git.saurik.com Git - apple/boot.git/blob - i386/cdboot/cdboot.s
boot-132.tar.gz
[apple/boot.git] / i386 / cdboot / cdboot.s
1 ; Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
2 ;
3 ; @APPLE_LICENSE_HEADER_START@
4 ;
5 ; Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
6 ; Reserved. This file contains Original Code and/or Modifications of
7 ; Original Code as defined in and that are subject to the Apple Public
8 ; Source License Version 2.0 (the "License"). You may not use this file
9 ; except in compliance with the License. Please obtain a copy of the
10 ; License at http://www.apple.com/publicsource and read it before using
11 ; this file.
12 ;
13 ; The Original Code and all software distributed under the License are
14 ; distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 ; EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 ; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 ; FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
18 ; License for the specific language governing rights and limitations
19 ; under the License.
20 ;
21 ; @APPLE_LICENSE_HEADER_END@
22
23 DEBUG EQU 0
24
25 %macro DebugCharMacro 1
26 push ax
27 mov al, %1
28 call putc
29 pop ax
30 %endmacro
31 %macro DebugPauseMacro 0
32 push ax
33 call getc
34 pop ax
35 %endmacro
36
37 %if DEBUG
38 %define DebugChar(x) DebugCharMacro x
39 %define DebugPause(x) DebugPauseMacro
40 %else
41 %define DebugChar(x)
42 %define DebugPause(x)
43 %endif
44
45 kBoot2Sectors EQU 126 ; sectors to load for boot2
46 kBoot2Address EQU 0x0200 ; boot2 load address
47 kBoot2Segment EQU 0x2000 ; boot2 load segment
48
49 kBoot0Stack EQU 0xFFF0 ; boot0 stack pointer
50
51 kReadBuffer EQU 0x1000 ; disk data buffer address
52
53 kVolSectorOffset EQU 0x47 ; offset in buffer of sector number
54 ; in volume descriptor
55 kBootSectorOffset EQU 0x28 ; offset in boot catalog
56 ; of sector number to load boot file
57 kBootCountOffset EQU 0x26 ; offset in boot catalog
58 ; of number of sectors to read
59
60
61 code16
62 ORG 0x7c00
63
64 SEGMENT .text
65
66 start:
67 cli
68 jmp 0:start1
69 times 8-($-$$) nop ; Put boot information table at offset 8
70
71 ; El Torito boot information table, filled in by the
72 ; mkisofs -boot-info-table option, if used.
73 bi_pvd: dd 0 ; LBA of primary volume descriptor
74 bi_file: dd 0 ; LBA of boot file
75 bi_length: dd 0 ; Length of boot file
76 bi_csum: dd 0 ; Checksum of boot file
77 bi_reserved: times 10 dd 0 ; Reserved
78
79 start1:
80 xor ax, ax ; zero %ax
81 mov ss, ax ; setup the
82 mov sp, kBoot0Stack ; stack
83 sti
84 cld ; increment SI after each lodsb call
85 mov ds, ax ; setup the
86 mov es, ax ; data segments
87 ;; BIOS boot drive is in DL
88
89 DebugChar('!')
90 DebugPause()
91
92 %if DEBUG
93 mov eax, [kBoot2LoadAddr]
94 call print_hex
95 call getc
96 %endif
97
98 ;;
99 ;; The BIOS likely didn't load the rest of the booter,
100 ;; so we have to fetch it ourselves.
101 ;;
102 xor ax, ax
103 mov es, ax
104 mov bx, kReadBuffer
105 mov al, 1
106 mov ecx, 17
107 call read_lba
108 jc error
109
110 DebugChar('A')
111
112 mov ecx, [kReadBuffer + kVolSectorOffset]
113 %if DEBUG
114 mov eax, ecx
115 call print_hex
116 DebugPause()
117 %endif
118 mov al, 1
119 call read_lba
120 jc error
121
122 ;; Now we have the boot catalog in the buffer.
123 ;; Really we should look at the validation entry, but oh well.
124
125 DebugChar('B')
126
127 mov ecx, [kReadBuffer + kBootSectorOffset]
128 inc ecx ; skip the first sector which is what we are in
129 %if DEBUG
130 mov eax, ecx
131 call print_hex
132 DebugPause()
133 %endif
134
135 mov ax, kBoot2Segment
136 mov es, ax
137
138 mov al, kBoot2Sectors / 4
139 mov bx, kBoot2Address
140 call read_lba
141 jc error
142
143 DebugChar('C')
144 %if DEBUG
145 mov eax, [es:kBoot2Address]
146 call print_hex
147 DebugPause()
148 %endif
149
150 xor ax, ax
151 mov es, ax
152
153 DebugChar('X')
154 DebugPause()
155
156 ;; Jump to newly-loaded booter
157 jmp kBoot2Segment:kBoot2Address
158
159 error:
160 mov al, 'E'
161 call putc
162 hlt
163
164 ;;
165 ;; Support functions
166 ;;
167
168 ;--------------------------------------------------------------------------
169 ; read_lba - Read sectors from CD using LBA addressing.
170 ;
171 ; Arguments:
172 ; AL = number of 2048-byte sectors to read (valid from 1-127).
173 ; ES:BX = pointer to where the sectors should be stored.
174 ; ECX = sector offset in partition
175 ; DL = drive number (0x80 + unit number)
176 ;
177 ; Returns:
178 ; CF = 0 success
179 ; 1 error
180 ;
181 read_lba:
182 pushad ; save all registers
183 mov bp, sp ; save current SP
184
185 ;
186 ; Create the Disk Address Packet structure for the
187 ; INT13/F42 (Extended Read Sectors) on the stack.
188 ;
189
190 ; push DWORD 0 ; offset 12, upper 32-bit LBA
191 push ds ; For sake of saving memory,
192 push ds ; push DS register, which is 0.
193
194 push ecx
195
196 push es ; offset 6, memory segment
197
198 push bx ; offset 4, memory offset
199
200 xor ah, ah ; offset 3, must be 0
201 push ax ; offset 2, number of sectors
202
203 push WORD 16 ; offset 0-1, packet size
204
205 ;
206 ; INT13 Func 42 - Extended Read Sectors
207 ;
208 ; Arguments:
209 ; AH = 0x42
210 ; DL = drive number (80h + drive unit)
211 ; DS:SI = pointer to Disk Address Packet
212 ;
213 ; Returns:
214 ; AH = return status (sucess is 0)
215 ; carry = 0 success
216 ; 1 error
217 ;
218 ; Packet offset 2 indicates the number of sectors read
219 ; successfully.
220 ;
221 mov si, sp
222 mov ah, 0x42
223 int 0x13
224
225 jnc .exit
226
227 DebugChar('R') ; indicate INT13/F42 error
228
229 ;
230 ; Issue a disk reset on error.
231 ; Should this be changed to Func 0xD to skip the diskette controller
232 ; reset?
233 ;
234 xor ax, ax ; Func 0
235 int 0x13 ; INT 13
236 stc ; set carry to indicate error
237
238 .exit:
239 mov sp, bp ; restore SP
240 popad
241 ret
242
243 ;;
244 ;; Display a single character from AL.
245 ;;
246 putc: pushad
247 mov bx, 0x1 ; attribute for output
248 mov ah, 0xe ; BIOS: put_char
249 int 0x10 ; call BIOS, print char in %al
250 popad
251 ret
252
253 ;;
254 ;; Get a character from the keyboard and return it in AL.
255 ;;
256 getc: mov ah, 0
257 int 0x16
258 ret
259
260 %if DEBUG
261 ;--------------------------------------------------------------------------
262 ; Write the 4-byte value to the console in hex.
263 ;
264 ; Arguments:
265 ; EAX = Value to be displayed in hex.
266 ;
267 print_hex:
268 pushad
269 mov cx, WORD 4
270 bswap eax
271 .loop
272 push ax
273 ror al, 4
274 call print_nibble ; display upper nibble
275 pop ax
276 call print_nibble ; display lower nibble
277 ror eax, 8
278 loop .loop
279
280 mov al, 10 ; carriage return
281 call putc
282 mov al, 13
283 call putc
284 popad
285 ret
286
287 print_nibble:
288 and al, 0x0f
289 add al, '0'
290 cmp al, '9'
291 jna .print_ascii
292 add al, 'A' - '9' - 1
293 .print_ascii:
294 call putc
295 ret
296
297 %endif ; DEBUG
298
299
300
301 ;; Pad this file to a size of 2048 bytes (one CD sector).
302 pad:
303 times 2048-($-$$) db 0
304
305 ;; Location of loaded boot2 code.
306 kBoot2LoadAddr equ $
307
308 END