Magellan Linux

Contents of /trunk/mkinitrd-magellan/isolinux/isolinux.lst

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 7 months ago) by niro
File size: 498694 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 1 ; -*- fundamental -*- (asm-mode sucks)
2 2 ; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
3 3 ; ****************************************************************************
4 4 ;
5 5 ; isolinux.asm
6 6 ;
7 7 ; A program to boot Linux kernels off a CD-ROM using the El Torito
8 8 ; boot standard in "no emulation" mode, making the entire filesystem
9 9 ; available. It is based on the SYSLINUX boot loader for MS-DOS
10 10 ; floppies.
11 11 ;
12 12 ; Copyright (C) 1994-2005 H. Peter Anvin
13 13 ;
14 14 ; This program is free software; you can redistribute it and/or modify
15 15 ; it under the terms of the GNU General Public License as published by
16 16 ; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
17 17 ; Boston MA 02111-1307, USA; either version 2 of the License, or
18 18 ; (at your option) any later version; incorporated herein by reference.
19 19 ;
20 20 ; ****************************************************************************
21 21
22 22 %define IS_ISOLINUX 1
23 23 %include "macros.inc"
24 24 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
25 25 <1> ;; -----------------------------------------------------------------------
26 26 <1> ;;
27 27 <1> ;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
28 28 <1> ;;
29 29 <1> ;; This program is free software; you can redistribute it and/or modify
30 30 <1> ;; it under the terms of the GNU General Public License as published by
31 31 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
32 32 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
33 33 <1> ;; (at your option) any later version; incorporated herein by reference.
34 34 <1> ;;
35 35 <1> ;; -----------------------------------------------------------------------
36 36 <1>
37 37 <1> ;;
38 38 <1> ;; macros.inc
39 39 <1> ;;
40 40 <1> ;; Convenient macros
41 41 <1> ;;
42 42 <1>
43 43 <1> %ifndef _MACROS_INC
44 44 <1> %define _MACROS_INC
45 45 <1>
46 46 <1> ;
47 47 <1> ; Identify the module we're compiling; the "correct" should be defined
48 48 <1> ; in the module itself to 1
49 49 <1> ;
50 50 <1> %ifndef IS_SYSLINUX
51 51 <1> %define IS_SYSLINUX 0
52 52 <1> %endif
53 53 <1> %ifndef IS_MDSLINUX
54 54 <1> %define IS_MDSLINUX 0
55 55 <1> %endif
56 56 <1> %ifndef IS_PXELINUX
57 57 <1> %define IS_PXELINUX 0
58 58 <1> %endif
59 59 <1> %ifndef IS_ISOLINUX
60 60 <1> %define IS_ISOLINUX 0
61 61 <1> %endif
62 62 <1> %ifndef IS_EXTLINUX
63 63 <1> %define IS_EXTLINUX 0
64 64 <1> %endif
65 65 <1>
66 66 <1> ;
67 67 <1> ; Macros similar to res[bwd], but which works in the code segment (after
68 68 <1> ; section .text) or the data segment (section .data)
69 69 <1> ;
70 70 <1> %macro zb 1.nolist
71 71 <1> times %1 db 0
72 72 <1> %endmacro
73 73 <1>
74 74 <1> %macro zw 1.nolist
75 75 <1> times %1 dw 0
76 76 <1> %endmacro
77 77 <1>
78 78 <1> %macro zd 1.nolist
79 79 <1> times %1 dd 0
80 80 <1> %endmacro
81 81 <1>
82 82 <1> ;
83 83 <1> ; Macro to emit an unsigned decimal number as a string
84 84 <1> ;
85 85 <1> %macro asciidec 1.nolist
86 86 <1> %ifndef DEPEND ; Not safe for "depend"
87 87 <1> %if %1 >= 1000000000
88 88 <1> db ((%1/1000000000) % 10) + '0'
89 89 <1> %endif
90 90 <1> %if %1 >= 100000000
91 91 <1> db ((%1/100000000) % 10) + '0'
92 92 <1> %endif
93 93 <1> %if %1 >= 10000000
94 94 <1> db ((%1/10000000) % 10) + '0'
95 95 <1> %endif
96 96 <1> %if %1 >= 1000000
97 97 <1> db ((%1/1000000) % 10) + '0'
98 98 <1> %endif
99 99 <1> %if %1 >= 100000
100 100 <1> db ((%1/100000) % 10) + '0'
101 101 <1> %endif
102 102 <1> %if %1 >= 10000
103 103 <1> db ((%1/10000) % 10) + '0'
104 104 <1> %endif
105 105 <1> %if %1 >= 1000
106 106 <1> db ((%1/1000) % 10) + '0'
107 107 <1> %endif
108 108 <1> %if %1 >= 100
109 109 <1> db ((%1/100) % 10) + '0'
110 110 <1> %endif
111 111 <1> %if %1 >= 10
112 112 <1> db ((%1/10) % 10) + '0'
113 113 <1> %endif
114 114 <1> db (%1 % 10) + '0'
115 115 <1> %endif
116 116 <1> %endmacro
117 117 <1>
118 118 <1> ;
119 119 <1> ; Macros for network byte order of constants
120 120 <1> ;
121 121 <1> %define htons(x) ( ( ((x) & 0FFh) << 8 ) + ( ((x) & 0FF00h) >> 8 ) )
122 122 <1> %define ntohs(x) htons(x)
123 123 <1> %define htonl(x) ( ( ((x) & 0FFh) << 24) + ( ((x) & 0FF00h) << 8 ) + ( ((x) & 0FF0000h) >> 8 ) + ( ((x) & 0FF000000h) >> 24) )
124 124 <1> %define ntohl(x) htonl(x)
125 125 <1>
126 126 <1> ;
127 127 <1> ; ASCII
128 128 <1> ;
129 129 <1> CR equ 13 ; Carriage Return
130 130 <1> LF equ 10 ; Line Feed
131 131 <1> FF equ 12 ; Form Feed
132 132 <1> BS equ 8 ; Backspace
133 133 <1>
134 134 <1> %endif ; _MACROS_INC
135 135 %include "config.inc"
136 136 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
137 137 <1> ;; -----------------------------------------------------------------------
138 138 <1> ;;
139 139 <1> ;; Copyright 2002-2005 H. Peter Anvin - All Rights Reserved
140 140 <1> ;;
141 141 <1> ;; This program is free software; you can redistribute it and/or modify
142 142 <1> ;; it under the terms of the GNU General Public License as published by
143 143 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
144 144 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
145 145 <1> ;; (at your option) any later version; incorporated herein by reference.
146 146 <1> ;;
147 147 <1> ;; -----------------------------------------------------------------------
148 148 <1>
149 149 <1> ;;
150 150 <1> ;; config.inc
151 151 <1> ;;
152 152 <1> ;; Common configuration options. Some of these are imposed by the kernel.
153 153 <1> ;;
154 154 <1>
155 155 <1> %ifndef _CONFIG_INC
156 156 <1> %define _CONFIG_INC
157 157 <1>
158 158 <1> max_cmd_len equ 511 ; Must be &3; 255 is the kernel limit
159 159 <1> HIGHMEM_MAX equ 037FFFFFFh ; DEFAULT highest address for an initrd
160 160 <1> DEFAULT_BAUD equ 9600 ; Default baud rate for serial port
161 161 <1> BAUD_DIVISOR equ 115200 ; Serial port parameter
162 162 <1>
163 163 <1> %assign DO_WBINVD 0 ; Should we use WBINVD or not?
164 164 <1>
165 165 <1> ;
166 166 <1> ; Version number definitinons
167 167 <1> ;
168 168 <1> %ifndef DEPEND ; Generated file
169 169 <1> %include "version.gen"
170 170 <2> %define VERSION "3.11"
171 171 <2> %define VER_MAJOR 3
172 172 <2> %define VER_MINOR 11
173 173 <1> %endif
174 174 <1>
175 175 <1> ;
176 176 <1> ; Should be updated with every release to avoid bootsector/SYS file mismatch
177 177 <1> ;
178 178 <1> %define version_str VERSION ; Must be 4 characters long!
179 179 <1> %define date DATE_STR ; Defined from the Makefile
180 180 <1> %define year '2005'
181 181 <1>
182 182 <1> %endif ; _CONFIG_INC
183 183 %include "kernel.inc"
184 184 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
185 185 <1> ;; -----------------------------------------------------------------------
186 186 <1> ;;
187 187 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
188 188 <1> ;;
189 189 <1> ;; This program is free software; you can redistribute it and/or modify
190 190 <1> ;; it under the terms of the GNU General Public License as published by
191 191 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
192 192 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
193 193 <1> ;; (at your option) any later version; incorporated herein by reference.
194 194 <1> ;;
195 195 <1> ;; -----------------------------------------------------------------------
196 196 <1>
197 197 <1> ;;
198 198 <1> ;; kernel.inc
199 199 <1> ;;
200 200 <1> ;; Header file for the kernel interface definitions
201 201 <1> ;;
202 202 <1>
203 203 <1> %ifndef _KERNEL_INC
204 204 <1> %define _KERNEL_INC
205 205 <1>
206 206 <1> ;;
207 207 <1> ;; Structure of the real_mode_seg
208 208 <1> ;;
209 209 <1>
210 210 <1> struc real_mode_seg_t
211 211 00000000 <res 00000020> <1> resb 20h-($-$$) ; org 20h
212 212 00000020 <res 00000002> <1> kern_cmd_magic resw 1 ; 0020 Magic # for command line
213 213 00000022 <res 00000002> <1> kern_cmd_offset resw 1 ; 0022 Offset for kernel command line
214 214 00000024 <res 000001CD> <1> resb 497-($-$$) ; org 497d
215 215 000001F1 <res 00000001> <1> bs_setupsecs resb 1 ; 01F1 Sectors for setup code (0 -> 4)
216 216 000001F2 <res 00000002> <1> bs_rootflags resw 1 ; 01F2 Root readonly flag
217 217 000001F4 <res 00000002> <1> bs_syssize resw 1 ; 01F4
218 218 000001F6 <res 00000002> <1> bs_swapdev resw 1 ; 01F6 Swap device (obsolete)
219 219 000001F8 <res 00000002> <1> bs_ramsize resw 1 ; 01F8 Ramdisk flags, formerly ramdisk size
220 220 000001FA <res 00000002> <1> bs_vidmode resw 1 ; 01FA Video mode
221 221 000001FC <res 00000002> <1> bs_rootdev resw 1 ; 01FC Root device
222 222 000001FE <res 00000002> <1> bs_bootsign resw 1 ; 01FE Boot sector signature (0AA55h)
223 223 00000200 <res 00000001> <1> su_jump resb 1 ; 0200 0EBh
224 224 00000201 <res 00000001> <1> su_jump2 resb 1 ; 0201 Size of following header
225 225 00000202 <res 00000004> <1> su_header resd 1 ; 0202 New setup code: header
226 226 00000206 <res 00000002> <1> su_version resw 1 ; 0206 See linux/arch/i386/boot/setup.S
227 227 00000208 <res 00000002> <1> su_switch resw 1 ; 0208
228 228 0000020A <res 00000002> <1> su_setupseg resw 1 ; 020A
229 229 0000020C <res 00000002> <1> su_startsys resw 1 ; 020C
230 230 0000020E <res 00000002> <1> su_kver resw 1 ; 020E Kernel version pointer
231 231 00000210 <res 00000001> <1> su_loader resb 1 ; 0210 Loader ID
232 232 00000211 <res 00000001> <1> su_loadflags resb 1 ; 0211 Load high flag
233 233 00000212 <res 00000002> <1> su_movesize resw 1 ; 0212
234 234 00000214 <res 00000004> <1> su_code32start resd 1 ; 0214 Start of code loaded high
235 235 00000218 <res 00000004> <1> su_ramdiskat resd 1 ; 0218 Start of initial ramdisk
236 236 0000021C <res 00000004> <1> su_ramdisklen resd 1 ; 021C Length of initial ramdisk
237 237 00000220 <res 00000002> <1> su_bsklugeoffs resw 1 ; 0220
238 238 00000222 <res 00000002> <1> su_bsklugeseg resw 1 ; 0222
239 239 00000224 <res 00000002> <1> su_heapend resw 1 ; 0224
240 240 00000226 <res 00000002> <1> su_pad1 resw 1 ; 0226
241 241 00000228 <res 00000004> <1> su_cmd_line_ptr resd 1 ; 0228
242 242 0000022C <res 00000004> <1> su_ramdisk_max resd 1 ; 022C
243 243 00000230 <res 00008DC4> <1> resb (9000h-12)-($-$$) ; Were bootsect.S puts it...
244 244 <1> linux_stack equ $ ; 8FF4
245 245 <1> linux_fdctab equ $
246 246 00008FF4 <res 0000000C> <1> resb 9000h-($-$$)
247 247 <1> cmd_line_here equ $ ; 9000 Should be out of the way
248 248 <1> endstruc
249 249 <1>
250 250 <1> ;
251 251 <1> ; Kernel command line signature
252 252 <1> ;
253 253 <1> CMD_MAGIC equ 0A33Fh ; Command line magic
254 254 <1>
255 255 <1> ;
256 256 <1> ; Magic number of su_header field
257 257 <1> ;
258 258 <1> HEADER_ID equ 'HdrS' ; HdrS (in littleendian hex)
259 259 <1>
260 260 <1> ;
261 261 <1> ; Flags for the su_loadflags field
262 262 <1> ;
263 263 <1> LOAD_HIGH equ 01h ; Large kernel, load high
264 264 <1> CAN_USE_HEAP equ 80h ; Boot loader reports heap size
265 265 <1>
266 266 <1> ;
267 267 <1> ; ID codes for various modules
268 268 <1> ;
269 269 <1> syslinux_id equ 031h ; 3 = SYSLINUX family; 1 = SYSLINUX
270 270 <1> pxelinux_id equ 032h ; 3 = SYSLINUX family; 2 = PXELINUX
271 271 <1> isolinux_id equ 033h ; 3 = SYSLINUX family; 3 = ISOLINUX
272 272 <1> extlinux_id equ 034h ; 3 = SYSLINUX family; 4 = EXTLINUX
273 273 <1>
274 274 <1> %endif ; _KERNEL_INC
275 275 %include "bios.inc"
276 276 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
277 277 <1> ;; -----------------------------------------------------------------------
278 278 <1> ;;
279 279 <1> ;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
280 280 <1> ;;
281 281 <1> ;; This program is free software; you can redistribute it and/or modify
282 282 <1> ;; it under the terms of the GNU General Public License as published by
283 283 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
284 284 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
285 285 <1> ;; (at your option) any later version; incorporated herein by reference.
286 286 <1> ;;
287 287 <1> ;; -----------------------------------------------------------------------
288 288 <1>
289 289 <1> ;;
290 290 <1> ;; bios.inc
291 291 <1> ;;
292 292 <1> ;; Header file for the BIOS data structures etc.
293 293 <1> ;;
294 294 <1>
295 295 <1> %ifndef _BIOS_INC
296 296 <1> %define _BIOS_INC
297 297 <1>
298 298 <1> absolute 4*1Eh ; In the interrupt table
299 299 <1> fdctab equ $
300 300 00000078 <res 00000002> <1> fdctab1 resw 1
301 301 0000007A <res 00000002> <1> fdctab2 resw 1
302 302 <1> absolute 0400h
303 303 00000400 <res 00000008> <1> serial_base resw 4 ; Base addresses for 4 serial ports
304 304 <1> absolute 0413h
305 305 00000413 <res 00000002> <1> BIOS_fbm resw 1 ; Free Base Memory (kilobytes)
306 306 <1> absolute 0462h
307 307 00000462 <res 00000001> <1> BIOS_page resb 1 ; Current video page
308 308 <1> absolute 046Ch
309 309 0000046C <res 00000002> <1> BIOS_timer resw 1 ; Timer ticks
310 310 <1> absolute 0472h
311 311 00000472 <res 00000002> <1> BIOS_magic resw 1 ; BIOS reset magic
312 312 <1> absolute 0484h
313 313 00000484 <res 00000001> <1> BIOS_vidrows resb 1 ; Number of screen rows
314 314 <1>
315 315 <1> %endif ; _BIOS_INC
316 316 %include "tracers.inc"
317 317 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
318 318 <1> ;; -----------------------------------------------------------------------
319 319 <1> ;;
320 320 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
321 321 <1> ;;
322 322 <1> ;; This program is free software; you can redistribute it and/or modify
323 323 <1> ;; it under the terms of the GNU General Public License as published by
324 324 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
325 325 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
326 326 <1> ;; (at your option) any later version; incorporated herein by reference.
327 327 <1> ;;
328 328 <1> ;; -----------------------------------------------------------------------
329 329 <1>
330 330 <1> ;;
331 331 <1> ;; tracers.inc
332 332 <1> ;;
333 333 <1> ;; Debugging tracers
334 334 <1> ;;
335 335 <1>
336 336 <1> %ifndef _TRACERS_INC
337 337 <1> %define _TRACERS_INC
338 338 <1>
339 339 <1> ; Note: The Makefile builds one version with DEBUG_MESSAGES automatically.
340 340 <1> ; %define DEBUG_TRACERS 1 ; Uncomment to get debugging tracers
341 341 <1> ; %define DEBUG_MESSAGES ; Uncomment to get debugging messages
342 342 <1>
343 343 <1> %ifdef DEBUG_TRACERS
344 344 <1>
345 345 <1> %macro TRACER 1
346 346 <1> call debug_tracer
347 347 <1> db %1
348 348 <1> %endmacro
349 349 <1>
350 350 <1> %else ; DEBUG_TRACERS
351 351 <1>
352 352 <1> %macro TRACER 1
353 353 <1> %endmacro
354 354 <1>
355 355 <1> %endif ; DEBUG_TRACERS
356 356 <1>
357 357 <1> %endif ; _TRACERS_INC
358 358 %include "layout.inc"
359 359 <1> ; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
360 360 <1> ; -----------------------------------------------------------------------
361 361 <1> ;
362 362 <1> ; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
363 363 <1> ;
364 364 <1> ; This program is free software; you can redistribute it and/or modify
365 365 <1> ; it under the terms of the GNU General Public License as published by
366 366 <1> ; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
367 367 <1> ; Bostom MA 02111-1307, USA; either version 2 of the License, or
368 368 <1> ; (at your option) any later version; incorporated herein by reference.
369 369 <1> ;
370 370 <1> ; -----------------------------------------------------------------------
371 371 <1>
372 372 <1> ;
373 373 <1> ; layout.inc
374 374 <1> ;
375 375 <1> ; Memory layout of segments
376 376 <1> ;
377 377 <1>
378 378 <1>
379 379 <1> ; Memory below 0800h is reserved for the BIOS and the MBR.
380 380 <1> BSS_START equ 0800h
381 381 <1>
382 382 <1> ; Text starts at the load address of 07C00h.
383 383 <1> TEXT_START equ 7C00h
384 384 <1>
385 385 <1> ; The secondary BSS section, above the text; we really wish we could
386 386 <1> ; just make it follow .bcopy32 or hang off the end,
387 387 <1> ; but it doesn't seem to work that way.
388 388 <1> LATEBSS_START equ 0B000h
389 389 <1>
390 390 <1> ; Reserve memory for the stack. This causes checkov to abort the
391 391 <1> ; compile if we violate this space.
392 392 <1> STACK_SIZE equ 4096
393 393 <1> STACK_START equ TEXT_START-STACK_SIZE
394 394 <1>
395 395 <1> %ifdef MAP
396 396 <1> [map all MAP]
397 397 <1> %endif
398 398 <1>
399 399 <1> ;
400 400 <1> ; The various sections and their relationship
401 401 <1> ;
402 402 <1> org TEXT_START
403 403 <1>
404 404 <1> ; NASM BUG: refers to hacks to handle NASM 0.98.38 bugs; might need
405 405 <1> ; conditional compilation
406 406 <1>
407 407 <1> section .earlybss nobits start=BSS_START
408 408 <1> section .bcopy32 align=4 valign=16 follows=.data vfollows=.earlybss
409 409 <1> ; NASM BUG: follows= here should be vfollows=
410 410 <1> section .bss nobits align=256 follows=.bcopy32
411 411 <1>
412 412 <1> section .text start=TEXT_START
413 413 <1> ; NASM BUG: follows=.text not accepted here
414 414 <1> section .data align=16 ; follows=.text
415 415 <1>
416 416 <1> ; NASM BUG: We would like to do follows=.bcopy32
417 417 <1> section .latebss nobits align=16 start=LATEBSS_START
418 418 <1>
419 419 <1> ; Reserve space for stack
420 420 <1> section .stack nobits align=16 start=STACK_START
421 421 00000000 <res 00001000> <1> Stack resb STACK_SIZE
422 422 <1>
423 423
424 424 ;
425 425 ; Some semi-configurable constants... change on your own risk.
426 426 ;
427 427 my_id equ isolinux_id
428 428 FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null)
429 429 FILENAME_MAX equ (1 << FILENAME_MAX_LG2)
430 430 NULLFILE equ 0 ; Zero byte == null file name
431 431 NULLOFFSET equ 0 ; Position in which to look
432 432 retry_count equ 6 ; How patient are we with the BIOS?
433 433 %assign HIGHMEM_SLOP 128*1024 ; Avoid this much memory near the top
434 434 MAX_OPEN_LG2 equ 6 ; log2(Max number of open files)
435 435 MAX_OPEN equ (1 << MAX_OPEN_LG2)
436 436 SECTOR_SHIFT equ 11 ; 2048 bytes/sector (El Torito requirement)
437 437 SECTOR_SIZE equ (1 << SECTOR_SHIFT)
438 438
439 439 ;
440 440 ; This is what we need to do when idle
441 441 ;
442 442 %macro RESET_IDLE 0
443 443 ; Nothing
444 444 %endmacro
445 445 %macro DO_IDLE 0
446 446 ; Nothing
447 447 %endmacro
448 448
449 449 ;
450 450 ; The following structure is used for "virtual kernels"; i.e. LILO-style
451 451 ; option labels. The options we permit here are `kernel' and `append
452 452 ; Since there is no room in the bottom 64K for all of these, we
453 453 ; stick them at vk_seg:0000 and copy them down before we need them.
454 454 ;
455 455 struc vkernel
456 456 00000000 <res 00000100> vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
457 457 00000100 <res 00000100> vk_rname: resb FILENAME_MAX ; Real name
458 458 00000200 <res 00000002> vk_appendlen: resw 1
459 459 00000202 <res 00000001>- alignb 4
460 460 00000202 <rept>
461 461 00000204 <res 00000200> vk_append: resb max_cmd_len+1 ; Command line
462 462 alignb 4
463 463 vk_end: equ $ ; Should be <= vk_size
464 464 endstruc
465 465
466 466 ;
467 467 ; Segment assignments in the bottom 640K
468 468 ; 0000h - main code/data segment (and BIOS segment)
469 469 ;
470 470 real_mode_seg equ 3000h
471 471 vk_seg equ 2000h ; Virtual kernels
472 472 xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
473 473 comboot_seg equ real_mode_seg ; COMBOOT image loading zone
474 474
475 475 ;
476 476 ; File structure. This holds the information for each currently open file.
477 477 ;
478 478 struc open_file_t
479 479 00000000 <res 00000004> file_sector resd 1 ; Sector pointer (0 = structure free)
480 480 00000004 <res 00000004> file_left resd 1 ; Number of sectors left
481 481 endstruc
482 482
483 483 %ifndef DEPEND
484 484 %if (open_file_t_size & (open_file_t_size-1))
485 485 %error "open_file_t is not a power of 2"
486 486 %endif
487 487 %endif
488 488
489 489 struc dir_t
490 490 00000000 <res 00000004> dir_lba resd 1 ; Directory start (LBA)
491 491 00000004 <res 00000004> dir_len resd 1 ; Length in bytes
492 492 00000008 <res 00000004> dir_clust resd 1 ; Length in clusters
493 493 endstruc
494 494
495 495 ; ---------------------------------------------------------------------------
496 496 ; BEGIN CODE
497 497 ; ---------------------------------------------------------------------------
498 498
499 499 ;
500 500 ; Memory below this point is reserved for the BIOS and the MBR
501 501 ;
502 502 section .earlybss
503 503 trackbufsize equ 8192
504 504 00000000 <res 00002000> trackbuf resb trackbufsize ; Track buffer goes here
505 505 00002000 <res 00002000> getcbuf resb trackbufsize
506 506 ; ends at 4800h
507 507
508 508 section .bss
509 509 alignb 4
510 510 00000000 <res 00000040> ISOFileName resb 64 ; ISO filename canonicalization buffer
511 511 ISOFileNameEnd equ $
512 512 00000040 <res 0000000C> CurDir resb dir_t_size ; Current directory
513 513 0000004C <res 0000000C> RootDir resb dir_t_size ; Root directory
514 514 00000058 <res 00000004> FirstSecSum resd 1 ; Checksum of bytes 64-2048
515 515 0000005C <res 00000004> ImageDwords resd 1 ; isolinux.bin size, dwords
516 516 00000060 <res 00000004> InitStack resd 1 ; Initial stack pointer (SS:SP)
517 517 00000064 <res 00000002> DiskSys resw 1 ; Last INT 13h call
518 518 00000066 <res 00000002> ImageSectors resw 1 ; isolinux.bin size, sectors
519 519 00000068 <res 00000001> DiskError resb 1 ; Error code for disk I/O
520 520 00000069 <res 00000001> DriveNo resb 1 ; CD-ROM BIOS drive number
521 521 0000006A <res 00000001> ISOFlags resb 1 ; Flags for ISO directory search
522 522 0000006B <res 00000001> RetryCount resb 1 ; Used for disk access retries
523 523
524 524 _spec_start equ $
525 525
526 526 ;
527 527 ; El Torito spec packet
528 528 ;
529 529
530 530 0000006C <res 00000001>- alignb 8
531 531 0000006C <rept>
532 532 00000070 <res 00000001> spec_packet: resb 1 ; Size of packet
533 533 00000071 <res 00000001> sp_media: resb 1 ; Media type
534 534 00000072 <res 00000001> sp_drive: resb 1 ; Drive number
535 535 00000073 <res 00000001> sp_controller: resb 1 ; Controller index
536 536 00000074 <res 00000004> sp_lba: resd 1 ; LBA for emulated disk image
537 537 00000078 <res 00000002> sp_devspec: resw 1 ; IDE/SCSI information
538 538 0000007A <res 00000002> sp_buffer: resw 1 ; User-provided buffer
539 539 0000007C <res 00000002> sp_loadseg: resw 1 ; Load segment
540 540 0000007E <res 00000002> sp_sectors: resw 1 ; Sector count
541 541 00000080 <res 00000003> sp_chs: resb 3 ; Simulated CHS geometry
542 542 00000083 <res 00000001> sp_dummy: resb 1 ; Scratch, safe to overwrite
543 543
544 544 ;
545 545 ; EBIOS drive parameter packet
546 546 ;
547 547 00000084 <res 00000001>- alignb 8
548 548 00000084 <rept>
549 549 00000088 <res 00000002> drive_params: resw 1 ; Buffer size
550 550 0000008A <res 00000002> dp_flags: resw 1 ; Information flags
551 551 0000008C <res 00000004> dp_cyl: resd 1 ; Physical cylinders
552 552 00000090 <res 00000004> dp_head: resd 1 ; Physical heads
553 553 00000094 <res 00000004> dp_sec: resd 1 ; Physical sectors/track
554 554 00000098 <res 00000008> dp_totalsec: resd 2 ; Total sectors
555 555 000000A0 <res 00000002> dp_secsize: resw 1 ; Bytes per sector
556 556 000000A2 <res 00000004> dp_dpte: resd 1 ; Device Parameter Table
557 557 000000A6 <res 00000002> dp_dpi_key: resw 1 ; 0BEDDh if rest valid
558 558 000000A8 <res 00000001> dp_dpi_len: resb 1 ; DPI len
559 559 000000A9 <res 00000001> resb 1
560 560 000000AA <res 00000002> resw 1
561 561 000000AC <res 00000004> dp_bus: resb 4 ; Host bus type
562 562 000000B0 <res 00000008> dp_interface: resb 8 ; Interface type
563 563 000000B8 <res 00000008> db_i_path: resd 2 ; Interface path
564 564 000000C0 <res 00000008> db_d_path: resd 2 ; Device path
565 565 000000C8 <res 00000001> resb 1
566 566 000000C9 <res 00000001> db_dpi_csum: resb 1 ; Checksum for DPI info
567 567
568 568 ;
569 569 ; EBIOS disk address packet
570 570 ;
571 571 000000CA <res 00000001>- alignb 8
572 572 000000CA <rept>
573 573 000000D0 <res 00000002> dapa: resw 1 ; Packet size
574 574 000000D2 <res 00000002> .count: resw 1 ; Block count
575 575 000000D4 <res 00000002> .off: resw 1 ; Offset of buffer
576 576 000000D6 <res 00000002> .seg: resw 1 ; Segment of buffer
577 577 000000D8 <res 00000008> .lba: resd 2 ; LBA (LSW, MSW)
578 578
579 579 ;
580 580 ; Spec packet for disk image emulation
581 581 ;
582 582 alignb 8
583 583 000000E0 <res 00000001> dspec_packet: resb 1 ; Size of packet
584 584 000000E1 <res 00000001> dsp_media: resb 1 ; Media type
585 585 000000E2 <res 00000001> dsp_drive: resb 1 ; Drive number
586 586 000000E3 <res 00000001> dsp_controller: resb 1 ; Controller index
587 587 000000E4 <res 00000004> dsp_lba: resd 1 ; LBA for emulated disk image
588 588 000000E8 <res 00000002> dsp_devspec: resw 1 ; IDE/SCSI information
589 589 000000EA <res 00000002> dsp_buffer: resw 1 ; User-provided buffer
590 590 000000EC <res 00000002> dsp_loadseg: resw 1 ; Load segment
591 591 000000EE <res 00000002> dsp_sectors: resw 1 ; Sector count
592 592 000000F0 <res 00000003> dsp_chs: resb 3 ; Simulated CHS geometry
593 593 000000F3 <res 00000001> dsp_dummy: resb 1 ; Scratch, safe to overwrite
594 594
595 595 alignb 4
596 596 _spec_end equ $
597 597 _spec_len equ _spec_end - _spec_start
598 598
599 599 000000F4 <res 00000001>- alignb open_file_t_size
600 600 000000F4 <rept>
601 601 000000F8 <res 00000200> Files resb MAX_OPEN*open_file_t_size
602 602
603 603 ;
604 604 ; Constants for the xfer_buf_seg
605 605 ;
606 606 ; The xfer_buf_seg is also used to store message file buffers. We
607 607 ; need two trackbuffers (text and graphics), plus a work buffer
608 608 ; for the graphics decompressor.
609 609 ;
610 610 xbs_textbuf equ 0 ; Also hard-coded, do not change
611 611 xbs_vgabuf equ trackbufsize
612 612 xbs_vgatmpbuf equ 2*trackbufsize
613 613
614 614 section .text
615 615 ;;
616 616 ;; Primary entry point. Because BIOSes are buggy, we only load the first
617 617 ;; CD-ROM sector (2K) of the file, so the number one priority is actually
618 618 ;; loading the rest.
619 619 ;;
620 620 StackBuf equ $
621 621
622 622 bootsec equ $
623 623
624 624 _start: ; Far jump makes sure we canonicalize the address
625 625 00000000 FA cli
626 626 00000001 EA[4000]0000 jmp 0:_start1
627 627 00000006 90<rept> times 8-($-$$) nop ; Pad to file offset 8
628 628
629 629 ; This table hopefully gets filled in by mkisofs using the
630 630 ; -boot-info-table option. If not, the values in this
631 631 ; table are default values that we can use to get us what
632 632 ; we need, at least under a certain set of assumptions.
633 633 00000008 10000000 bi_pvd: dd 16 ; LBA of primary volume descriptor
634 634 0000000C 00000000 bi_file: dd 0 ; LBA of boot file
635 635 00000010 EFBEADDE bi_length: dd 0xdeadbeef ; Length of boot file
636 636 00000014 EFBEADDE bi_csum: dd 0xdeadbeef ; Checksum of boot file
637 637 00000018 EFBEADDE<rept> bi_reserved: times 10 dd 0xdeadbeef ; Reserved
638 638
639 639 00000040 2E8926[6000] _start1: mov [cs:InitStack],sp ; Save initial stack pointer
640 640 00000045 2E8C16[6200] mov [cs:InitStack+2],ss
641 641 0000004A 31C0 xor ax,ax
642 642 0000004C 8ED0 mov ss,ax
643 643 0000004E BC[0000] mov sp,StackBuf ; Set up stack
644 644 00000051 8ED8 mov ds,ax
645 645 00000053 8EC0 mov es,ax
646 646 00000055 8EE0 mov fs,ax
647 647 00000057 8EE8 mov gs,ax
648 648 00000059 FB sti
649 649
650 650 0000005A FC cld
651 651 ; Show signs of life
652 652 0000005B BE[7C03] mov si,syslinux_banner
653 653 0000005E E8C902 call writestr
654 654 %ifdef DEBUG_MESSAGES
655 655 mov si,copyright_str
656 656 call writestr
657 657 %endif
658 658
659 659 ;
660 660 ; Before modifying any memory, get the checksum of bytes
661 661 ; 64-2048
662 662 ;
663 663 00000061 6631FF initial_csum: xor edi,edi
664 664 00000064 BE[4000] mov si,_start1
665 665 00000067 B9F001 mov cx,(SECTOR_SIZE-64) >> 2
666 666 0000006A 66AD .loop: lodsd
667 667 0000006C 6601C7 add edi,eax
668 668 0000006F E2F9 loop .loop
669 669 00000071 66893E[5800] mov [FirstSecSum],edi
670 670
671 671 00000076 8816[6900] mov [DriveNo],dl
672 672 %ifdef DEBUG_MESSAGES
673 673 mov si,startup_msg
674 674 call writemsg
675 675 mov al,dl
676 676 call writehex2
677 677 call crlf
678 678 %endif
679 679 ;
680 680 ; Initialize spec packet buffers
681 681 ;
682 682 0000007A BF[6C00] mov di,_spec_start
683 683 0000007D B92200 mov cx,_spec_len >> 2
684 684 00000080 6631C0 xor eax,eax
685 685 00000083 F366AB rep stosd
686 686
687 687 ; Initialize length field of the various packets
688 688 00000086 C606[7000]13 mov byte [spec_packet],13h
689 689 0000008B C606[8800]1E mov byte [drive_params],30
690 690 00000090 C606[D000]10 mov byte [dapa],16
691 691 00000095 C606[E000]13 mov byte [dspec_packet],13h
692 692
693 693 ; Other nonzero fields
694 694 0000009A FF06[EE00] inc word [dsp_sectors]
695 695
696 696 ; Now figure out what we're actually doing
697 697 ; Note: use passed-in DL value rather than 7Fh because
698 698 ; at least some BIOSes will get the wrong value otherwise
699 699 0000009E B8014B mov ax,4B01h ; Get disk emulation status
700 700 000000A1 8A16[6900] mov dl,[DriveNo]
701 701 000000A5 BE[7000] mov si,spec_packet
702 702 000000A8 CD13 int 13h
703 703 000000AA 0F82BE00 jc award_hack ; changed for BrokenAwardHack
704 704 000000AE 8A16[6900] mov dl,[DriveNo]
705 705 000000B2 3816[7200] cmp [sp_drive],dl ; Should contain the drive number
706 706 000000B6 0F850A01 jne spec_query_failed
707 707
708 708 %ifdef DEBUG_MESSAGES
709 709 mov si,spec_ok_msg
710 710 call writemsg
711 711 mov al,byte [sp_drive]
712 712 call writehex2
713 713 call crlf
714 714 %endif
715 715
716 716 found_drive:
717 717 ; Alright, we have found the drive. Now, try to find the
718 718 ; boot file itself. If we have a boot info table, life is
719 719 ; good; if not, we have to make some assumptions, and try
720 720 ; to figure things out ourselves. In particular, the
721 721 ; assumptions we have to make are:
722 722 ; - single session only
723 723 ; - only one boot entry (no menu or other alternatives)
724 724
725 725 000000BA 66833E[0C00]00 cmp dword [bi_file],0 ; Address of code to load
726 726 000000C0 7527 jne found_file ; Boot info table present :)
727 727
728 728 %ifdef DEBUG_MESSAGES
729 729 mov si,noinfotable_msg
730 730 call writemsg
731 731 %endif
732 732
733 733 ; No such luck. See if the the spec packet contained one.
734 734 000000C2 66A1[7400] mov eax,[sp_lba]
735 735 000000C6 6621C0 and eax,eax
736 736 000000C9 741A jz set_file ; Good enough
737 737
738 738 %ifdef DEBUG_MESSAGES
739 739 mov si,noinfoinspec_msg
740 740 call writemsg
741 741 %endif
742 742
743 743 ; No such luck. Get the Boot Record Volume, assuming single
744 744 ; session disk, and that we're the first entry in the chain
745 745 000000CB 66B811000000 mov eax,17 ; Assumed address of BRV
746 746 000000D1 BB[0000] mov bx,trackbuf
747 747 000000D4 E87201 call getonesec
748 748
749 749 000000D7 66A1[4700] mov eax,[trackbuf+47h] ; Get boot catalog address
750 750 000000DB BB[0000] mov bx,trackbuf
751 751 000000DE E86801 call getonesec ; Get boot catalog
752 752
753 753 000000E1 66A1[2800] mov eax,[trackbuf+28h] ; First boot entry
754 754 ; And hope and pray this is us...
755 755
756 756 ; Some BIOSes apparently have limitations on the size
757 757 ; that may be loaded (despite the El Torito spec being very
758 758 ; clear on the fact that it must all be loaded.) Therefore,
759 759 ; we load it ourselves, and *bleep* the BIOS.
760 760
761 761 set_file:
762 762 000000E5 66A3[0C00] mov [bi_file],eax
763 763
764 764 found_file:
765 765 ; Set up boot file sizes
766 766 000000E9 66A1[1000] mov eax,[bi_length]
767 767 000000ED 662DFD070000 sub eax,SECTOR_SIZE-3
768 768 000000F3 66C1E802 shr eax,2 ; bytes->dwords
769 769 000000F7 66A3[5C00] mov [ImageDwords],eax ; boot file dwords
770 770 000000FB 6605FF010000 add eax,(2047 >> 2)
771 771 00000101 66C1E809 shr eax,9 ; dwords->sectors
772 772 00000105 A3[6600] mov [ImageSectors],ax ; boot file sectors
773 773
774 774 00000108 66A1[0C00] mov eax,[bi_file] ; Address of code to load
775 775 0000010C 6640 inc eax ; Don't reload bootstrap code
776 776 %ifdef DEBUG_MESSAGES
777 777 mov si,offset_msg
778 778 call writemsg
779 779 call writehex8
780 780 call crlf
781 781 %endif
782 782
783 783 ; Just in case some BIOSes have problems with
784 784 ; segment wraparound, use the normalized address
785 785 0000010E BB4008 mov bx,((7C00h+2048) >> 4)
786 786 00000111 8EC3 mov es,bx
787 787 00000113 31DB xor bx,bx
788 788 00000115 8B2E[6600] mov bp,[ImageSectors]
789 789 %ifdef DEBUG_MESSAGES
790 790 push ax
791 791 mov si,size_msg
792 792 call writemsg
793 793 mov ax,bp
794 794 call writehex4
795 795 call crlf
796 796 pop ax
797 797 %endif
798 798 00000119 E83001 call getlinsec
799 799
800 800 0000011C 1E push ds
801 801 0000011D 07 pop es
802 802
803 803 %ifdef DEBUG_MESSAGES
804 804 mov si,loaded_msg
805 805 call writemsg
806 806 %endif
807 807
808 808 ; Verify the checksum on the loaded image.
809 809 verify_image:
810 810 0000011E BE0084 mov si,7C00h+2048
811 811 00000121 8CC3 mov bx,es
812 812 00000123 668B0E[5C00] mov ecx,[ImageDwords]
813 813 00000128 668B3E[5800] mov edi,[FirstSecSum] ; First sector checksum
814 814 0000012D 2666AD .loop es lodsd
815 815 00000130 6601C7 add edi,eax
816 816 00000133 6649 dec ecx
817 817 00000135 740C jz .done
818 818 00000137 21F6 and si,si
819 819 00000139 75F2 jnz .loop
820 820 ; SI wrapped around, advance ES
821 821 0000013B 81C30010 add bx,1000h
822 822 0000013F 8EC3 mov es,bx
823 823 00000141 EBEA jmp short .loop
824 824 00000143 8CD8 .done: mov ax,ds
825 825 00000145 8EC0 mov es,ax
826 826 00000147 66393E[1400] cmp [bi_csum],edi
827 827 0000014C 7409 je integrity_ok
828 828
829 829 0000014E BE[8205] mov si,checkerr_msg
830 830 00000151 E8D500 call writemsg
831 831 00000154 E9A001 jmp kaboom
832 832
833 833 integrity_ok:
834 834 %ifdef DEBUG_MESSAGES
835 835 mov si,allread_msg
836 836 call writemsg
837 837 %endif
838 838 00000157 E97804 jmp all_read ; Jump to main code
839 839
840 840 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
841 841 ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
842 842 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
843 843 ;;
844 844 ;; There is a problem with certain versions of the AWARD BIOS ...
845 845 ;; the boot sector will be loaded and executed correctly, but, because the
846 846 ;; int 13 vector points to the wrong code in the BIOS, every attempt to
847 847 ;; load the spec packet will fail. We scan for the equivalent of
848 848 ;;
849 849 ;; mov ax,0201h
850 850 ;; mov bx,7c00h
851 851 ;; mov cx,0006h
852 852 ;; mov dx,0180h
853 853 ;; pushf
854 854 ;; call <direct far>
855 855 ;;
856 856 ;; and use <direct far> as the new vector for int 13. The code above is
857 857 ;; used to load the boot code into ram, and there should be no reason
858 858 ;; for anybody to change it now or in the future. There are no opcodes
859 859 ;; that use encodings relativ to IP, so scanning is easy. If we find the
860 860 ;; code above in the BIOS code we can be pretty sure to run on a machine
861 861 ;; with an broken AWARD BIOS ...
862 862 ;;
863 863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
864 864 ;;
865 865 %ifdef DEBUG_MESSAGES ;;
866 866 ;;
867 867 award_notice db "Trying BrokenAwardHack first ...",CR,LF,0 ;;
868 868 award_not_orig db "BAH: Original Int 13 vector : ",0 ;;
869 869 award_not_new db "BAH: Int 13 vector changed to : ",0 ;;
870 870 award_not_succ db "BAH: SUCCESS",CR,LF,0 ;;
871 871 award_not_fail db "BAH: FAILURE" ;;
872 872 award_not_crlf db CR,LF,0 ;;
873 873 ;;
874 874 %endif ;;
875 875 ;;
876 876 0000015A 00000000 award_oldint13 dd 0 ;;
877 877 0000015E B80102BB007CB90600- award_string db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah ;;
878 878 00000167 BA80019C9A
879 879 ;;
880 880 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
881 881 0000016C BE[3F04] award_hack: mov si,spec_err_msg ; Moved to this place from
882 882 0000016F E8B700 call writemsg ; spec_query_faild
883 883 ;
884 884 %ifdef DEBUG_MESSAGES ;
885 885 ;
886 886 mov si,award_notice ; display our plan
887 887 call writemsg ;
888 888 mov si,award_not_orig ; display original int 13
889 889 call writemsg ; vector
890 890 %endif ;
891 891 00000172 66A14C00 mov eax,[13h*4] ;
892 892 00000176 66A3[5A01] mov [award_oldint13],eax ;
893 893 ;
894 894 %ifdef DEBUG_MESSAGES ;
895 895 ;
896 896 call writehex8 ;
897 897 mov si,award_not_crlf ;
898 898 call writestr ;
899 899 %endif ;
900 900 0000017A 06 push es ; save ES
901 901 0000017B B800F0 mov ax,0f000h ; ES = BIOS Seg
902 902 0000017E 8EC0 mov es,ax ;
903 903 00000180 FC cld ;
904 904 00000181 31FF xor di,di ; start at ES:DI = f000:0
905 905 00000183 57 award_loop: push di ; save DI
906 906 00000184 BE[5E01] mov si,award_string ; scan for award_string
907 907 00000187 B90700 mov cx,7 ; length of award_string = 7dw
908 908 0000018A F3A7 repz cmpsw ; compare
909 909 0000018C 5F pop di ; restore DI
910 910 0000018D E313 jcxz award_found ; jmp if found
911 911 0000018F 47 inc di ; not found, inc di
912 912 00000190 71F1 jno award_loop ;
913 913 ;
914 914 00000192 07 award_failed: pop es ; No, not this way :-((
915 915 award_fail2: ;
916 916 ;
917 917 %ifdef DEBUG_MESSAGES ;
918 918 ;
919 919 mov si,award_not_fail ; display failure ...
920 920 call writemsg ;
921 921 %endif ;
922 922 00000193 66A1[5A01] mov eax,[award_oldint13] ; restore the original int
923 923 00000197 6609C0 or eax,eax ; 13 vector if there is one
924 924 0000019A 7428 jz spec_query_failed ; and try other workarounds
925 925 0000019C 66A34C00 mov [13h*4],eax ;
926 926 000001A0 EB22 jmp spec_query_failed ;
927 927 ;
928 928 000001A2 26668B450E award_found: mov eax,[es:di+0eh] ; load possible int 13 addr
929 929 000001A7 07 pop es ; restore ES
930 930 ;
931 931 000001A8 663B06[5A01] cmp eax,[award_oldint13] ; give up if this is the
932 932 000001AD 74E3 jz award_failed ; active int 13 vector,
933 933 000001AF 66A34C00 mov [13h*4],eax ; otherwise change 0:13h*4
934 934 ;
935 935 ;
936 936 %ifdef DEBUG_MESSAGES ;
937 937 ;
938 938 push eax ; display message and
939 939 mov si,award_not_new ; new vector address
940 940 call writemsg ;
941 941 pop eax ;
942 942 call writehex8 ;
943 943 mov si,award_not_crlf ;
944 944 call writestr ;
945 945 %endif ;
946 946 000001B3 B8014B mov ax,4B01h ; try to read the spec packet
947 947 000001B6 8A16[6900] mov dl,[DriveNo] ; now ... it should not fail
948 948 000001BA BE[7000] mov si,spec_packet ; any longer
949 949 000001BD CD13 int 13h ;
950 950 000001BF 72D2 jc award_fail2 ;
951 951 ;
952 952 %ifdef DEBUG_MESSAGES ;
953 953 ;
954 954 mov si,award_not_succ ; display our SUCCESS
955 955 call writemsg ;
956 956 %endif ;
957 957 000001C1 E9F6FE jmp found_drive ; and leave error recovery code
958 958 ;
959 959 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
960 960 ;; End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de
961 961 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
962 962
963 963
964 964 ; INT 13h, AX=4B01h, DL=<passed in value> failed.
965 965 ; Try to scan the entire 80h-FFh from the end.
966 966
967 967 spec_query_failed:
968 968
969 969 ; some code moved to BrokenAwardHack
970 970
971 971 000001C4 B2FF mov dl,0FFh
972 972 000001C6 60 .test_loop: pusha
973 973 000001C7 B8014B mov ax,4B01h
974 974 000001CA BE[7000] mov si,spec_packet
975 975 000001CD C6040D mov byte [si],13 ; Size of buffer
976 976 000001D0 CD13 int 13h
977 977 000001D2 61 popa
978 978 000001D3 7227 jc .still_broken
979 979
980 980 000001D5 BE[7204] mov si,maybe_msg
981 981 000001D8 E84E00 call writemsg
982 982 000001DB 88D0 mov al,dl
983 983 000001DD E85D01 call writehex2
984 984 000001E0 E83A01 call crlf
985 985
986 986 000001E3 3816[7200] cmp byte [sp_drive],dl
987 987 000001E7 750D jne .maybe_broken
988 988
989 989 ; Okay, good enough...
990 990 000001E9 BE[8E04] mov si,alright_msg
991 991 000001EC E83A00 call writemsg
992 992 000001EF 8816[6900] mov [DriveNo],dl
993 993 000001F3 E9C4FE .found_drive: jmp found_drive
994 994
995 995 ; Award BIOS 4.51 apparently passes garbage in sp_drive,
996 996 ; but if this was the drive number originally passed in
997 997 ; DL then consider it "good enough"
998 998 .maybe_broken:
999 999 000001F6 3816[6900] cmp byte [DriveNo],dl
1000 1000 000001FA 74F7 je .found_drive
1001 1001
1002 1002 000001FC 4A .still_broken: dec dx
1003 1003 000001FD 80FA80 cmp dl, 80h
1004 1004 00000200 73C4 jnb .test_loop
1005 1005
1006 1006 ; No spec packet anywhere. Some particularly pathetic
1007 1007 ; BIOSes apparently don't even implement function
1008 1008 ; 4B01h, so we can't query a spec packet no matter
1009 1009 ; what. If we got a drive number in DL, then try to
1010 1010 ; use it, and if it works, then well...
1011 1011 00000202 8A16[6900] mov dl,[DriveNo]
1012 1012 00000206 80FA81 cmp dl,81h ; Should be 81-FF at least
1013 1013 00000209 7216 jb fatal_error ; If not, it's hopeless
1014 1014
1015 1015 ; Write a warning to indicate we're on *very* thin ice now
1016 1016 0000020B BE[BC04] mov si,nospec_msg
1017 1017 0000020E E81800 call writemsg
1018 1018 00000211 88D0 mov al,dl
1019 1019 00000213 E82701 call writehex2
1020 1020 00000216 E80401 call crlf
1021 1021 00000219 BE[2B05] mov si,trysbm_msg
1022 1022 0000021C E80A00 call writemsg
1023 1023 0000021F EBD2 jmp .found_drive ; Pray that this works...
1024 1024
1025 1025 fatal_error:
1026 1026 00000221 BE[FD04] mov si,nothing_msg
1027 1027 00000224 E80200 call writemsg
1028 1028
1029 1029 00000227 EBFE .norge: jmp short .norge
1030 1030
1031 1031 ; Information message (DS:SI) output
1032 1032 ; Prefix with "isolinux: "
1033 1033 ;
1034 1034 00000229 50 writemsg: push ax
1035 1035 0000022A 56 push si
1036 1036 0000022B BE[C203] mov si,isolinux_str
1037 1037 0000022E E8F900 call writestr
1038 1038 00000231 5E pop si
1039 1039 00000232 E8F500 call writestr
1040 1040 00000235 58 pop ax
1041 1041 00000236 C3 ret
1042 1042
1043 1043 ;
1044 1044 ; Write a character to the screen. There is a more "sophisticated"
1045 1045 ; version of this in the subsequent code, so we patch the pointer
1046 1046 ; when appropriate.
1047 1047 ;
1048 1048
1049 1049 writechr:
1050 1050 00000237 E90000 jmp near writechr_simple ; 3-byte jump
1051 1051
1052 1052 writechr_simple:
1053 1053 0000023A 669C pushfd
1054 1054 0000023C 6660 pushad
1055 1055 0000023E B40E mov ah,0Eh
1056 1056 00000240 31DB xor bx,bx
1057 1057 00000242 CD10 int 10h
1058 1058 00000244 6661 popad
1059 1059 00000246 669D popfd
1060 1060 00000248 C3 ret
1061 1061
1062 1062 ;
1063 1063 ; Get one sector. Convenience entry point.
1064 1064 ;
1065 1065 getonesec:
1066 1066 00000249 BD0100 mov bp,1
1067 1067 ; Fall through to getlinsec
1068 1068
1069 1069 ;
1070 1070 ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
1071 1071 ;
1072 1072 ; Note that we can't always do this as a single request, because at least
1073 1073 ; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick
1074 1074 ; to 32 sectors (64K) per request.
1075 1075 ;
1076 1076 ; Input:
1077 1077 ; EAX - Linear sector number
1078 1078 ; ES:BX - Target buffer
1079 1079 ; BP - Sector count
1080 1080 ;
1081 1081 getlinsec:
1082 1082 0000024C BE[D000] mov si,dapa ; Load up the DAPA
1083 1083 0000024F 895C04 mov [si+4],bx
1084 1084 00000252 8CC3 mov bx,es
1085 1085 00000254 895C06 mov [si+6],bx
1086 1086 00000257 66894408 mov [si+8],eax
1087 1087 .loop:
1088 1088 0000025B 55 push bp ; Sectors left
1089 1089 0000025C 3B2E[D005] cmp bp,[MaxTransfer]
1090 1090 00000260 7604 jbe .bp_ok
1091 1091 00000262 8B2E[D005] mov bp,[MaxTransfer]
1092 1092 .bp_ok:
1093 1093 00000266 896C02 mov [si+2],bp
1094 1094 00000269 56 push si
1095 1095 0000026A 8A16[6900] mov dl,[DriveNo]
1096 1096 0000026E B442 mov ah,42h ; Extended Read
1097 1097 00000270 E81C00 call xint13
1098 1098 00000273 5E pop si
1099 1099 00000274 5D pop bp
1100 1100 00000275 660FB74402 movzx eax,word [si+2] ; Sectors we read
1101 1101 0000027A 66014408 add [si+8],eax ; Advance sector pointer
1102 1102 0000027E 29C5 sub bp,ax ; Sectors left
1103 1103 00000280 C1E007 shl ax,SECTOR_SHIFT-4 ; 2048-byte sectors -> segment
1104 1104 00000283 014406 add [si+6],ax ; Advance buffer pointer
1105 1105 00000286 21ED and bp,bp
1106 1106 00000288 75D1 jnz .loop
1107 1107 0000028A 668B4408 mov eax,[si+8] ; Next sector
1108 1108 0000028E C3 ret
1109 1109
1110 1110 ; INT 13h with retry
1111 1111 0000028F C606[6B00]06 xint13: mov byte [RetryCount],retry_count
1112 1112 00000294 6660 .try: pushad
1113 1113 00000296 CD13 int 13h
1114 1114 00000298 7204 jc .error
1115 1115 0000029A 83C420 add sp,byte 8*4 ; Clean up stack
1116 1116 0000029D C3 ret
1117 1117 .error:
1118 1118 0000029E 8826[6800] mov [DiskError],ah ; Save error code
1119 1119 000002A2 6661 popad
1120 1120 000002A4 A3[6400] mov [DiskSys],ax ; Save system call number
1121 1121 000002A7 FE0E[6B00] dec byte [RetryCount]
1122 1122 000002AB 7424 jz .real_error
1123 1123 000002AD 50 push ax
1124 1124 000002AE A0[6B00] mov al,[RetryCount]
1125 1125 000002B1 8A26[D200] mov ah,[dapa+2] ; Sector transfer count
1126 1126 000002B5 3C02 cmp al,2 ; Only 2 attempts left
1127 1127 000002B7 7704 ja .nodanger
1128 1128 000002B9 B401 mov ah,1 ; Drop transfer size to 1
1129 1129 000002BB EB09 jmp short .setsize
1130 1130 .nodanger:
1131 1131 000002BD 3C04 cmp al,retry_count-2
1132 1132 000002BF 770D ja .again ; First time, just try again
1133 1133 000002C1 D0EC shr ah,1 ; Otherwise, try to reduce
1134 1134 000002C3 80D400 adc ah,0 ; the max transfer size, but not to 0
1135 1135 .setsize:
1136 1136 000002C6 8826[D005] mov [MaxTransfer],ah
1137 1137 000002CA 8826[D200] mov [dapa+2],ah
1138 1138 .again:
1139 1139 000002CE 58 pop ax
1140 1140 000002CF EBC3 jmp .try
1141 1141
1142 1142 000002D1 BE[6505] .real_error: mov si,diskerr_msg
1143 1143 000002D4 E852FF call writemsg
1144 1144 000002D7 A0[6800] mov al,[DiskError]
1145 1145 000002DA E86000 call writehex2
1146 1146 000002DD BE[7105] mov si,oncall_str
1147 1147 000002E0 E84700 call writestr
1148 1148 000002E3 A1[6400] mov ax,[DiskSys]
1149 1149 000002E6 E86100 call writehex4
1150 1150 000002E9 BE[7905] mov si,ondrive_str
1151 1151 000002EC E83B00 call writestr
1152 1152 000002EF 88D0 mov al,dl
1153 1153 000002F1 E84900 call writehex2
1154 1154 000002F4 E82600 call crlf
1155 1155 ; Fall through to kaboom
1156 1156
1157 1157 ;
1158 1158 ; kaboom: write a message and bail out. Wait for a user keypress,
1159 1159 ; then do a hard reboot.
1160 1160 ;
1161 1161 kaboom:
1162 1162 000002F7 2E0FB226[CC05] lss sp,[cs:StackPtr]
1163 1163 000002FD 8CC8 mov ax,cs
1164 1164 000002FF 8ED8 mov ds,ax
1165 1165 00000301 8EC0 mov es,ax
1166 1166 00000303 8EE0 mov fs,ax
1167 1167 00000305 8EE8 mov gs,ax
1168 1168 00000307 FB sti
1169 1169 00000308 BE[A305] mov si,err_bootfailed
1170 1170 0000030B E81C00 call cwritestr
1171 1171 0000030E E88E17 call getchar
1172 1172 00000311 FA cli
1173 1173 00000312 C70672040000 mov word [BIOS_magic],0 ; Cold reboot
1174 1174 00000318 EAF0FF00F0 jmp 0F000h:0FFF0h ; Reset vector address
1175 1175
1176 1176 ; -----------------------------------------------------------------------------
1177 1177 ; Common modules needed in the first sector
1178 1178 ; -----------------------------------------------------------------------------
1179 1179
1180 1180 %include "writestr.inc" ; String output
1181 1181 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
1182 1182 <1> ;; -----------------------------------------------------------------------
1183 1183 <1> ;;
1184 1184 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
1185 1185 <1> ;;
1186 1186 <1> ;; This program is free software; you can redistribute it and/or modify
1187 1187 <1> ;; it under the terms of the GNU General Public License as published by
1188 1188 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
1189 1189 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
1190 1190 <1> ;; (at your option) any later version; incorporated herein by reference.
1191 1191 <1> ;;
1192 1192 <1> ;; -----------------------------------------------------------------------
1193 1193 <1>
1194 1194 <1> ;;
1195 1195 <1> ;; writestr.inc
1196 1196 <1> ;;
1197 1197 <1> ;; Code to write a simple string.
1198 1198 <1> ;;
1199 1199 <1>
1200 1200 <1> section .text
1201 1201 <1> ;
1202 1202 <1> ; crlf: Print a newline
1203 1203 <1> ;
1204 1204 0000031D 50 <1> crlf: push ax
1205 1205 0000031E B00D <1> mov al,CR
1206 1206 00000320 E814FF <1> call writechr
1207 1207 00000323 B00A <1> mov al,LF
1208 1208 00000325 E80FFF <1> call writechr
1209 1209 00000328 58 <1> pop ax
1210 1210 00000329 C3 <1> ret
1211 1211 <1>
1212 1212 <1> ;
1213 1213 <1> ; cwritestr: write a null-terminated string to the console, saving
1214 1214 <1> ; registers on entry.
1215 1215 <1> ;
1216 1216 <1> ; Note: writestr and cwritestr are distinct in SYSLINUX (only)
1217 1217 <1> ;
1218 1218 <1> cwritestr:
1219 1219 0000032A 669C <1> pushfd
1220 1220 0000032C 6660 <1> pushad
1221 1221 0000032E AC <1> .top: lodsb
1222 1222 0000032F 20C0 <1> and al,al
1223 1223 00000331 7405 <1> jz .end
1224 1224 00000333 E801FF <1> call writechr
1225 1225 00000336 EBF6 <1> jmp short .top
1226 1226 00000338 6661 <1> .end: popad
1227 1227 0000033A 669D <1> popfd
1228 1228 0000033C C3 <1> ret
1229 1229 writestr equ cwritestr
1230 1230 %include "writehex.inc" ; Hexadecimal output
1231 1231 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
1232 1232 <1> ;; -----------------------------------------------------------------------
1233 1233 <1> ;;
1234 1234 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
1235 1235 <1> ;;
1236 1236 <1> ;; This program is free software; you can redistribute it and/or modify
1237 1237 <1> ;; it under the terms of the GNU General Public License as published by
1238 1238 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
1239 1239 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
1240 1240 <1> ;; (at your option) any later version; incorporated herein by reference.
1241 1241 <1> ;;
1242 1242 <1> ;; -----------------------------------------------------------------------
1243 1243 <1>
1244 1244 <1> ;;
1245 1245 <1> ;; writehex.inc
1246 1246 <1> ;;
1247 1247 <1> ;; Write hexadecimal numbers to the console
1248 1248 <1> ;;
1249 1249 <1>
1250 1250 <1> section .text
1251 1251 <1> ;
1252 1252 <1> ; writehex[248]: Write a hex number in (AL, AX, EAX) to the console
1253 1253 <1> ;
1254 1254 <1> writehex2:
1255 1255 0000033D 669C <1> pushfd
1256 1256 0000033F 6660 <1> pushad
1257 1257 00000341 66C1C018 <1> rol eax,24
1258 1258 00000345 B90200 <1> mov cx,2
1259 1259 00000348 EB14 <1> jmp short writehex_common
1260 1260 <1> writehex4:
1261 1261 0000034A 669C <1> pushfd
1262 1262 0000034C 6660 <1> pushad
1263 1263 0000034E 66C1C010 <1> rol eax,16
1264 1264 00000352 B90400 <1> mov cx,4
1265 1265 00000355 EB07 <1> jmp short writehex_common
1266 1266 <1> writehex8:
1267 1267 00000357 669C <1> pushfd
1268 1268 00000359 6660 <1> pushad
1269 1269 0000035B B90800 <1> mov cx,8
1270 1270 <1> writehex_common:
1271 1271 0000035E 66C1C004 <1> .loop: rol eax,4
1272 1272 00000362 6650 <1> push eax
1273 1273 00000364 240F <1> and al,0Fh
1274 1274 00000366 3C0A <1> cmp al,10
1275 1275 00000368 7304 <1> jae .high
1276 1276 0000036A 0430 <1> .low: add al,'0'
1277 1277 0000036C EB02 <1> jmp short .ischar
1278 1278 0000036E 0437 <1> .high: add al,'A'-10
1279 1279 00000370 E8C4FE <1> .ischar: call writechr
1280 1280 00000373 6658 <1> pop eax
1281 1281 00000375 E2E7 <1> loop .loop
1282 1282 00000377 6661 <1> popad
1283 1283 00000379 669D <1> popfd
1284 1284 0000037B C3 <1> ret
1285 1285 <1>
1286 1286
1287 1287 ; -----------------------------------------------------------------------------
1288 1288 ; Data that needs to be in the first sector
1289 1289 ; -----------------------------------------------------------------------------
1290 1290
1291 1291 0000037C 0D0A49534F4C494E55- syslinux_banner db CR, LF, 'ISOLINUX ', version_str, ' ', date, ' ', 0
1292 1292 00000385 5820332E3131203078-
1293 1293 0000038E 343664396437353820-
1294 1294 00000397 00
1295 1295 00000398 20436F707972696768- copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin'
1296 1296 000003A1 742028432920313939-
1297 1297 000003AA 342D3230303520482E-
1298 1298 000003B3 20506574657220416E-
1299 1299 000003BC 76696E
1300 1300 000003BF 0D0A00 db CR, LF, 0
1301 1301 000003C2 69736F6C696E75783A- isolinux_str db 'isolinux: ', 0
1302 1302 000003CB 2000
1303 1303 %ifdef DEBUG_MESSAGES
1304 1304 startup_msg: db 'Starting up, DL = ', 0
1305 1305 spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
1306 1306 secsize_msg: db 'Sector size appears to be ', 0
1307 1307 offset_msg: db 'Loading main image from LBA = ', 0
1308 1308 size_msg: db 'Sectors to load = ', 0
1309 1309 loaded_msg: db 'Loaded boot image, verifying...', CR, LF, 0
1310 1310 verify_msg: db 'Image checksum verified.', CR, LF, 0
1311 1311 allread_msg db 'Main image read, jumping to main code...', CR, LF, 0
1312 1312 %endif
1313 1313 000003CD 4E6F20626F6F742069- noinfotable_msg db 'No boot info table, assuming single session disk...', CR, LF, 0
1314 1314 000003D6 6E666F207461626C65-
1315 1315 000003DF 2C20617373756D696E-
1316 1316 000003E8 672073696E676C6520-
1317 1317 000003F1 73657373696F6E2064-
1318 1318 000003FA 69736B2E2E2E0D0A00
1319 1319 00000403 53706563207061636B- noinfoinspec_msg db 'Spec packet missing LBA information, trying to wing it...', CR, LF, 0
1320 1320 0000040C 6574206D697373696E-
1321 1321 00000415 67204C424120696E66-
1322 1322 0000041E 6F726D6174696F6E2C-
1323 1323 00000427 20747279696E672074-
1324 1324 00000430 6F2077696E67206974-
1325 1325 00000439 2E2E2E0D0A00
1326 1326 0000043F 4C6F6164696E672073- spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0
1327 1327 00000448 706563207061636B65-
1328 1328 00000451 74206661696C65642C-
1329 1329 0000045A 20747279696E672074-
1330 1330 00000463 6F2077696E67206974-
1331 1331 0000046C 2E2E2E0D0A00
1332 1332 00000472 466F756E6420736F6D- maybe_msg: db 'Found something at drive = ', 0
1333 1333 0000047B 657468696E67206174-
1334 1334 00000484 206472697665203D20-
1335 1335 0000048D 00
1336 1336 0000048E 4C6F6F6B73206C696B- alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0
1337 1337 00000497 65206974206D696768-
1338 1338 000004A0 742062652072696768-
1339 1339 000004A9 742C20636F6E74696E-
1340 1340 000004B2 75696E672E2E2E0D0A-
1341 1341 000004BB 00
1342 1342 000004BC 45787472656D656C79- nospec_msg db 'Extremely broken BIOS detected, last ditch attempt with drive = ', 0
1343 1343 000004C5 2062726F6B656E2042-
1344 1344 000004CE 494F53206465746563-
1345 1345 000004D7 7465642C206C617374-
1346 1346 000004E0 206469746368206174-
1347 1347 000004E9 74656D707420776974-
1348 1348 000004F2 68206472697665203D-
1349 1349 000004FB 2000
1350 1350 000004FD 4661696C656420746F- nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF
1351 1351 00000506 206C6F636174652043-
1352 1352 0000050F 442D524F4D20646576-
1353 1353 00000518 6963653B20626F6F74-
1354 1354 00000521 206661696C65642E0D-
1355 1355 0000052A 0A
1356 1356 0000052B 53656520687474703A- trysbm_msg db 'See http://syslinux.zytor.com/sbm for more information.', CR, LF, 0
1357 1357 00000534 2F2F7379736C696E75-
1358 1358 0000053D 782E7A79746F722E63-
1359 1359 00000546 6F6D2F73626D20666F-
1360 1360 0000054F 72206D6F726520696E-
1361 1361 00000558 666F726D6174696F6E-
1362 1362 00000561 2E0D0A00
1363 1363 00000565 4469736B206572726F- diskerr_msg: db 'Disk error ', 0
1364 1364 0000056E 722000
1365 1365 00000571 2C204158203D2000 oncall_str: db ', AX = ',0
1366 1366 00000579 2C2064726976652000 ondrive_str: db ', drive ', 0
1367 1367 00000582 496D61676520636865- checkerr_msg: db 'Image checksum error, sorry...', CR, LF, 0
1368 1368 0000058B 636B73756D20657272-
1369 1369 00000594 6F722C20736F727279-
1370 1370 0000059D 2E2E2E0D0A00
1371 1371
1372 1372 000005A3 0D0A426F6F74206661- err_bootfailed db CR, LF, 'Boot failed: press a key to retry...'
1373 1373 000005AC 696C65643A20707265-
1374 1374 000005B5 73732061206B657920-
1375 1375 000005BE 746F2072657472792E-
1376 1376 000005C7 2E2E
1377 1377 bailmsg equ err_bootfailed
1378 1378 000005C9 0D0A crlf_msg db CR, LF
1379 1379 000005CB 00 null_msg db 0
1380 1380
1381 1381 alignb 4, db 0
1382 1382 000005CC [0000]0000 StackPtr dw StackBuf, 0 ; SS:SP for stack reset
1383 1383 000005D0 2000 MaxTransfer dw 32 ; Max sectors per transfer
1384 1384
1385 1385 rl_checkpt equ $ ; Must be <= 800h
1386 1386
1387 1387 rl_checkpt_off equ ($-$$)
1388 1388 ;%ifndef DEPEND
1389 1389 ;%if rl_checkpt_off > 0x800
1390 1390 ;%error "Sector 0 overflow"
1391 1391 ;%endif
1392 1392 ;%endif
1393 1393
1394 1394 ; ----------------------------------------------------------------------------
1395 1395 ; End of code and data that have to be in the first sector
1396 1396 ; ----------------------------------------------------------------------------
1397 1397
1398 1398 all_read:
1399 1399 ;
1400 1400 ; Initialize screen (if we're using one)
1401 1401 ;
1402 1402 ; Now set up screen parameters
1403 1403 000005D2 E8FB18 call adjust_screen
1404 1404
1405 1405 ; Wipe the F-key area
1406 1406 000005D5 B000 mov al,NULLFILE
1407 1407 000005D7 BF[080F] mov di,FKeyName
1408 1408 000005DA B9000A mov cx,10*(1 << FILENAME_MAX_LG2)
1409 1409 000005DD F3AA rep stosb
1410 1410
1411 1411 ; Patch the writechr routine to point to the full code
1412 1412 000005DF C706[3802]751F mov word [writechr+1], writechr_full-(writechr+3)
1413 1413
1414 1414 ; Tell the user we got this far...
1415 1415 %ifndef DEBUG_MESSAGES ; Gets messy with debugging on
1416 1416 000005E5 BE[9803] mov si,copyright_str
1417 1417 000005E8 E83FFD call writestr
1418 1418 %endif
1419 1419
1420 1420 ; Test tracers
1421 1421 TRACER 'T'
1422 1422 TRACER '>'
1423 1423
1424 1424 ;
1425 1425 ; Common initialization code
1426 1426 ;
1427 1427 %include "init.inc"
1428 1428 <1> ; -*- fundamental -*-
1429 1429 <1> ; -----------------------------------------------------------------------
1430 1430 <1> ;
1431 1431 <1> ; Copyright 2004 H. Peter Anvin - All Rights Reserved
1432 1432 <1> ;
1433 1433 <1> ; This program is free software; you can redistribute it and/or modify
1434 1434 <1> ; it under the terms of the GNU General Public License as published by
1435 1435 <1> ; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
1436 1436 <1> ; Boston MA 02111-1307, USA; either version 2 of the License, or
1437 1437 <1> ; (at your option) any later version; incorporated herein by reference.
1438 1438 <1> ;
1439 1439 <1> ; -----------------------------------------------------------------------
1440 1440 <1> ; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
1441 1441 <1>
1442 1442 <1> ;
1443 1443 <1> ; init.inc
1444 1444 <1> ;
1445 1445 <1> ; Common initialization code (inline)
1446 1446 <1> ;
1447 1447 <1>
1448 1448 <1> section .text
1449 1449 <1> common_init:
1450 1450 <1> ; Now set up screen parameters
1451 1451 000005EB E8E218 <1> call adjust_screen
1452 1452 <1>
1453 1453 <1> ; Wipe the F-key area
1454 1454 000005EE B000 <1> mov al,NULLFILE
1455 1455 000005F0 BF[080F] <1> mov di,FKeyName
1456 1456 000005F3 B9000A <1> mov cx,10*(1 << FILENAME_MAX_LG2)
1457 1457 000005F6 F3AA <1> rep stosb
1458 1458 <1>
1459 1459 000005F8 BE[0000] <1> mov si,linuxauto_cmd ; Default command: "linux auto"
1460 1460 000005FB BF[0402] <1> mov di,default_cmd
1461 1461 000005FE B90B00 <1> mov cx,linuxauto_len
1462 1462 00000601 F3A4 <1> rep movsb
1463 1463 <1>
1464 1464 00000603 BF[080E] <1> mov di,KbdMap ; Default keymap 1:1
1465 1465 00000606 30C0 <1> xor al,al
1466 1466 00000608 FEC5 <1> inc ch ; CX <- 256
1467 1467 0000060A AA <1> mkkeymap: stosb
1468 1468 0000060B FEC0 <1> inc al
1469 1469 0000060D E2FB <1> loop mkkeymap
1470 1470 <1>
1471 1471 <1> ;
1472 1472 <1> ; Clear Files structures
1473 1473 <1> ;
1474 1474 0000060F BF[F800] <1> mov di,Files
1475 1475 00000612 B98000 <1> mov cx,(MAX_OPEN*open_file_t_size)/4
1476 1476 00000615 6631C0 <1> xor eax,eax
1477 1477 00000618 F366AB <1> rep stosd
1478 1478 <1>
1479 1479 <1> %if IS_PXELINUX
1480 1480 <1> mov di,Files+tftp_pktbuf
1481 1481 <1> mov cx,MAX_OPEN
1482 1482 <1> .setbufptr:
1483 1483 <1> mov [di],ax
1484 1484 <1> add di,open_file_t_size
1485 1485 <1> add ax,PKTBUF_SIZE
1486 1486 <1> loop .setbufptr
1487 1487 <1> %endif
1488 1488 <1>
1489 1489 <1> section .data
1490 1490 00000000 6C696E757820617574- <1> linuxauto_cmd db 'linux auto',0
1491 1491 00000009 6F00 <1>
1492 1492 <1> linuxauto_len equ $-linuxauto_cmd
1493 1493 <1>
1494 1494 <1> section .text ; This is an inline file...
1495 1495 <1>
1496 1496 %include "cpuinit.inc"
1497 1497 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
1498 1498 <1> ;; -----------------------------------------------------------------------
1499 1499 <1> ;;
1500 1500 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
1501 1501 <1> ;;
1502 1502 <1> ;; This program is free software; you can redistribute it and/or modify
1503 1503 <1> ;; it under the terms of the GNU General Public License as published by
1504 1504 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
1505 1505 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
1506 1506 <1> ;; (at your option) any later version; incorporated herein by reference.
1507 1507 <1> ;;
1508 1508 <1> ;; -----------------------------------------------------------------------
1509 1509 <1>
1510 1510 <1> ;;
1511 1511 <1> ;; cpuinit.inc
1512 1512 <1> ;;
1513 1513 <1> ;; CPU-dependent initialization and related checks.
1514 1514 <1> ;;
1515 1515 <1>
1516 1516 <1> check_escapes:
1517 1517 0000061B B402 <1> mov ah,02h ; Check keyboard flags
1518 1518 0000061D CD16 <1> int 16h
1519 1519 0000061F A2[0C03] <1> mov [KbdFlags],al ; Save for boot prompt check
1520 1520 00000622 A804 <1> test al,04h ; Ctrl->skip 386 check
1521 1521 00000624 7510 <1> jnz skip_checks
1522 1522 <1>
1523 1523 <1> ;
1524 1524 <1> ; Now check that there is sufficient low (DOS) memory
1525 1525 <1> ;
1526 1526 <1> ; NOTE: Linux doesn't use all of real_mode_seg, but we use the same
1527 1527 <1> ; segment for COMBOOT images, which can use all 64K
1528 1528 <1> ;
1529 1529 <1> dosram_k equ (real_mode_seg+0x1000) >> 6 ; Minimum DOS memory (K)
1530 1530 00000626 CD12 <1> int 12h
1531 1531 00000628 3D0001 <1> cmp ax,dosram_k
1532 1532 0000062B 7309 <1> jae enough_ram
1533 1533 0000062D BE[1D01] <1> mov si,err_noram
1534 1534 00000630 E8F7FC <1> call writestr
1535 1535 00000633 E9C1FC <1> jmp kaboom
1536 1536 <1> enough_ram:
1537 1537 <1> skip_checks:
1538 1538 <1>
1539 1539 <1> ;
1540 1540 <1> ; Initialize the bcopy32 code in low memory
1541 1541 <1> ;
1542 1542 00000636 BE[0000] <1> mov si,section..bcopy32.start
1543 1543 00000639 BF[0000] <1> mov di,__bcopy_start
1544 1544 0000063C B98300 <1> mov cx,__bcopy_size >> 2
1545 1545 0000063F F366A5 <1> rep movsd
1546 1546 <1>
1547 1547 <1> ;
1548 1548 <1> ; Check if we're 386 (as opposed to 486+); if so we need to blank out
1549 1549 <1> ; the WBINVD instruction
1550 1550 <1> ;
1551 1551 <1> ; We check for 486 by setting EFLAGS.AC
1552 1552 <1> ;
1553 1553 <1> %if DO_WBINVD
1554 1554 <1> pushfd ; Save the good flags
1555 1555 <1> pushfd
1556 1556 <1> pop eax
1557 1557 <1> mov ebx,eax
1558 1558 <1> xor eax,(1 << 18) ; AC bit
1559 1559 <1> push eax
1560 1560 <1> popfd
1561 1561 <1> pushfd
1562 1562 <1> pop eax
1563 1563 <1> popfd ; Restore the original flags
1564 1564 <1> xor eax,ebx
1565 1565 <1> jnz is_486
1566 1566 <1> ;
1567 1567 <1> ; 386 - Looks like we better blot out the WBINVD instruction
1568 1568 <1> ;
1569 1569 <1> mov byte [try_wbinvd],0c3h ; Near RET
1570 1570 <1> is_486:
1571 1571 <1> %endif ; DO_WBINVD
1572 1572 <1>
1573 1573
1574 1574 ;
1575 1575 ; Now we're all set to start with our *real* business. First load the
1576 1576 ; configuration file (if any) and parse it.
1577 1577 ;
1578 1578 ; In previous versions I avoided using 32-bit registers because of a
1579 1579 ; rumour some BIOSes clobbered the upper half of 32-bit registers at
1580 1580 ; random. I figure, though, that if there are any of those still left
1581 1581 ; they probably won't be trying to install Linux on them...
1582 1582 ;
1583 1583 ; The code is still ripe with 16-bitisms, though. Not worth the hassle
1584 1584 ; to take'm out. In fact, we may want to put them back if we're going
1585 1585 ; to boot ELKS at some point.
1586 1586 ;
1587 1587
1588 1588 ;
1589 1589 ; Now, we need to sniff out the actual filesystem data structures.
1590 1590 ; mkisofs gave us a pointer to the primary volume descriptor
1591 1591 ; (which will be at 16 only for a single-session disk!); from the PVD
1592 1592 ; we should be able to find the rest of what we need to know.
1593 1593 ;
1594 1594 get_fs_structures:
1595 1595 00000642 66A1[0800] mov eax,[bi_pvd]
1596 1596 00000646 BB[0000] mov bx,trackbuf
1597 1597 00000649 E8FDFB call getonesec
1598 1598
1599 1599 0000064C 66A1[9E00] mov eax,[trackbuf+156+2]
1600 1600 00000650 66A3[4C00] mov [RootDir+dir_lba],eax
1601 1601 00000654 66A3[4000] mov [CurDir+dir_lba],eax
1602 1602 %ifdef DEBUG_MESSAGES
1603 1603 mov si,dbg_rootdir_msg
1604 1604 call writemsg
1605 1605 call writehex8
1606 1606 call crlf
1607 1607 %endif
1608 1608 00000658 66A1[A600] mov eax,[trackbuf+156+10]
1609 1609 0000065C 66A3[5000] mov [RootDir+dir_len],eax
1610 1610 00000660 66A3[4400] mov [CurDir+dir_len],eax
1611 1611 00000664 6605FF070000 add eax,SECTOR_SIZE-1
1612 1612 0000066A 66C1E80B shr eax,SECTOR_SHIFT
1613 1613 0000066E 66A3[5400] mov [RootDir+dir_clust],eax
1614 1614 00000672 66A3[4800] mov [CurDir+dir_clust],eax
1615 1615
1616 1616 ; Look for an isolinux directory, and if found,
1617 1617 ; make it the current directory instead of the root
1618 1618 ; directory.
1619 1619 00000676 BF[CC03] mov di,boot_dir ; Search for /boot/isolinux
1620 1620 00000679 B002 mov al,02h
1621 1621 0000067B E8B20E call searchdir_iso
1622 1622 0000067E 750A jnz .found_dir
1623 1623 00000680 BF[D103] mov di,isolinux_dir
1624 1624 00000683 B002 mov al,02h ; Search for /isolinux
1625 1625 00000685 E8A80E call searchdir_iso
1626 1626 00000688 7416 jz .no_isolinux_dir
1627 1627 .found_dir:
1628 1628 0000068A 66A3[4400] mov [CurDir+dir_len],eax
1629 1629 0000068E 668B4404 mov eax,[si+file_left]
1630 1630 00000692 66A3[4800] mov [CurDir+dir_clust],eax
1631 1631 00000696 6631C0 xor eax,eax ; Free this file pointer entry
1632 1632 00000699 668704 xchg eax,[si+file_sector]
1633 1633 0000069C 66A3[4000] mov [CurDir+dir_lba],eax
1634 1634 %ifdef DEBUG_MESSAGES
1635 1635 push si
1636 1636 mov si,dbg_isodir_msg
1637 1637 call writemsg
1638 1638 pop si
1639 1639 call writehex8
1640 1640 call crlf
1641 1641 %endif
1642 1642 .no_isolinux_dir:
1643 1643
1644 1644 ;
1645 1645 ; Locate the configuration file
1646 1646 ;
1647 1647 load_config:
1648 1648 %ifdef DEBUG_MESSAGES
1649 1649 mov si,dbg_config_msg
1650 1650 call writemsg
1651 1651 %endif
1652 1652
1653 1653 000006A0 BF[DB03] mov di,isolinux_cfg
1654 1654 000006A3 E82C10 call open
1655 1655 000006A6 7403 jz no_config_file ; Not found or empty
1656 1656
1657 1657 %ifdef DEBUG_MESSAGES
1658 1658 mov si,dbg_configok_msg
1659 1659 call writemsg
1660 1660 %endif
1661 1661
1662 1662 ;
1663 1663 ; Now we have the config file open. Parse the config file and
1664 1664 ; run the user interface.
1665 1665 ;
1666 1666 %include "ui.inc"
1667 1667 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
1668 1668 <1> ;; -----------------------------------------------------------------------
1669 1669 <1> ;;
1670 1670 <1> ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
1671 1671 <1> ;;
1672 1672 <1> ;; This program is free software; you can redistribute it and/or modify
1673 1673 <1> ;; it under the terms of the GNU General Public License as published by
1674 1674 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
1675 1675 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
1676 1676 <1> ;; (at your option) any later version; incorporated herein by reference.
1677 1677 <1> ;;
1678 1678 <1> ;; -----------------------------------------------------------------------
1679 1679 <1>
1680 1680 <1> ;
1681 1681 <1> ; This file should be entered with the config file open (for getc)
1682 1682 <1> ;
1683 1683 000006A8 E80216 <1> call parse_config ; Parse configuration file
1684 1684 <1> no_config_file:
1685 1685 <1> ;
1686 1686 <1> ; Check whether or not we are supposed to display the boot prompt.
1687 1687 <1> ;
1688 1688 <1> check_for_key:
1689 1689 000006AB 833E[AC00]00 <1> cmp word [ForcePrompt],0 ; Force prompt?
1690 1690 000006B0 7509 <1> jnz enter_command
1691 1691 000006B2 F606[0C03]5B <1> test byte [KbdFlags],5Bh ; Shift Alt Caps Scroll
1692 1692 000006B7 0F840201 <1> jz auto_boot ; If neither, default boot
1693 1693 <1>
1694 1694 <1> enter_command:
1695 1695 000006BB 833E[AE00]00 <1> cmp word [NoEscape],0 ; If NOESCAPE, no prompt,
1696 1696 000006C0 0F85F900 <1> jne auto_boot ; always run default cmd
1697 1697 <1>
1698 1698 000006C4 BE[CF00] <1> mov si,boot_prompt
1699 1699 000006C7 E860FC <1> call cwritestr
1700 1700 <1>
1701 1701 000006CA C606[0D03]00 <1> mov byte [FuncFlag],0 ; <Ctrl-F> not pressed
1702 1702 000006CF BF[0000] <1> mov di,command_line
1703 1703 <1>
1704 1704 <1> ;
1705 1705 <1> ; get the very first character -- we can either time
1706 1706 <1> ; out, or receive a character press at this time. Some dorky BIOSes stuff
1707 1707 <1> ; a return in the buffer on bootup, so wipe the keyboard buffer first.
1708 1708 <1> ;
1709 1709 000006D2 B411 <1> clear_buffer: mov ah,11h ; Check for pending char
1710 1710 000006D4 CD16 <1> int 16h
1711 1711 000006D6 7406 <1> jz get_char_time
1712 1712 000006D8 B410 <1> mov ah,10h ; Get char
1713 1713 000006DA CD16 <1> int 16h
1714 1714 000006DC EBF4 <1> jmp short clear_buffer
1715 1715 <1>
1716 1716 <1> ; For the first character, both KbdTimeout and
1717 1717 <1> ; TotalTimeout apply; after that, only TotalTimeout.
1718 1718 <1>
1719 1719 <1> get_char_time:
1720 1720 000006DE 66A1[A000] <1> mov eax,[TotalTimeout]
1721 1721 000006E2 66A3[0403] <1> mov [ThisTotalTo],eax
1722 1722 000006E6 66A1[9C00] <1> mov eax,[KbdTimeout]
1723 1723 000006EA 66A3[0003] <1> mov [ThisKbdTo],eax
1724 1724 <1>
1725 1725 <1> get_char:
1726 1726 000006EE E81802 <1> call getchar_timeout
1727 1727 000006F1 668326[0003]00 <1> and dword [ThisKbdTo],0 ; For the next time...
1728 1728 <1>
1729 1729 000006F7 20C0 <1> and al,al
1730 1730 000006F9 747B <1> jz func_key
1731 1731 <1>
1732 1732 000006FB 3C7F <1> got_ascii: cmp al,7Fh ; <DEL> == <BS>
1733 1733 000006FD 744D <1> je backspace
1734 1734 000006FF 3C20 <1> cmp al,' ' ; ASCII?
1735 1735 00000701 722A <1> jb not_ascii
1736 1736 00000703 7706 <1> ja enter_char
1737 1737 00000705 81FF[0000] <1> cmp di,command_line ; Space must not be first
1738 1738 00000709 74E3 <1> je short get_char
1739 1739 0000070B F606[0D03]01 <1> enter_char: test byte [FuncFlag],1
1740 1740 00000710 740F <1> jz .not_ctrl_f
1741 1741 00000712 C606[0D03]00 <1> mov byte [FuncFlag],0
1742 1742 00000717 3C30 <1> cmp al,'0'
1743 1743 00000719 7206 <1> jb .not_ctrl_f
1744 1744 0000071B 7451 <1> je ctrl_f_0
1745 1745 0000071D 3C39 <1> cmp al,'9'
1746 1746 0000071F 764F <1> jbe ctrl_f
1747 1747 00000721 81FF[FF01] <1> .not_ctrl_f: cmp di,max_cmd_len+command_line ; Check there's space
1748 1748 00000725 73C7 <1> jnb short get_char
1749 1749 00000727 AA <1> stosb ; Save it
1750 1750 00000728 E80CFB <1> call writechr ; Echo to screen
1751 1751 0000072B EBC1 <1> jmp short get_char
1752 1752 0000072D C606[0D03]00 <1> not_ascii: mov byte [FuncFlag],0
1753 1753 00000732 3C0D <1> cmp al,0Dh ; Enter
1754 1754 00000734 0F849300 <1> je command_done
1755 1755 00000738 3C06 <1> cmp al,'F' & 1Fh ; <Ctrl-F>
1756 1756 0000073A 742B <1> je set_func_flag
1757 1757 0000073C 3C15 <1> cmp al,'U' & 1Fh ; <Ctrl-U>
1758 1758 0000073E 741B <1> je kill_command ; Kill input line
1759 1759 00000740 3C16 <1> cmp al,'V' & 1Fh ; <Ctrl-V>
1760 1760 00000742 7458 <1> je print_version
1761 1761 00000744 3C18 <1> cmp al,'X' & 1Fh ; <Ctrl-X>
1762 1762 00000746 7419 <1> je force_text_mode
1763 1763 00000748 3C08 <1> cmp al,08h ; Backspace
1764 1764 0000074A 75A2 <1> jne get_char
1765 1765 0000074C 81FF[0000] <1> backspace: cmp di,command_line ; Make sure there is anything
1766 1766 00000750 749C <1> je get_char ; to erase
1767 1767 00000752 4F <1> dec di ; Unstore one character
1768 1768 00000753 BE[D600] <1> mov si,wipe_char ; and erase it from the screen
1769 1769 00000756 E8D1FB <1> call cwritestr
1770 1770 00000759 EB11 <1> jmp short get_char_2
1771 1771 <1>
1772 1772 <1> kill_command:
1773 1773 0000075B E8BFFB <1> call crlf
1774 1774 0000075E E95AFF <1> jmp enter_command
1775 1775 <1>
1776 1776 <1> force_text_mode:
1777 1777 00000761 E80B19 <1> call vgaclearmode
1778 1778 00000764 E954FF <1> jmp enter_command
1779 1779 <1>
1780 1780 <1> set_func_flag:
1781 1781 00000767 C606[0D03]01 <1> mov byte [FuncFlag],1
1782 1782 <1> get_char_2:
1783 1783 0000076C EB80 <1> jmp short get_char
1784 1784 <1>
1785 1785 0000076E 040A <1> ctrl_f_0: add al,10 ; <Ctrl-F>0 == F10
1786 1786 00000770 2C31 <1> ctrl_f: sub al,'1'
1787 1787 00000772 30E4 <1> xor ah,ah
1788 1788 00000774 EB0A <1> jmp short show_help
1789 1789 <1>
1790 1790 <1> func_key:
1791 1791 <1> ; AL = 0 if we get here
1792 1792 00000776 86C4 <1> xchg al,ah
1793 1793 00000778 3C44 <1> cmp al,68 ; F10
1794 1794 0000077A 77F0 <1> ja short get_char_2
1795 1795 0000077C 2C3B <1> sub al,59 ; F1
1796 1796 0000077E 72EC <1> jb short get_char_2
1797 1797 <1> show_help: ; AX = func key # (0 = F1, 9 = F10)
1798 1798 00000780 57 <1> push di ; Save end-of-cmdline pointer
1799 1799 00000781 C1E008 <1> shl ax,FILENAME_MAX_LG2 ; Convert to pointer
1800 1800 00000784 05[080F] <1> add ax,FKeyName
1801 1801 00000787 97 <1> xchg di,ax
1802 1802 00000788 803D00 <1> cmp byte [di+NULLOFFSET],NULLFILE
1803 1803 0000078B 742D <1> je short fk_nofile ; Undefined F-key
1804 1804 0000078D E89E0D <1> call searchdir
1805 1805 00000790 7428 <1> jz short fk_nofile ; File not found
1806 1806 00000792 56 <1> push si
1807 1807 00000793 E887FB <1> call crlf
1808 1808 00000796 5E <1> pop si
1809 1809 00000797 E8E610 <1> call get_msg_file
1810 1810 0000079A EB0D <1> jmp short fk_wrcmd
1811 1811 <1>
1812 1812 <1> print_version:
1813 1813 0000079C 57 <1> push di ; Command line write pointer
1814 1814 0000079D BE[7C03] <1> mov si,syslinux_banner
1815 1815 000007A0 E887FB <1> call cwritestr
1816 1816 <1> %ifdef HAVE_BIOSNAME
1817 1817 <1> mov si,[BIOSName]
1818 1818 <1> call cwritestr
1819 1819 <1> %endif
1820 1820 000007A3 BE[9803] <1> mov si,copyright_str
1821 1821 000007A6 E881FB <1> call cwritestr
1822 1822 <1>
1823 1823 <1> ; ... fall through ...
1824 1824 <1>
1825 1825 <1> ; Write the boot prompt and command line again and
1826 1826 <1> ; wait for input. Note that this expects the cursor
1827 1827 <1> ; to already have been CRLF'd, and that the old value
1828 1828 <1> ; of DI (the command line write pointer) is on the stack.
1829 1829 <1> fk_wrcmd:
1830 1830 000007A9 BE[CF00] <1> mov si,boot_prompt
1831 1831 000007AC E87BFB <1> call cwritestr
1832 1832 000007AF 5F <1> pop di ; Command line write pointer
1833 1833 000007B0 57 <1> push di
1834 1834 000007B1 C60500 <1> mov byte [di],0 ; Null-terminate command line
1835 1835 000007B4 BE[0000] <1> mov si,command_line
1836 1836 000007B7 E870FB <1> call cwritestr ; Write command line so far
1837 1837 000007BA 5F <1> fk_nofile: pop di
1838 1838 000007BB EBAF <1> jmp short get_char_2
1839 1839 <1>
1840 1840 <1> ;
1841 1841 <1> ; Jump here to run the default command line
1842 1842 <1> ;
1843 1843 <1> auto_boot:
1844 1844 000007BD BE[0402] <1> mov si,default_cmd
1845 1845 000007C0 BF[0000] <1> mov di,command_line
1846 1846 000007C3 B98000 <1> mov cx,(max_cmd_len+4) >> 2
1847 1847 000007C6 F366A5 <1> rep movsd
1848 1848 000007C9 EB0C <1> jmp short load_kernel
1849 1849 <1>
1850 1850 <1> ;
1851 1851 <1> ; Jump here when the command line is completed
1852 1852 <1> ;
1853 1853 <1> command_done:
1854 1854 000007CB E84FFB <1> call crlf
1855 1855 000007CE 81FF[0000] <1> cmp di,command_line ; Did we just hit return?
1856 1856 000007D2 74E9 <1> je auto_boot
1857 1857 000007D4 30C0 <1> xor al,al ; Store a final null
1858 1858 000007D6 AA <1> stosb
1859 1859 <1>
1860 1860 <1> load_kernel: ; Load the kernel now
1861 1861 <1> ;
1862 1862 <1> ; First we need to mangle the kernel name the way DOS would...
1863 1863 <1> ;
1864 1864 000007D7 BE[0000] <1> mov si,command_line
1865 1865 000007DA BF[0C19] <1> mov di,KernelName
1866 1866 000007DD 56 <1> push si
1867 1867 000007DE 57 <1> push di
1868 1868 000007DF E8800E <1> call mangle_name
1869 1869 000007E2 5F <1> pop di
1870 1870 000007E3 5E <1> pop si
1871 1871 <1> ;
1872 1872 <1> ; Fast-forward to first option (we start over from the beginning, since
1873 1873 <1> ; mangle_name doesn't necessarily return a consistent ending state.)
1874 1874 <1> ;
1875 1875 000007E4 AC <1> clin_non_wsp: lodsb
1876 1876 000007E5 3C20 <1> cmp al,' '
1877 1877 000007E7 77FB <1> ja clin_non_wsp
1878 1878 000007E9 20C0 <1> clin_is_wsp: and al,al
1879 1879 000007EB 7405 <1> jz clin_opt_ptr
1880 1880 000007ED AC <1> lodsb
1881 1881 000007EE 3C20 <1> cmp al,' '
1882 1882 000007F0 76F7 <1> jbe clin_is_wsp
1883 1883 000007F2 4E <1> clin_opt_ptr: dec si ; Point to first nonblank
1884 1884 000007F3 8936[0A03] <1> mov [CmdOptPtr],si ; Save ptr to first option
1885 1885 <1> ;
1886 1886 <1> ; If "allowoptions 0", put a null character here in order to ignore any
1887 1887 <1> ; user-specified options.
1888 1888 <1> ;
1889 1889 000007F7 A1[B200] <1> mov ax,[AllowOptions]
1890 1890 000007FA 21C0 <1> and ax,ax
1891 1891 000007FC 7502 <1> jnz clin_opt_ok
1892 1892 000007FE 8804 <1> mov [si],al
1893 1893 <1> clin_opt_ok:
1894 1894 <1>
1895 1895 <1> ;
1896 1896 <1> ; Now check if it is a "virtual kernel"
1897 1897 <1> ;
1898 1898 <1> vk_check:
1899 1899 00000800 31F6 <1> xor si,si ; Beginning of vk_seg
1900 1900 <1> .scan:
1901 1901 00000802 3B36[B600] <1> cmp si,[VKernelBytes]
1902 1902 00000806 734F <1> jae .not_vk
1903 1903 <1>
1904 1904 00000808 1E <1> push ds
1905 1905 00000809 680020 <1> push word vk_seg
1906 1906 0000080C 1F <1> pop ds
1907 1907 <1>
1908 1908 0000080D BF[0404] <1> mov di,VKernelBuf
1909 1909 00000810 E84815 <1> call rllunpack
1910 1910 00000813 1F <1> pop ds
1911 1911 <1> ; SI updated on return
1912 1912 <1>
1913 1913 00000814 29CF <1> sub di,cx ; Return to beginning of buf
1914 1914 00000816 56 <1> push si
1915 1915 00000817 BE[0C19] <1> mov si,KernelName
1916 1916 0000081A B90001 <1> mov cx,FILENAME_MAX
1917 1917 0000081D 26F3A6 <1> es repe cmpsb
1918 1918 00000820 5E <1> pop si
1919 1919 00000821 7402 <1> je .found
1920 1920 00000823 EBDD <1> jmp .scan
1921 1921 <1>
1922 1922 <1> ;
1923 1923 <1> ; We *are* using a "virtual kernel"
1924 1924 <1> ;
1925 1925 <1> .found:
1926 1926 00000825 06 <1> push es
1927 1927 00000826 680030 <1> push word real_mode_seg
1928 1928 00000829 07 <1> pop es
1929 1929 0000082A BF0090 <1> mov di,cmd_line_here
1930 1930 0000082D BE[0806] <1> mov si,VKernelBuf+vk_append
1931 1931 00000830 8B0E[0406] <1> mov cx,[VKernelBuf+vk_appendlen]
1932 1932 00000834 F3A4 <1> rep movsb
1933 1933 00000836 893E[AA00] <1> mov [CmdLinePtr],di ; Where to add rest of cmd
1934 1934 0000083A 07 <1> pop es
1935 1935 0000083B BF[0C19] <1> mov di,KernelName
1936 1936 0000083E 57 <1> push di
1937 1937 0000083F BE[0405] <1> mov si,VKernelBuf+vk_rname
1938 1938 00000842 B90001 <1> mov cx,FILENAME_MAX ; We need ECX == CX later
1939 1939 00000845 F3A4 <1> rep movsb
1940 1940 00000847 5F <1> pop di
1941 1941 <1> %if IS_PXELINUX
1942 1942 <1> mov al,[VKernelBuf+vk_ipappend]
1943 1943 <1> mov [IPAppend],al
1944 1944 <1> %endif
1945 1945 00000848 31DB <1> xor bx,bx ; Try only one version
1946 1946 <1>
1947 1947 <1> %if IS_PXELINUX || IS_ISOLINUX
1948 1948 <1> ; Is this a "localboot" pseudo-kernel?
1949 1949 <1> %if IS_PXELINUX
1950 1950 <1> cmp byte [VKernelBuf+vk_rname+4], 0
1951 1951 <1> %else
1952 1952 0000084A 803E[0405]00 <1> cmp byte [VKernelBuf+vk_rname], 0
1953 1953 <1> %endif
1954 1954 0000084F 7528 <1> jne get_kernel ; No, it's real, go get it
1955 1955 <1>
1956 1956 00000851 A1[0505] <1> mov ax, [VKernelBuf+vk_rname+1]
1957 1957 00000854 E95A0C <1> jmp local_boot
1958 1958 <1> %else
1959 1959 <1> jmp get_kernel
1960 1960 <1> %endif
1961 1961 <1>
1962 1962 <1> .not_vk:
1963 1963 <1>
1964 1964 <1> ;
1965 1965 <1> ; Not a "virtual kernel" - check that's OK and construct the command line
1966 1966 <1> ;
1967 1967 00000857 833E[B000]00 <1> cmp word [AllowImplicit],byte 0
1968 1968 0000085C 7457 <1> je bad_implicit
1969 1969 0000085E 06 <1> push es
1970 1970 0000085F 56 <1> push si
1971 1971 00000860 57 <1> push di
1972 1972 00000861 BF0030 <1> mov di,real_mode_seg
1973 1973 00000864 8EC7 <1> mov es,di
1974 1974 00000866 BE[0808] <1> mov si,AppendBuf
1975 1975 00000869 BF0090 <1> mov di,cmd_line_here
1976 1976 0000086C 8B0E[A400] <1> mov cx,[AppendLen]
1977 1977 00000870 F3A4 <1> rep movsb
1978 1978 00000872 893E[AA00] <1> mov [CmdLinePtr],di
1979 1979 00000876 5F <1> pop di
1980 1980 00000877 5E <1> pop si
1981 1981 00000878 07 <1> pop es
1982 1982 <1> ;
1983 1983 <1> ; Find the kernel on disk
1984 1984 <1> ;
1985 1985 00000879 C606[0C1A]00 <1> get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension
1986 1986 <1> %if IS_SYSLINUX || IS_MDSLINUX ; SYSLINUX has to deal with DOS mangled names...
1987 1987 <1> mov eax,[KernelName+8] ; Save initial extension
1988 1988 <1> mov [exten_table_end],eax ; Last case == initial ext.
1989 1989 <1> %else
1990 1990 0000087E BF[0C19] <1> mov di,KernelName+4*IS_PXELINUX
1991 1991 00000881 30C0 <1> xor al,al
1992 1992 00000883 B9FB00 <1> mov cx,FILENAME_MAX-5 ; Need 4 chars + null
1993 1993 00000886 F2AE <1> repne scasb ; Scan for final null
1994 1994 00000888 7501 <1> jne .no_skip
1995 1995 0000088A 4F <1> dec di ; Point to final null
1996 1996 0000088B 893E[0803] <1> .no_skip: mov [KernelExtPtr],di
1997 1997 <1> %endif
1998 1998 0000088F BB[1005] <1> mov bx,exten_table
1999 1999 00000892 53 <1> .search_loop: push bx
2000 2000 00000893 BF[0C19] <1> mov di,KernelName ; Search on disk
2001 2001 00000896 E8950C <1> call searchdir
2002 2002 00000899 5B <1> pop bx
2003 2003 0000089A 0F85B300 <1> jnz kernel_good
2004 2004 0000089E 668B07 <1> mov eax,[bx] ; Try a different extension
2005 2005 <1> %if IS_SYSLINUX || IS_MDSLINUX
2006 2006 <1> mov [KernelName+8],eax
2007 2007 <1> %else
2008 2008 000008A1 8B36[0803] <1> mov si,[KernelExtPtr]
2009 2009 000008A5 668904 <1> mov [si],eax
2010 2010 000008A8 C6440400 <1> mov byte [si+4],0
2011 2011 <1> %endif
2012 2012 000008AC 83C304 <1> add bx,byte 4
2013 2013 000008AF 81FB[2405] <1> cmp bx,exten_table_end
2014 2014 000008B3 76DD <1> jna .search_loop ; allow == case (final case)
2015 2015 <1> ; Fall into bad_kernel
2016 2016 <1> ;
2017 2017 <1> ; bad_kernel: Kernel image not found
2018 2018 <1> ; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0"
2019 2019 <1> ;
2020 2020 <1> bad_implicit:
2021 2021 <1> bad_kernel:
2022 2022 000008B5 8B0E[A800] <1> mov cx,[OnerrorLen]
2023 2023 000008B9 21C9 <1> and cx,cx
2024 2024 000008BB 751A <1> jnz on_error
2025 2025 <1> .really:
2026 2026 000008BD BE[0C19] <1> mov si,KernelName
2027 2027 000008C0 BF[0C1A] <1> mov di,KernelCName
2028 2028 000008C3 57 <1> push di
2029 2029 000008C4 E8D20D <1> call unmangle_name ; Get human form
2030 2030 000008C7 BE[DA00] <1> mov si,err_notfound ; Complain about missing kernel
2031 2031 000008CA E85DFA <1> call cwritestr
2032 2032 000008CD 5E <1> pop si ; KernelCName
2033 2033 000008CE E859FA <1> call cwritestr
2034 2034 000008D1 BE[C905] <1> mov si,crlf_msg
2035 2035 000008D4 E9420C <1> jmp abort_load ; Ask user for clue
2036 2036 <1>
2037 2037 <1> ;
2038 2038 <1> ; on_error: bad kernel, but we have onerror set
2039 2039 <1> ;
2040 2040 <1> on_error:
2041 2041 000008D7 BE[080C] <1> mov si,Onerror
2042 2042 000008DA BF[0000] <1> mov di,command_line
2043 2043 000008DD 56 <1> push si ; <A>
2044 2044 000008DE 57 <1> push di ; <B>
2045 2045 000008DF 51 <1> push cx ; <C>
2046 2046 000008E0 51 <1> push cx ; <D>
2047 2047 000008E1 57 <1> push di ; <E>
2048 2048 000008E2 F3A6 <1> repe cmpsb
2049 2049 000008E4 5F <1> pop di ; <E> di == command_line
2050 2050 000008E5 5B <1> pop bx ; <D> bx == [OnerrorLen]
2051 2051 000008E6 74D5 <1> je bad_kernel.really ; Onerror matches command_line already
2052 2052 000008E8 F7DB <1> neg bx ; bx == -[OnerrorLen]
2053 2053 000008EA 8D8FFF01 <1> lea cx,[max_cmd_len+bx]
2054 2054 <1> ; CX == max_cmd_len-[OnerrorLen]
2055 2055 000008EE BF[FE01] <1> mov di,command_line+max_cmd_len-1
2056 2056 000008F1 C6450100 <1> mov byte [di+1],0 ; Enforce null-termination
2057 2057 000008F5 8D31 <1> lea si,[di+bx]
2058 2058 000008F7 FD <1> std
2059 2059 000008F8 F3A4 <1> rep movsb ; Make space in command_line
2060 2060 000008FA FC <1> cld
2061 2061 000008FB 59 <1> pop cx ; <C> cx == [OnerrorLen]
2062 2062 000008FC 5F <1> pop di ; <B> di == command_line
2063 2063 000008FD 5E <1> pop si ; <A> si == Onerror
2064 2064 000008FE F3A4 <1> rep movsb
2065 2065 00000900 E9D4FE <1> jmp load_kernel
2066 2066 <1>
2067 2067 <1> ;
2068 2068 <1> ; kernel_corrupt: Called if the kernel file does not seem healthy
2069 2069 <1> ;
2070 2070 00000903 BE[F800] <1> kernel_corrupt: mov si,err_notkernel
2071 2071 00000906 E9100C <1> jmp abort_load
2072 2072 <1>
2073 2073 <1> ;
2074 2074 <1> ; Get a key, observing ThisKbdTO and ThisTotalTO -- those are timeouts
2075 2075 <1> ; which can be adjusted by the caller based on the corresponding
2076 2076 <1> ; master variables; on return they're updated.
2077 2077 <1> ;
2078 2078 <1> ; This cheats. If we say "no timeout" we actually get a timeout of
2079 2079 <1> ; 7.5 years.
2080 2080 <1> ;
2081 2081 <1> getchar_timeout:
2082 2082 00000909 E88B17 <1> call vgashowcursor
2083 2083 <1> RESET_IDLE
2084 2084 <2>
2085 2085 <1>
2086 2086 <1> .loop:
2087 2087 0000090C FF366C04 <1> push word [BIOS_timer]
2088 2088 00000910 E86211 <1> call pollchar
2089 2089 00000913 7528 <1> jnz .got_char
2090 2090 00000915 58 <1> pop ax
2091 2091 00000916 3B066C04 <1> cmp ax,[BIOS_timer] ; Has the timer advanced?
2092 2092 0000091A 74F0 <1> je .loop
2093 2093 <1> DO_IDLE
2094 2094 <2>
2095 2095 <1>
2096 2096 0000091C 66FF0E[0003] <1> dec dword [ThisKbdTo]
2097 2097 00000921 7407 <1> jz .timeout
2098 2098 00000923 66FF0E[0403] <1> dec dword [ThisTotalTo]
2099 2099 00000928 75E2 <1> jnz .loop
2100 2100 <1>
2101 2101 <1> .timeout:
2102 2102 <1> ; Timeout!!!!
2103 2103 0000092A 59 <1> pop cx ; Discard return address
2104 2104 0000092B E86F17 <1> call vgahidecursor
2105 2105 0000092E BE[080A] <1> mov si,Ontimeout ; Copy ontimeout command
2106 2106 00000931 BF[0000] <1> mov di,command_line
2107 2107 00000934 8B0E[A600] <1> mov cx,[OntimeoutLen] ; if we have one...
2108 2108 00000938 F3A4 <1> rep movsb
2109 2109 0000093A E98EFE <1> jmp command_done
2110 2110 <1>
2111 2111 <1> .got_char:
2112 2112 0000093D 59 <1> pop cx ; Discard
2113 2113 0000093E E85E11 <1> call getchar
2114 2114 00000941 E85917 <1> call vgahidecursor
2115 2115 00000944 C3 <1> ret
2116 2116 <1>
2117 2117 <1> ;
2118 2118 <1> ; This is it! We have a name (and location on the disk)... let's load
2119 2119 <1> ; that sucker!! First we have to decide what kind of file this is; base
2120 2120 <1> ; that decision on the file extension. The following extensions are
2121 2121 <1> ; recognized; case insensitive:
2122 2122 <1> ;
2123 2123 <1> ; .com - COMBOOT image
2124 2124 <1> ; .cbt - COMBOOT image
2125 2125 <1> ; .c32 - COM32 image
2126 2126 <1> ; .bs - Boot sector
2127 2127 <1> ; .0 - PXE bootstrap program (PXELINUX only)
2128 2128 <1> ; .bin - Boot sector
2129 2129 <1> ; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only)
2130 2130 <1> ; .img - Floppy image (ISOLINUX only)
2131 2131 <1> ;
2132 2132 <1> ; Anything else is assumed to be a Linux kernel.
2133 2133 <1> ;
2134 2134 <1> section .bss
2135 2135 <1> alignb 4
2136 2136 000002F8 <res 00000004> <1> Kernel_EAX resd 1
2137 2137 000002FC <res 00000002> <1> Kernel_SI resw 1
2138 2138 <1>
2139 2139 <1> section .text
2140 2140 <1> kernel_good_saved:
2141 2141 <1> ; Alternate entry point for which the return from
2142 2142 <1> ; searchdir is stored in memory. This is used for
2143 2143 <1> ; COMBOOT function INT 22h, AX=0016h.
2144 2144 00000945 8B36[FC02] <1> mov si,[Kernel_SI]
2145 2145 00000949 66A1[F802] <1> mov eax,[Kernel_EAX]
2146 2146 0000094D 8B16[FA02] <1> mov dx,[Kernel_EAX+2]
2147 2147 <1>
2148 2148 <1> kernel_good:
2149 2149 00000951 60 <1> pusha
2150 2150 00000952 BE[0C19] <1> mov si,KernelName
2151 2151 00000955 BF[0C1A] <1> mov di,KernelCName
2152 2152 00000958 E83E0D <1> call unmangle_name
2153 2153 0000095B 81EF[0C1A] <1> sub di,KernelCName
2154 2154 0000095F 893E[0819] <1> mov [KernelCNameLen],di
2155 2155 00000963 61 <1> popa
2156 2156 <1>
2157 2157 <1> %if IS_SYSLINUX || IS_MDSLINUX
2158 2158 <1> mov ecx,[KernelName+7]
2159 2159 <1> mov cl,'.'
2160 2160 <1> %else
2161 2161 00000964 57 <1> push di
2162 2162 00000965 50 <1> push ax
2163 2163 00000966 BF[0C19] <1> mov di,KernelName+4*IS_PXELINUX
2164 2164 00000969 30C0 <1> xor al,al
2165 2165 0000096B B90001 <1> mov cx,FILENAME_MAX
2166 2166 0000096E F2AE <1> repne scasb
2167 2167 00000970 7501 <1> jne .one_step
2168 2168 00000972 4F <1> dec di
2169 2169 00000973 668B4DFC <1> .one_step: mov ecx,[di-4] ; 4 bytes before end
2170 2170 00000977 58 <1> pop ax
2171 2171 00000978 5F <1> pop di
2172 2172 <1> %endif
2173 2173 <1>
2174 2174 <1> ;
2175 2175 <1> ; At this point, DX:AX contains the size of the kernel, and SI contains
2176 2176 <1> ; the file handle/cluster pointer.
2177 2177 <1> ;
2178 2178 00000979 6681C900202020 <1> or ecx,20202000h ; Force lower case
2179 2179 <1>
2180 2180 00000980 6681F92E636F6D <1> cmp ecx,'.com'
2181 2181 00000987 0F844604 <1> je is_comboot_image
2182 2182 0000098B 6681F92E636274 <1> cmp ecx,'.cbt'
2183 2183 00000992 0F843B04 <1> je is_comboot_image
2184 2184 00000996 6681F92E633332 <1> cmp ecx,'.c32'
2185 2185 0000099D 0F849107 <1> je is_com32_image
2186 2186 <1> %if IS_ISOLINUX
2187 2187 000009A1 6681F92E696D67 <1> cmp ecx,'.img'
2188 2188 000009A8 0F840B0A <1> je is_disk_image
2189 2189 <1> %endif
2190 2190 000009AC 6681F92E627373 <1> cmp ecx,'.bss'
2191 2191 000009B3 0F84F709 <1> je is_bss_sector
2192 2192 000009B7 6681F92E62696E <1> cmp ecx,'.bin'
2193 2193 000009BE 0F847709 <1> je is_bootsector
2194 2194 <1> %if IS_SYSLINUX || IS_MDSLINUX
2195 2195 <1> cmp ecx,'.bs '
2196 2196 <1> je is_bootsector
2197 2197 <1> cmp ecx,'.0 '
2198 2198 <1> je is_bootsector
2199 2199 <1> %else
2200 2200 000009C2 66C1E908 <1> shr ecx,8
2201 2201 000009C6 6681F92E627300 <1> cmp ecx,'.bs'
2202 2202 000009CD 0F846809 <1> je is_bootsector
2203 2203 000009D1 66C1E908 <1> shr ecx,8
2204 2204 000009D5 81F92E30 <1> cmp cx,'.0'
2205 2205 000009D9 0F845C09 <1> je is_bootsector
2206 2206 <1> %endif
2207 2207 <1> ; Otherwise Linux kernel
2208 2208 <1>
2209 2209 <1> section .bss
2210 2210 000002FE <res 00000001>- <1> alignb 4
2211 2211 000002FE <rept> <1>
2212 2212 00000300 <res 00000004> <1> ThisKbdTo resd 1 ; Temporary holder for KbdTimeout
2213 2213 00000304 <res 00000004> <1> ThisTotalTo resd 1 ; Temporary holder for TotalTimeout
2214 2214 00000308 <res 00000002> <1> KernelExtPtr resw 1 ; During search, final null pointer
2215 2215 0000030A <res 00000002> <1> CmdOptPtr resw 1 ; Pointer to first option on cmd line
2216 2216 0000030C <res 00000001> <1> KbdFlags resb 1 ; Check for keyboard escapes
2217 2217 0000030D <res 00000001> <1> FuncFlag resb 1 ; Escape sequences received from keyboard
2218 2218 <1>
2219 2219 <1> section .text
2220 2220
2221 2221 ;
2222 2222 ; Linux kernel loading code is common.
2223 2223 ;
2224 2224 %include "runkernel.inc"
2225 2225 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
2226 2226 <1> ;; -----------------------------------------------------------------------
2227 2227 <1> ;;
2228 2228 <1> ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
2229 2229 <1> ;;
2230 2230 <1> ;; This program is free software; you can redistribute it and/or modify
2231 2231 <1> ;; it under the terms of the GNU General Public License as published by
2232 2232 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
2233 2233 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
2234 2234 <1> ;; (at your option) any later version; incorporated herein by reference.
2235 2235 <1> ;;
2236 2236 <1> ;; -----------------------------------------------------------------------
2237 2237 <1>
2238 2238 <1> ;;
2239 2239 <1> ;; runkernel.inc
2240 2240 <1> ;;
2241 2241 <1> ;; Common code for running a Linux kernel
2242 2242 <1> ;;
2243 2243 <1>
2244 2244 <1> ;
2245 2245 <1> ; Hook macros, that may or may not be defined
2246 2246 <1> ;
2247 2247 <1> %ifndef HAVE_SPECIAL_APPEND
2248 2248 <1> %macro SPECIAL_APPEND 0
2249 2249 <1> %endmacro
2250 2250 <1> %endif
2251 2251 <1>
2252 2252 <1> %ifndef HAVE_UNLOAD_PREP
2253 2253 <1> %macro UNLOAD_PREP 0
2254 2254 <1> %endmacro
2255 2255 <1> %endif
2256 2256 <1>
2257 2257 <1> ;
2258 2258 <1> ; A Linux kernel consists of three parts: boot sector, setup code, and
2259 2259 <1> ; kernel code. The boot sector is never executed when using an external
2260 2260 <1> ; booting utility, but it contains some status bytes that are necessary.
2261 2261 <1> ;
2262 2262 <1> ; First check that our kernel is at least 1K and less than 8M (if it is
2263 2263 <1> ; more than 8M, we need to change the logic for loading it anyway...)
2264 2264 <1> ;
2265 2265 <1> ; We used to require the kernel to be 64K or larger, but it has gotten
2266 2266 <1> ; popular to use the Linux kernel format for other things, which may
2267 2267 <1> ; not be so large.
2268 2268 <1> ;
2269 2269 <1> is_linux_kernel:
2270 2270 000009DD 81FA8000 <1> cmp dx,80h ; 8 megs
2271 2271 000009E1 0F871EFF <1> ja kernel_corrupt
2272 2272 000009E5 21D2 <1> and dx,dx
2273 2273 000009E7 7507 <1> jnz kernel_sane
2274 2274 000009E9 3D0004 <1> cmp ax,1024 ; Bootsect + 1 setup sect
2275 2275 000009EC 0F8213FF <1> jb kernel_corrupt
2276 2276 000009F0 50 <1> kernel_sane: push ax
2277 2277 000009F1 52 <1> push dx
2278 2278 000009F2 56 <1> push si
2279 2279 000009F3 BE[A403] <1> mov si,loading_msg
2280 2280 000009F6 E831F9 <1> call cwritestr
2281 2281 <1> ;
2282 2282 <1> ; Now start transferring the kernel
2283 2283 <1> ;
2284 2284 000009F9 680030 <1> push word real_mode_seg
2285 2285 000009FC 07 <1> pop es
2286 2286 <1>
2287 2287 000009FD 660FB7C0 <1> movzx eax,ax ; Fix this by using a 32-bit
2288 2288 00000A01 66C1E210 <1> shl edx,16 ; register for the kernel size
2289 2289 00000A05 6609D0 <1> or eax,edx
2290 2290 00000A08 66A3[1403] <1> mov [KernelSize],eax
2291 2291 00000A0C 6605FF070000 <1> add eax,SECTOR_SIZE-1
2292 2292 00000A12 66C1E80B <1> shr eax,SECTOR_SHIFT
2293 2293 00000A16 66A3[1803] <1> mov [KernelSects],eax ; Total sectors in kernel
2294 2294 <1>
2295 2295 <1> ;
2296 2296 <1> ; Now, if we transfer these straight, we'll hit 64K boundaries. Hence we
2297 2297 <1> ; have to see if we're loading more than 64K, and if so, load it step by
2298 2298 <1> ; step.
2299 2299 <1> ;
2300 2300 <1>
2301 2301 <1> ;
2302 2302 <1> ; Start by loading the bootsector/setup code, to see if we need to
2303 2303 <1> ; do something funky. It should fit in the first 32K (loading 64K won't
2304 2304 <1> ; work since we might have funny stuff up near the end of memory).
2305 2305 <1> ; If we have larger than 32K clusters, yes, we're hosed.
2306 2306 <1> ;
2307 2307 00000A1A E8E60A <1> call abort_check ; Check for abort key
2308 2308 00000A1D 66B910000000 <1> mov ecx,8000h >> SECTOR_SHIFT ; Half a moby (32K)
2309 2309 00000A23 663B0E[1803] <1> cmp ecx,[KernelSects]
2310 2310 00000A28 7605 <1> jna .normalkernel
2311 2311 00000A2A 668B0E[1803] <1> mov ecx,[KernelSects]
2312 2312 <1> .normalkernel:
2313 2313 00000A2F 66290E[1803] <1> sub [KernelSects],ecx
2314 2314 00000A34 31DB <1> xor bx,bx
2315 2315 00000A36 5E <1> pop si ; Cluster pointer on stack
2316 2316 00000A37 E8640C <1> call getfssec
2317 2317 00000A3A 26813EFE0155AA <1> cmp word [es:bs_bootsign],0AA55h
2318 2318 00000A41 0F85BEFE <1> jne kernel_corrupt ; Boot sec signature missing
2319 2319 <1>
2320 2320 <1> ;
2321 2321 <1> ; Save the cluster pointer for later...
2322 2322 <1> ;
2323 2323 00000A45 56 <1> push si
2324 2324 <1> ;
2325 2325 <1> ; Get the BIOS' idea of what the size of high memory is.
2326 2326 <1> ;
2327 2327 00000A46 E86C16 <1> call highmemsize
2328 2328 <1> ;
2329 2329 <1> ; Construct the command line (append options have already been copied)
2330 2330 <1> ;
2331 2331 <1> construct_cmdline:
2332 2332 00000A49 8B3E[AA00] <1> mov di,[CmdLinePtr]
2333 2333 00000A4D BE[0B00] <1> mov si,boot_image ; BOOT_IMAGE=
2334 2334 00000A50 B90B00 <1> mov cx,boot_image_len
2335 2335 00000A53 F3A4 <1> rep movsb
2336 2336 00000A55 BE[0C1A] <1> mov si,KernelCName ; Unmangled kernel name
2337 2337 00000A58 8B0E[0819] <1> mov cx,[KernelCNameLen]
2338 2338 00000A5C F3A4 <1> rep movsb
2339 2339 00000A5E B020 <1> mov al,' ' ; Space
2340 2340 00000A60 AA <1> stosb
2341 2341 <1>
2342 2342 <1> SPECIAL_APPEND ; Module-specific hook
2343 2343 <1>
2344 2344 00000A61 8B36[0A03] <1> mov si,[CmdOptPtr] ; Options from user input
2345 2345 00000A65 E83E17 <1> call strcpy
2346 2346 <1>
2347 2347 <1> ;
2348 2348 <1> ; Scan through the command line for anything that looks like we might be
2349 2349 <1> ; interested in. The original version of this code automatically assumed
2350 2350 <1> ; the first option was BOOT_IMAGE=, but that is no longer certain.
2351 2351 <1> ;
2352 2352 00000A68 BE0090 <1> mov si,cmd_line_here
2353 2353 00000A6B 31C0 <1> xor ax,ax
2354 2354 00000A6D A3[2403] <1> mov [InitRDPtr],ax ; No initrd= option (yet)
2355 2355 00000A70 06 <1> push es ; Set DS <- real_mode_seg
2356 2356 00000A71 1F <1> pop ds
2357 2357 00000A72 AC <1> get_next_opt: lodsb
2358 2358 00000A73 20C0 <1> and al,al
2359 2359 00000A75 0F848500 <1> jz cmdline_end
2360 2360 00000A79 3C20 <1> cmp al,' '
2361 2361 00000A7B 76F5 <1> jbe get_next_opt
2362 2362 00000A7D 4E <1> dec si
2363 2363 00000A7E 668B04 <1> mov eax,[si]
2364 2364 00000A81 663D7667613D <1> cmp eax,'vga='
2365 2365 00000A87 742F <1> je is_vga_cmd
2366 2366 00000A89 663D6D656D3D <1> cmp eax,'mem='
2367 2367 00000A8F 7456 <1> je is_mem_cmd
2368 2368 <1> %if IS_PXELINUX
2369 2369 <1> cmp eax,'keep' ; Is it "keeppxe"?
2370 2370 <1> jne .notkeep
2371 2371 <1> cmp dword [si+3],'ppxe'
2372 2372 <1> jne .notkeep
2373 2373 <1> cmp byte [si+7],' ' ; Must be whitespace or EOS
2374 2374 <1> ja .notkeep
2375 2375 <1> or byte [cs:KeepPXE],1
2376 2376 <1> .notkeep:
2377 2377 <1> %endif
2378 2378 00000A91 06 <1> push es ; Save ES -> real_mode_seg
2379 2379 00000A92 0E <1> push cs
2380 2380 00000A93 07 <1> pop es ; Set ES <- normal DS
2381 2381 00000A94 BF[1104] <1> mov di,initrd_cmd
2382 2382 00000A97 B90700 <1> mov cx,initrd_cmd_len
2383 2383 00000A9A F3A6 <1> repe cmpsb
2384 2384 00000A9C 7511 <1> jne .not_initrd
2385 2385 <1>
2386 2386 00000A9E 3C20 <1> cmp al,' '
2387 2387 00000AA0 7607 <1> jbe .noramdisk
2388 2388 00000AA2 2E8936[2403] <1> mov [cs:InitRDPtr],si
2389 2389 00000AA7 EB06 <1> jmp .not_initrd
2390 2390 <1> .noramdisk:
2391 2391 00000AA9 31C0 <1> xor ax,ax
2392 2392 00000AAB 2EA3[2403] <1> mov [cs:InitRDPtr],ax
2393 2393 00000AAF 07 <1> .not_initrd: pop es ; Restore ES -> real_mode_seg
2394 2394 00000AB0 AC <1> skip_this_opt: lodsb ; Load from command line
2395 2395 00000AB1 3C20 <1> cmp al,' '
2396 2396 00000AB3 77FB <1> ja skip_this_opt
2397 2397 00000AB5 4E <1> dec si
2398 2398 00000AB6 EBBA <1> jmp short get_next_opt
2399 2399 <1> is_vga_cmd:
2400 2400 00000AB8 83C604 <1> add si,4
2401 2401 00000ABB 668B44FF <1> mov eax,[si-1]
2402 2402 00000ABF BBFFFF <1> mov bx,-1
2403 2403 00000AC2 663D3D6E6F72 <1> cmp eax,'=nor' ; vga=normal
2404 2404 00000AC8 7417 <1> je vc0
2405 2405 00000ACA 4B <1> dec bx ; bx <- -2
2406 2406 00000ACB 663D3D657874 <1> cmp eax,'=ext' ; vga=ext
2407 2407 00000AD1 740E <1> je vc0
2408 2408 00000AD3 4B <1> dec bx ; bx <- -3
2409 2409 00000AD4 663D3D61736B <1> cmp eax,'=ask' ; vga=ask
2410 2410 00000ADA 7405 <1> je vc0
2411 2411 00000ADC E8AF0C <1> call parseint ; vga=<number>
2412 2412 00000ADF 72CF <1> jc skip_this_opt ; Not an integer
2413 2413 00000AE1 891EFA01 <1> vc0: mov [bs_vidmode],bx ; Set video mode
2414 2414 00000AE5 EBC9 <1> jmp short skip_this_opt
2415 2415 <1> is_mem_cmd:
2416 2416 00000AE7 83C604 <1> add si,4
2417 2417 00000AEA E8A10C <1> call parseint
2418 2418 00000AED 72C1 <1> jc skip_this_opt ; Not an integer
2419 2419 <1> %if HIGHMEM_SLOP != 0
2420 2420 00000AEF 6681EB00000200 <1> sub ebx,HIGHMEM_SLOP
2421 2421 <1> %endif
2422 2422 00000AF6 2E66891E[7803] <1> mov [cs:HighMemSize],ebx
2423 2423 00000AFC EBB2 <1> jmp short skip_this_opt
2424 2424 <1> cmdline_end:
2425 2425 00000AFE 0E <1> push cs ; Restore standard DS
2426 2426 00000AFF 1F <1> pop ds
2427 2427 00000B00 81EE0090 <1> sub si,cmd_line_here
2428 2428 00000B04 8936[2003] <1> mov [CmdLineLen],si ; Length including final null
2429 2429 <1> ;
2430 2430 <1> ; Now check if we have a large kernel, which needs to be loaded high
2431 2431 <1> ;
2432 2432 00000B08 66C706[1003]FFFFFF- <1> mov dword [RamdiskMax], HIGHMEM_MAX ; Default initrd limit
2433 2433 00000B10 37 <1>
2434 2434 00000B11 2666813E0202486472- <1> cmp dword [es:su_header],HEADER_ID ; New setup code ID
2435 2435 00000B1A 53 <1>
2436 2436 00000B1B 0F859401 <1> jne old_kernel ; Old kernel, load low
2437 2437 00000B1F 26813E06020002 <1> cmp word [es:su_version],0200h ; Setup code version 2.0
2438 2438 00000B26 0F828901 <1> jb old_kernel ; Old kernel, load low
2439 2439 00000B2A 26813E06020102 <1> cmp word [es:su_version],0201h ; Version 2.01+?
2440 2440 00000B31 721F <1> jb new_kernel ; If 2.00, skip this step
2441 2441 00000B33 26C7062402F48F <1> mov word [es:su_heapend],linux_stack ; Set up the heap
2442 2442 00000B3A 26800E110280 <1> or byte [es:su_loadflags],80h ; Let the kernel know we care
2443 2443 00000B40 26813E06020302 <1> cmp word [es:su_version],0203h ; Version 2.03+?
2444 2444 00000B47 7209 <1> jb new_kernel ; Not 2.03+
2445 2445 00000B49 2666A12C02 <1> mov eax,[es:su_ramdisk_max]
2446 2446 00000B4E 66A3[1003] <1> mov [RamdiskMax],eax ; Set the ramdisk limit
2447 2447 <1>
2448 2448 <1> ;
2449 2449 <1> ; We definitely have a new-style kernel. Let the kernel know who we are,
2450 2450 <1> ; and that we are clueful
2451 2451 <1> ;
2452 2452 <1> new_kernel:
2453 2453 00000B52 26C606100233 <1> mov byte [es:su_loader],my_id ; Show some ID
2454 2454 00000B58 260FB606F101 <1> movzx ax,byte [es:bs_setupsecs] ; Variable # of setup sectors
2455 2455 00000B5E A3[2203] <1> mov [SetupSecs],ax
2456 2456 00000B61 6631C0 <1> xor eax,eax
2457 2457 00000B64 2666A31C02 <1> mov [es:su_ramdisklen],eax ; No initrd loaded yet
2458 2458 <1>
2459 2459 <1> ;
2460 2460 <1> ; About to load the kernel. This is a modern kernel, so use the boot flags
2461 2461 <1> ; we were provided.
2462 2462 <1> ;
2463 2463 00000B69 26A01102 <1> mov al,[es:su_loadflags]
2464 2464 00000B6D A2[2603] <1> mov [LoadFlags],al
2465 2465 <1> ;
2466 2466 <1> ; Load the kernel. We always load it at 100000h even if we're supposed to
2467 2467 <1> ; load it "low"; for a "low" load we copy it down to low memory right before
2468 2468 <1> ; jumping to it.
2469 2469 <1> ;
2470 2470 <1> read_kernel:
2471 2471 00000B70 BE[0C1A] <1> mov si,KernelCName ; Print kernel name part of
2472 2472 00000B73 E8B4F7 <1> call cwritestr ; "Loading" message
2473 2473 00000B76 BE[AD03] <1> mov si,dotdot_msg ; Print dots
2474 2474 00000B79 E8AEF7 <1> call cwritestr
2475 2475 <1>
2476 2476 00000B7C 66A1[7803] <1> mov eax,[HighMemSize]
2477 2477 00000B80 662D00001000 <1> sub eax,100000h ; Load address
2478 2478 00000B86 663B06[1403] <1> cmp eax,[KernelSize]
2479 2479 00000B8B 0F823202 <1> jb no_high_mem ; Not enough high memory
2480 2480 <1> ;
2481 2481 <1> ; Move the stuff beyond the setup code to high memory at 100000h
2482 2482 <1> ;
2483 2483 00000B8F 660FB736[2203] <1> movzx esi,word [SetupSecs] ; Setup sectors
2484 2484 00000B95 46 <1> inc si ; plus 1 boot sector
2485 2485 00000B96 C1E609 <1> shl si,9 ; Convert to bytes
2486 2486 00000B99 66B900800000 <1> mov ecx,8000h ; 32K
2487 2487 00000B9F 6629F1 <1> sub ecx,esi ; Number of bytes to copy
2488 2488 00000BA2 6651 <1> push ecx
2489 2489 00000BA4 6681C600000300 <1> add esi,(real_mode_seg << 4) ; Pointer to source
2490 2490 00000BAB 66BF00001000 <1> mov edi,100000h ; Copy to address 100000h
2491 2491 <1>
2492 2492 00000BB1 E8(3000) <1> call bcopy ; Transfer to high memory
2493 2493 <1>
2494 2494 <1> ; On exit EDI -> where to load the rest
2495 2495 <1>
2496 2496 00000BB4 BE[AE03] <1> mov si,dot_msg ; Progress report
2497 2497 00000BB7 E870F7 <1> call cwritestr
2498 2498 00000BBA E84609 <1> call abort_check
2499 2499 <1>
2500 2500 00000BBD 6659 <1> pop ecx ; Number of bytes in the initial portion
2501 2501 00000BBF 5E <1> pop si ; Restore file handle/cluster pointer
2502 2502 00000BC0 66A1[1403] <1> mov eax,[KernelSize]
2503 2503 00000BC4 662D00800000 <1> sub eax,8000h ; Amount of kernel not yet loaded
2504 2504 00000BCA 7605 <1> jbe high_load_done ; Zero left (tiny kernel)
2505 2505 <1>
2506 2506 00000BCC 31D2 <1> xor dx,dx ; No padding needed
2507 2507 00000BCE E81412 <1> call load_high ; Copy the file
2508 2508 <1>
2509 2509 <1> high_load_done:
2510 2510 00000BD1 66893E[1C03] <1> mov [KernelEnd],edi
2511 2511 00000BD6 B80030 <1> mov ax,real_mode_seg ; Set to real mode seg
2512 2512 00000BD9 8EC0 <1> mov es,ax
2513 2513 <1>
2514 2514 00000BDB BE[AE03] <1> mov si,dot_msg
2515 2515 00000BDE E849F7 <1> call cwritestr
2516 2516 <1>
2517 2517 <1> ;
2518 2518 <1> ; Now see if we have an initial RAMdisk; if so, do requisite computation
2519 2519 <1> ; We know we have a new kernel; the old_kernel code already will have objected
2520 2520 <1> ; if we tried to load initrd using an old kernel
2521 2521 <1> ;
2522 2522 <1> load_initrd:
2523 2523 00000BE1 833E[2403]00 <1> cmp word [InitRDPtr],0
2524 2524 00000BE6 7403 <1> jz nk_noinitrd
2525 2525 00000BE8 E8E300 <1> call parse_load_initrd
2526 2526 <1> nk_noinitrd:
2527 2527 <1> ;
2528 2528 <1> ; Abandon hope, ye that enter here! We do no longer permit aborts.
2529 2529 <1> ;
2530 2530 00000BEB E81509 <1> call abort_check ; Last chance!!
2531 2531 <1>
2532 2532 00000BEE BE[8803] <1> mov si,ready_msg
2533 2533 00000BF1 E836F7 <1> call cwritestr
2534 2534 <1>
2535 2535 00000BF4 E87814 <1> call vgaclearmode ; We can't trust ourselves after this
2536 2536 <1>
2537 2537 <1> UNLOAD_PREP ; Module-specific hook
2538 2538 <1>
2539 2539 <1> ;
2540 2540 <1> ; Now, if we were supposed to load "low", copy the kernel down to 10000h
2541 2541 <1> ; and the real mode stuff to 90000h. We assume that all bzImage kernels are
2542 2542 <1> ; capable of starting their setup from a different address.
2543 2543 <1> ;
2544 2544 00000BF7 B80030 <1> mov ax,real_mode_seg
2545 2545 00000BFA 8EE0 <1> mov fs,ax
2546 2546 <1>
2547 2547 <1> ;
2548 2548 <1> ; Copy command line. Unfortunately, the kernel boot protocol requires
2549 2549 <1> ; the command line to exist in the 9xxxxh range even if the rest of the
2550 2550 <1> ; setup doesn't.
2551 2551 <1> ;
2552 2552 00000BFC FA <1> cli ; In case of hooked interrupts
2553 2553 00000BFD F606[2603]01 <1> test byte [LoadFlags],LOAD_HIGH
2554 2554 00000C02 7415 <1> jz need_high_cmdline
2555 2555 00000C04 64813E06020202 <1> cmp word [fs:su_version],0202h ; Support new cmdline protocol?
2556 2556 00000C0B 720C <1> jb need_high_cmdline
2557 2557 <1> ; New cmdline protocol
2558 2558 <1> ; Store 32-bit (flat) pointer to command line
2559 2559 00000C0D 6466C7062802009003- <1> mov dword [fs:su_cmd_line_ptr],(real_mode_seg << 4) + cmd_line_here
2560 2560 00000C16 00 <1>
2561 2561 00000C17 EB70 <1> jmp short in_proper_place
2562 2562 <1>
2563 2563 <1> need_high_cmdline:
2564 2564 <1> ;
2565 2565 <1> ; Copy command line up to 90000h
2566 2566 <1> ;
2567 2567 00000C19 B80090 <1> mov ax,9000h ; Note AL <- 0
2568 2568 00000C1C 8EC0 <1> mov es,ax
2569 2569 00000C1E BE0090 <1> mov si,cmd_line_here
2570 2570 00000C21 89F7 <1> mov di,si
2571 2571 00000C23 64C70620003FA3 <1> mov [fs:kern_cmd_magic],word CMD_MAGIC ; Store magic
2572 2572 00000C2A 64893E2200 <1> mov [fs:kern_cmd_offset],di ; Store pointer
2573 2573 <1>
2574 2574 00000C2F 8B0E[2003] <1> mov cx,[CmdLineLen]
2575 2575 00000C33 81F9FF00 <1> cmp cx,255
2576 2576 00000C37 7603 <1> jna .len_ok
2577 2577 00000C39 B9FF00 <1> mov cx,255 ; Protocol < 0x202 has 255 as hard limit
2578 2578 <1> .len_ok:
2579 2579 00000C3C 64F3A4 <1> fs rep movsb
2580 2580 00000C3F AA <1> stosb ; Final null, note AL == 0 already
2581 2581 <1>
2582 2582 00000C40 0FA0 <1> push fs
2583 2583 00000C42 07 <1> pop es
2584 2584 <1>
2585 2585 00000C43 F606[2603]01 <1> test byte [LoadFlags],LOAD_HIGH
2586 2586 00000C48 753F <1> jnz in_proper_place ; If high load, we're done
2587 2587 <1>
2588 2588 <1> ;
2589 2589 <1> ; Loading low; we can't assume it's safe to run in place.
2590 2590 <1> ;
2591 2591 <1> ; Copy real_mode stuff up to 90000h
2592 2592 <1> ;
2593 2593 00000C4A B80090 <1> mov ax,9000h
2594 2594 00000C4D 8EC0 <1> mov es,ax
2595 2595 00000C4F 8B0E[2203] <1> mov cx,[SetupSecs]
2596 2596 00000C53 41 <1> inc cx ; Setup + boot sector
2597 2597 00000C54 C1E107 <1> shl cx,7 ; Sectors -> dwords
2598 2598 00000C57 31F6 <1> xor si,si
2599 2599 00000C59 31FF <1> xor di,di
2600 2600 00000C5B 64F366A5 <1> fs rep movsd ; Copy setup + boot sector
2601 2601 <1> ;
2602 2602 <1> ; Some kernels in the 1.2 ballpark but pre-bzImage have more than 4
2603 2603 <1> ; setup sectors, but the boot protocol had not yet been defined. They
2604 2604 <1> ; rely on a signature to figure out if they need to copy stuff from
2605 2605 <1> ; the "protected mode" kernel area. Unfortunately, we used that area
2606 2606 <1> ; as a transfer buffer, so it's going to find the signature there.
2607 2607 <1> ; Hence, zero the low 32K beyond the setup area.
2608 2608 <1> ;
2609 2609 00000C5F 8B3E[2203] <1> mov di,[SetupSecs]
2610 2610 00000C63 47 <1> inc di ; Setup + boot sector
2611 2611 00000C64 B94000 <1> mov cx,32768/512 ; Sectors/32K
2612 2612 00000C67 29F9 <1> sub cx,di ; Remaining sectors
2613 2613 00000C69 C1E709 <1> shl di,9 ; Sectors -> bytes
2614 2614 00000C6C C1E107 <1> shl cx,7 ; Sectors -> dwords
2615 2615 00000C6F 6631C0 <1> xor eax,eax
2616 2616 00000C72 F366AB <1> rep stosd ; Clear region
2617 2617 <1> ;
2618 2618 <1> ; Copy the kernel down to the "low" location
2619 2619 <1> ;
2620 2620 00000C75 668B0E[1403] <1> mov ecx,[KernelSize]
2621 2621 00000C7A 66BE00001000 <1> mov esi,100000h
2622 2622 00000C80 66BF00000100 <1> mov edi,10000h
2623 2623 00000C86 E8(3000) <1> call bcopy
2624 2624 <1>
2625 2625 <1> ;
2626 2626 <1> ; Now everything is where it needs to be...
2627 2627 <1> ;
2628 2628 <1> ; When we get here, es points to the final segment, either
2629 2629 <1> ; 9000h or real_mode_seg
2630 2630 <1> ;
2631 2631 <1> in_proper_place:
2632 2632 <1>
2633 2633 <1> ;
2634 2634 <1> ; If the default root device is set to FLOPPY (0000h), change to
2635 2635 <1> ; /dev/fd0 (0200h)
2636 2636 <1> ;
2637 2637 00000C89 26833EFC0100 <1> cmp word [es:bs_rootdev],byte 0
2638 2638 00000C8F 7507 <1> jne root_not_floppy
2639 2639 00000C91 26C706FC010002 <1> mov word [es:bs_rootdev],0200h
2640 2640 <1> root_not_floppy:
2641 2641 <1>
2642 2642 <1> ;
2643 2643 <1> ; Copy the disk table to high memory, then re-initialize the floppy
2644 2644 <1> ; controller
2645 2645 <1> ;
2646 2646 <1> %if IS_SYSLINUX || IS_MDSLINUX
2647 2647 <1> lgs si,[cs:fdctab]
2648 2648 <1> mov di,linux_fdctab
2649 2649 <1> mov cx,6 ; 12 bytes
2650 2650 <1> gs rep movsw
2651 2651 <1> mov [cs:fdctab],word linux_fdctab ; Save new floppy tab pos
2652 2652 <1> mov [cs:fdctab+2],es
2653 2653 <1> %endif
2654 2654 <1> ;
2655 2655 <1> ; Linux wants the floppy motor shut off before starting the kernel,
2656 2656 <1> ; at least bootsect.S seems to imply so.
2657 2657 <1> ;
2658 2658 <1> kill_motor:
2659 2659 00000C98 31C0 <1> xor ax,ax
2660 2660 00000C9A 31D2 <1> xor dx,dx
2661 2661 00000C9C CD13 <1> int 13h
2662 2662 <1>
2663 2663 <1> ;
2664 2664 <1> ; If we're debugging, wait for a keypress so we can read any debug messages
2665 2665 <1> ;
2666 2666 <1> %ifdef debug
2667 2667 <1> xor ax,ax
2668 2668 <1> int 16h
2669 2669 <1> %endif
2670 2670 <1> ;
2671 2671 <1> ; Set up segment registers and the Linux real-mode stack
2672 2672 <1> ; Note: es == the real mode segment
2673 2673 <1> ;
2674 2674 00000C9E FA <1> cli
2675 2675 00000C9F 8CC3 <1> mov bx,es
2676 2676 00000CA1 8EDB <1> mov ds,bx
2677 2677 00000CA3 8EE3 <1> mov fs,bx
2678 2678 00000CA5 8EEB <1> mov gs,bx
2679 2679 00000CA7 8ED3 <1> mov ss,bx
2680 2680 00000CA9 BCF48F <1> mov sp,linux_stack
2681 2681 <1> ;
2682 2682 <1> ; We're done... now RUN THAT KERNEL!!!!
2683 2683 <1> ; Setup segment == real mode segment + 020h; we need to jump to offset
2684 2684 <1> ; zero in the real mode segment.
2685 2685 <1> ;
2686 2686 00000CAC 83C320 <1> add bx,020h
2687 2687 00000CAF 53 <1> push bx
2688 2688 00000CB0 6A00 <1> push word 0h
2689 2689 00000CB2 CB <1> retf
2690 2690 <1>
2691 2691 <1> ;
2692 2692 <1> ; Load an older kernel. Older kernels always have 4 setup sectors, can't have
2693 2693 <1> ; initrd, and are always loaded low.
2694 2694 <1> ;
2695 2695 <1> old_kernel:
2696 2696 00000CB3 833E[2403]00 <1> cmp word [InitRDPtr],0 ; Old kernel can't have initrd
2697 2697 00000CB8 7406 <1> je load_old_kernel
2698 2698 00000CBA BE[AA02] <1> mov si,err_oldkernel
2699 2699 00000CBD E95908 <1> jmp abort_load
2700 2700 <1> load_old_kernel:
2701 2701 00000CC0 C706[2203]0400 <1> mov word [SetupSecs],4 ; Always 4 setup sectors
2702 2702 00000CC6 C606[2603]00 <1> mov byte [LoadFlags],0 ; Always low
2703 2703 00000CCB E9A2FE <1> jmp read_kernel
2704 2704 <1>
2705 2705 <1> ;
2706 2706 <1> ; parse_load_initrd
2707 2707 <1> ;
2708 2708 <1> ; Parse an initrd= option and load the initrds. Note that we load
2709 2709 <1> ; from the high end of memory first, so we parse this option from
2710 2710 <1> ; left to right.
2711 2711 <1> ;
2712 2712 <1> parse_load_initrd:
2713 2713 00000CCE 06 <1> push es
2714 2714 00000CCF 1E <1> push ds
2715 2715 00000CD0 B80030 <1> mov ax,real_mode_seg
2716 2716 00000CD3 8ED8 <1> mov ds,ax
2717 2717 00000CD5 0E <1> push cs
2718 2718 00000CD6 07 <1> pop es ; DS == real_mode_seg, ES == CS
2719 2719 <1>
2720 2720 00000CD7 2E8B36[2403] <1> mov si,[cs:InitRDPtr]
2721 2721 <1> .find_end:
2722 2722 00000CDC AC <1> lodsb
2723 2723 00000CDD 3C20 <1> cmp al,' '
2724 2724 00000CDF 77FB <1> ja .find_end
2725 2725 <1> ; Now SI points to one character beyond the
2726 2726 <1> ; byte that ended this option.
2727 2727 <1>
2728 2728 <1> .get_chunk:
2729 2729 00000CE1 4E <1> dec si
2730 2730 <1>
2731 2731 <1> ; DS:SI points to a termination byte
2732 2732 <1>
2733 2733 00000CE2 31C0 <1> xor ax,ax
2734 2734 00000CE4 8604 <1> xchg al,[si] ; Zero-terminate
2735 2735 00000CE6 56 <1> push si ; Save ending byte address
2736 2736 00000CE7 50 <1> push ax ; Save ending byte
2737 2737 <1>
2738 2738 <1> .find_start:
2739 2739 00000CE8 4E <1> dec si
2740 2740 00000CE9 2E3B36[2403] <1> cmp si,[cs:InitRDPtr]
2741 2741 00000CEE 7406 <1> je .got_start
2742 2742 00000CF0 803C2C <1> cmp byte [si],','
2743 2743 00000CF3 75F3 <1> jne .find_start
2744 2744 <1>
2745 2745 <1> ; It's a comma byte
2746 2746 00000CF5 46 <1> inc si
2747 2747 <1>
2748 2748 <1> .got_start:
2749 2749 00000CF6 56 <1> push si
2750 2750 00000CF7 BF[0C1D] <1> mov di,InitRD ; Target buffer for mangled name
2751 2751 00000CFA E86509 <1> call mangle_name
2752 2752 00000CFD E80F00 <1> call loadinitrd
2753 2753 00000D00 5E <1> pop si
2754 2754 <1>
2755 2755 00000D01 58 <1> pop ax
2756 2756 00000D02 5F <1> pop di
2757 2757 00000D03 8805 <1> mov [di],al ; Restore ending byte
2758 2758 <1>
2759 2759 00000D05 2E3B36[2403] <1> cmp si,[cs:InitRDPtr]
2760 2760 00000D0A 77D5 <1> ja .get_chunk
2761 2761 <1>
2762 2762 00000D0C 1F <1> pop ds
2763 2763 00000D0D 07 <1> pop es
2764 2764 00000D0E C3 <1> ret
2765 2765 <1>
2766 2766 <1> ;
2767 2767 <1> ; Load RAM disk into high memory
2768 2768 <1> ;
2769 2769 <1> ; Input: InitRD - set to the mangled name of the initrd
2770 2770 <1> ;
2771 2771 <1> loadinitrd:
2772 2772 00000D0F 1E <1> push ds
2773 2773 00000D10 06 <1> push es
2774 2774 00000D11 8CC8 <1> mov ax,cs ; CS == DS == ES
2775 2775 00000D13 8ED8 <1> mov ds,ax
2776 2776 00000D15 8EC0 <1> mov es,ax
2777 2777 00000D17 BE[0C1D] <1> mov si,InitRD
2778 2778 00000D1A BF[0C1B] <1> mov di,InitRDCName
2779 2779 00000D1D E87909 <1> call unmangle_name ; Create human-readable name
2780 2780 00000D20 81EF[0C1B] <1> sub di,InitRDCName
2781 2781 00000D24 893E[0A19] <1> mov [InitRDCNameLen],di
2782 2782 00000D28 BF[0C1D] <1> mov di,InitRD
2783 2783 00000D2B E80008 <1> call searchdir ; Look for it in directory
2784 2784 00000D2E 747F <1> jz .notthere
2785 2785 <1>
2786 2786 00000D30 89D1 <1> mov cx,dx
2787 2787 00000D32 66C1E110 <1> shl ecx,16
2788 2788 00000D36 89C1 <1> mov cx,ax ; ECX <- ram disk length
2789 2789 <1>
2790 2790 00000D38 B80030 <1> mov ax,real_mode_seg
2791 2791 00000D3B 8EC0 <1> mov es,ax
2792 2792 <1>
2793 2793 00000D3D 6651 <1> push ecx ; Bytes to load
2794 2794 00000D3F 2666833E1C0200 <1> cmp dword [es:su_ramdisklen],0
2795 2795 00000D46 740B <1> je .nopadding ; Don't pad the last initrd
2796 2796 00000D48 6681C1FF0F0000 <1> add ecx,4095
2797 2797 00000D4F 81E100F0 <1> and cx,0F000h
2798 2798 <1> .nopadding:
2799 2799 00000D53 2666010E1C02 <1> add [es:su_ramdisklen],ecx
2800 2800 00000D59 668B16[7803] <1> mov edx,[HighMemSize] ; End of memory
2801 2801 00000D5E 664A <1> dec edx
2802 2802 00000D60 66A1[1003] <1> mov eax,[RamdiskMax] ; Highest address allowed by kernel
2803 2803 00000D64 6639C2 <1> cmp edx,eax
2804 2804 00000D67 7603 <1> jna .memsize_ok
2805 2805 00000D69 6689C2 <1> mov edx,eax ; Adjust to fit inside limit
2806 2806 <1> .memsize_ok:
2807 2807 00000D6C 6642 <1> inc edx
2808 2808 00000D6E 81E200F0 <1> and dx,0F000h ; Round down to 4K boundary
2809 2809 00000D72 6629CA <1> sub edx,ecx ; Subtract size of ramdisk
2810 2810 00000D75 81E200F0 <1> and dx,0F000h ; Round down to 4K boundary
2811 2811 00000D79 663B16[1C03] <1> cmp edx,[KernelEnd] ; Are we hitting the kernel image?
2812 2812 00000D7E 7241 <1> jb no_high_mem
2813 2813 <1>
2814 2814 00000D80 266689161802 <1> mov [es:su_ramdiskat],edx ; Load address
2815 2815 00000D86 668916[1003] <1> mov [RamdiskMax],edx ; Next initrd loaded here
2816 2816 <1>
2817 2817 00000D8B 6689D7 <1> mov edi,edx ; initrd load address
2818 2818 00000D8E 56 <1> push si
2819 2819 00000D8F BE[A203] <1> mov si,crlfloading_msg ; Write "Loading "
2820 2820 00000D92 E895F5 <1> call cwritestr
2821 2821 00000D95 BE[0C1B] <1> mov si,InitRDCName ; Write ramdisk name
2822 2822 00000D98 E88FF5 <1> call cwritestr
2823 2823 00000D9B BE[AD03] <1> mov si,dotdot_msg ; Write dots
2824 2824 00000D9E E889F5 <1> call cwritestr
2825 2825 00000DA1 5E <1> pop si
2826 2826 <1>
2827 2827 00000DA2 6658 <1> pop eax ; Bytes to load
2828 2828 00000DA4 BAFF0F <1> mov dx,0FFFh ; Pad to page
2829 2829 00000DA7 E83B10 <1> call load_high ; Load the file
2830 2830 <1>
2831 2831 00000DAA 07 <1> pop es
2832 2832 00000DAB 1F <1> pop ds
2833 2833 00000DAC E96EF5 <1> jmp crlf ; Print carriage return and return
2834 2834 <1>
2835 2835 <1> .notthere:
2836 2836 00000DAF BE[3E02] <1> mov si,err_noinitrd
2837 2837 00000DB2 E875F5 <1> call cwritestr
2838 2838 00000DB5 BE[0C1B] <1> mov si,InitRDCName
2839 2839 00000DB8 E86FF5 <1> call cwritestr
2840 2840 00000DBB BE[C905] <1> mov si,crlf_msg
2841 2841 00000DBE E95807 <1> jmp abort_load
2842 2842 <1>
2843 2843 <1> no_high_mem: ; Error routine
2844 2844 00000DC1 BE[5F02] <1> mov si,err_nohighmem
2845 2845 00000DC4 E95207 <1> jmp abort_load
2846 2846 <1>
2847 2847 00000DC7 C3 <1> ret
2848 2848 <1>
2849 2849 <1> section .data
2850 2850 0000000B 424F4F545F494D4147- <1> boot_image db 'BOOT_IMAGE='
2851 2851 00000014 453D <1>
2852 2852 <1> boot_image_len equ $-boot_image
2853 2853 <1>
2854 2854 <1> section .bss
2855 2855 0000030E <res 00000001>- <1> alignb 4
2856 2856 0000030E <rept> <1>
2857 2857 00000310 <res 00000004> <1> RamdiskMax resd 1 ; Highest address for ramdisk
2858 2858 00000314 <res 00000004> <1> KernelSize resd 1 ; Size of kernel in bytes
2859 2859 00000318 <res 00000004> <1> KernelSects resd 1 ; Size of kernel in sectors
2860 2860 0000031C <res 00000004> <1> KernelEnd resd 1 ; Ending address of the kernel image
2861 2861 00000320 <res 00000002> <1> CmdLineLen resw 1 ; Length of command line including null
2862 2862 00000322 <res 00000002> <1> SetupSecs resw 1 ; Number of setup sectors
2863 2863 00000324 <res 00000002> <1> InitRDPtr resw 1 ; Pointer to initrd= option in command line
2864 2864 00000326 <res 00000001> <1> LoadFlags resb 1 ; Loadflags from kernel
2865 2865
2866 2866 ;
2867 2867 ; COMBOOT-loading code
2868 2868 ;
2869 2869 %include "comboot.inc"
2870 2870 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
2871 2871 <1> ;; -----------------------------------------------------------------------
2872 2872 <1> ;;
2873 2873 <1> ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
2874 2874 <1> ;;
2875 2875 <1> ;; This program is free software; you can redistribute it and/or modify
2876 2876 <1> ;; it under the terms of the GNU General Public License as published by
2877 2877 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
2878 2878 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
2879 2879 <1> ;; (at your option) any later version; incorporated herein by reference.
2880 2880 <1> ;;
2881 2881 <1> ;; -----------------------------------------------------------------------
2882 2882 <1>
2883 2883 <1> ;;
2884 2884 <1> ;; comboot.inc
2885 2885 <1> ;;
2886 2886 <1> ;; Common code for running a COMBOOT image
2887 2887 <1> ;;
2888 2888 <1>
2889 2889 <1> section .text
2890 2890 <1>
2891 2891 <1> ; Parameter registers definition; this is the definition
2892 2892 <1> ; of the stack frame used by INT 21h and INT 22h.
2893 2893 <1> %define P_FLAGS word [bp+44]
2894 2894 <1> %define P_FLAGSL byte [bp+44]
2895 2895 <1> %define P_FLAGSH byte [bp+45]
2896 2896 <1> %define P_CS word [bp+42]
2897 2897 <1> %define P_IP word [bp+40]
2898 2898 <1> %define P_DS word [bp+38]
2899 2899 <1> %define P_ES word [bp+36]
2900 2900 <1> %define P_FS word [bp+34]
2901 2901 <1> %define P_GS word [bp+32]
2902 2902 <1> %define P_EAX dword [bp+28]
2903 2903 <1> %define P_AX word [bp+28]
2904 2904 <1> %define P_HAX word [bp+30]
2905 2905 <1> %define P_AL byte [bp+28]
2906 2906 <1> %define P_AH byte [bp+29]
2907 2907 <1> %define P_ECX dword [bp+24]
2908 2908 <1> %define P_CX word [bp+24]
2909 2909 <1> %define P_HCX word [bp+26]
2910 2910 <1> %define P_CL byte [bp+24]
2911 2911 <1> %define P_CH byte [bp+25]
2912 2912 <1> %define P_EDX dword [bp+20]
2913 2913 <1> %define P_DX word [bp+20]
2914 2914 <1> %define P_HDX word [bp+22]
2915 2915 <1> %define P_DL byte [bp+20]
2916 2916 <1> %define P_DH byte [bp+21]
2917 2917 <1> %define P_EBX dword [bp+16]
2918 2918 <1> %define P_BX word [bp+16]
2919 2919 <1> %define P_HBX word [bp+18]
2920 2920 <1> %define P_BL byte [bp+16]
2921 2921 <1> %define P_BH byte [bp+17]
2922 2922 <1> %define P_EBP dword [bp+8]
2923 2923 <1> %define P_BP word [bp+8]
2924 2924 <1> %define P_HBP word [bp+10]
2925 2925 <1> %define P_ESI dword [bp+4]
2926 2926 <1> %define P_SI word [bp+4]
2927 2927 <1> %define P_HSI word [bp+6]
2928 2928 <1> %define P_EDI dword [bp]
2929 2929 <1> %define P_DI word [bp]
2930 2930 <1> %define P_HDI word [bp+2]
2931 2931 <1>
2932 2932 <1> ; Looks like a COMBOOT image but too large
2933 2933 <1> comboot_too_large:
2934 2934 00000DC8 BE[FA02] <1> mov si,err_comlarge
2935 2935 00000DCB E85CF5 <1> call cwritestr
2936 2936 00000DCE E9EAF8 <1> jmp enter_command
2937 2937 <1>
2938 2938 <1> ;
2939 2939 <1> ; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
2940 2940 <1> ; except that it may, of course, not contain any DOS system calls. We
2941 2941 <1> ; do, however, allow the execution of INT 20h to return to SYSLINUX.
2942 2942 <1> ;
2943 2943 <1> is_comboot_image:
2944 2944 00000DD1 21D2 <1> and dx,dx
2945 2945 00000DD3 75F3 <1> jnz comboot_too_large
2946 2946 00000DD5 3D00FF <1> cmp ax,0ff00h ; Max size in bytes
2947 2947 00000DD8 73EE <1> jae comboot_too_large
2948 2948 <1>
2949 2949 00000DDA 56 <1> push si ; Save file handle
2950 2950 <1>
2951 2951 00000DDB E84305 <1> call make_plain_cmdline
2952 2952 <1>
2953 2953 00000DDE E86600 <1> call comboot_setup_api
2954 2954 <1>
2955 2955 00000DE1 B90030 <1> mov cx,comboot_seg
2956 2956 00000DE4 8EC1 <1> mov es,cx
2957 2957 <1>
2958 2958 00000DE6 31FF <1> xor di,di
2959 2959 00000DE8 B94000 <1> mov cx,64 ; 256 bytes (size of PSP)
2960 2960 00000DEB 6631C0 <1> xor eax,eax ; Clear PSP
2961 2961 00000DEE F366AB <1> rep stosd
2962 2962 <1>
2963 2963 00000DF1 26C7060000CD20 <1> mov word [es:0], 020CDh ; INT 20h instruction
2964 2964 <1> ; First non-free paragraph
2965 2965 <1> ; This is valid because comboot_seg == real_mode_seg
2966 2966 <1> ; == the highest segment used by all derivatives
2967 2967 00000DF8 CD12 <1> int 12h ; Get DOS memory size
2968 2968 00000DFA C1E006 <1> shl ax,6 ; Kilobytes -> paragraphs
2969 2969 00000DFD 26A30200 <1> mov word [es:02h],ax
2970 2970 <1>
2971 2971 <1> %ifndef DEPEND
2972 2972 <1> %if real_mode_seg != comboot_seg
2973 2973 <1> %error "This code assumes real_mode_seg == comboot_seg"
2974 2974 <1> %endif
2975 2975 <1> %endif
2976 2976 <1> ; Copy the command line from high memory
2977 2977 00000E01 BE0090 <1> mov si,cmd_line_here
2978 2978 00000E04 B97D00 <1> mov cx,125 ; Max cmdline len (minus space and CR)
2979 2979 00000E07 BF8100 <1> mov di,081h ; Offset in PSP for command line
2980 2980 00000E0A B020 <1> mov al,' ' ; DOS command lines begin with a space
2981 2981 00000E0C AA <1> stosb
2982 2982 <1>
2983 2983 00000E0D 26AC <1> .loop: es lodsb
2984 2984 00000E0F 20C0 <1> and al,al
2985 2985 00000E11 7403 <1> jz .done
2986 2986 00000E13 AA <1> stosb
2987 2987 00000E14 E2F7 <1> loop .loop
2988 2988 <1> .done:
2989 2989 <1>
2990 2990 00000E16 B00D <1> mov al,0Dh ; CR after last character
2991 2991 00000E18 AA <1> stosb
2992 2992 00000E19 89F8 <1> mov ax,di
2993 2993 00000E1B 2C82 <1> sub al,82h ; Include space but not CR
2994 2994 00000E1D 26A28000 <1> mov [es:80h],al ; Store command line length
2995 2995 <1>
2996 2996 <1> ; Now actually load the file...
2997 2997 00000E21 5E <1> pop si ; File handle
2998 2998 00000E22 BB0001 <1> mov bx,100h ; Load at <seg>:0100h
2999 2999 00000E25 B91F00 <1> mov cx,0FF00h >> SECTOR_SHIFT
3000 3000 <1> ; Absolute maximum # of sectors
3001 3001 00000E28 E87308 <1> call getfssec
3002 3002 <1>
3003 3003 <1> ; And invoke the program...
3004 3004 00000E2B 8926[0440] <1> mov [SavedSSSP],sp
3005 3005 00000E2F 8C16[0640] <1> mov [SavedSSSP+2],ss ; Save away SS:SP
3006 3006 <1>
3007 3007 00000E33 8CC0 <1> mov ax,es
3008 3008 00000E35 8ED8 <1> mov ds,ax
3009 3009 00000E37 8ED0 <1> mov ss,ax
3010 3010 00000E39 31E4 <1> xor sp,sp
3011 3011 00000E3B 6A00 <1> push word 0 ; Return to address 0 -> exit
3012 3012 <1>
3013 3013 00000E3D EA00010030 <1> jmp comboot_seg:100h ; Run it
3014 3014 <1>
3015 3015 <1> ; Proper return vector
3016 3016 00000E42 FA <1> comboot_return: cli ; Don't trust anyone
3017 3017 00000E43 31C0 <1> xor ax,ax
3018 3018 00000E45 EB55 <1> jmp comboot_exit
3019 3019 <1>
3020 3020 <1> ;
3021 3021 <1> ; Set up the COMBOOT API interrupt vectors. This is also used
3022 3022 <1> ; by the COM32 code.
3023 3023 <1> ;
3024 3024 <1> comboot_setup_api:
3025 3025 00000E47 BF8000 <1> mov di,4*0x20 ; DOS interrupt vectors
3026 3026 00000E4A 66B8[420E0000] <1> mov eax,comboot_return ; INT 20h = exit
3027 3027 00000E50 66AB <1> stosd
3028 3028 00000E52 B8[660E] <1> mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls
3029 3029 00000E55 66AB <1> stosd
3030 3030 00000E57 B8[4D0F] <1> mov ax,comboot_int22 ; INT 22h = proprietary syscalls
3031 3031 00000E5A 66AB <1> stosd
3032 3032 00000E5C B8[980E] <1> mov ax,comboot_bogus
3033 3033 00000E5F B91D00 <1> mov cx,29 ; All remaining DOS vectors
3034 3034 00000E62 F366AB <1> rep stosd
3035 3035 00000E65 C3 <1> ret
3036 3036 <1>
3037 3037 <1> ; INT 21h: generic DOS system call
3038 3038 00000E66 FA <1> comboot_int21: cli
3039 3039 00000E67 1E <1> push ds
3040 3040 00000E68 06 <1> push es
3041 3041 00000E69 0FA0 <1> push fs
3042 3042 00000E6B 0FA8 <1> push gs
3043 3043 00000E6D 6660 <1> pushad
3044 3044 00000E6F FC <1> cld
3045 3045 00000E70 8CCD <1> mov bp,cs
3046 3046 00000E72 8EDD <1> mov ds,bp
3047 3047 00000E74 8EC5 <1> mov es,bp
3048 3048 00000E76 89E5 <1> mov bp,sp ; Set up stack frame
3049 3049 <1>
3050 3050 00000E78 E85510 <1> call adjust_screen ; The COMBOOT program might have changed the screen
3051 3051 <1>
3052 3052 00000E7B B90A00 <1> mov cx,int21_count
3053 3053 00000E7E BE[1600] <1> mov si,int21_table
3054 3054 00000E81 AC <1> .again: lodsb
3055 3055 00000E82 3A461D <1> cmp al,P_AH
3056 3056 00000E85 AD <1> lodsw
3057 3057 00000E86 E0F9 <1> loopne .again
3058 3058 <1> ; The last function in the list is the
3059 3059 <1> ; "no such function" function
3060 3060 00000E88 F8 <1> clc
3061 3061 00000E89 FFD0 <1> call ax ; Call the invoked function
3062 3062 <1> comboot_resume:
3063 3063 00000E8B 0F92462C <1> setc P_FLAGSL ; Propagate CF->error
3064 3064 00000E8F 6661 <1> popad
3065 3065 00000E91 0FA9 <1> pop gs
3066 3066 00000E93 0FA1 <1> pop fs
3067 3067 00000E95 07 <1> pop es
3068 3068 00000E96 1F <1> pop ds
3069 3069 00000E97 CF <1> iret
3070 3070 <1>
3071 3071 <1> ; Attempted to execute non-21h DOS system call
3072 3072 00000E98 FA <1> comboot_bogus: cli ; Don't trust anyone
3073 3073 00000E99 B8[DC02] <1> mov ax,err_notdos
3074 3074 <1> ;
3075 3075 <1> ; Generic COMBOOT return to command line code
3076 3076 <1> ; AX -> message (if any)
3077 3077 <1> ; BX -> where to go next
3078 3078 <1> ;
3079 3079 <1> comboot_exit:
3080 3080 00000E9C BB[BB06] <1> mov bx,enter_command ; Normal return to command prompt
3081 3081 <1> comboot_exit_special:
3082 3082 00000E9F 31D2 <1> xor dx,dx
3083 3083 00000EA1 8EDA <1> mov ds,dx
3084 3084 00000EA3 8EC2 <1> mov es,dx
3085 3085 00000EA5 0FB226[0440] <1> lss sp,[SavedSSSP]
3086 3086 00000EAA FB <1> sti
3087 3087 00000EAB FC <1> cld
3088 3088 00000EAC E82110 <1> call adjust_screen ; The COMBOOT program might have changed the screen
3089 3089 00000EAF 21C0 <1> and ax,ax
3090 3090 00000EB1 740A <1> je .nomsg
3091 3091 00000EB3 BE[0C1A] <1> mov si,KernelCName
3092 3092 00000EB6 E871F4 <1> call cwritestr
3093 3093 00000EB9 96 <1> xchg si,ax
3094 3094 00000EBA E86DF4 <1> call cwritestr
3095 3095 00000EBD FFE3 <1> .nomsg: jmp bx
3096 3096 <1>
3097 3097 <1> ;
3098 3098 <1> ; INT 21h system calls
3099 3099 <1> ;
3100 3100 <1> comboot_getkey: ; 01 = get key with echo
3101 3101 00000EBF E8D511 <1> call vgashowcursor
3102 3102 00000EC2 E86500 <1> call comboot_getchar
3103 3103 00000EC5 E8D511 <1> call vgahidecursor
3104 3104 00000EC8 E86CF3 <1> call writechr
3105 3105 00000ECB F8 <1> clc
3106 3106 00000ECC C3 <1> ret
3107 3107 <1>
3108 3108 <1> comboot_writechr: ; 02 = writechr
3109 3109 00000ECD 8A4614 <1> mov al,P_DL
3110 3110 00000ED0 E864F3 <1> call writechr
3111 3111 00000ED3 F8 <1> clc
3112 3112 00000ED4 C3 <1> ret
3113 3113 <1>
3114 3114 <1> comboot_writeserial: ; 04 = write serial port
3115 3115 00000ED5 8A4614 <1> mov al,P_DL
3116 3116 00000ED8 E85C0B <1> call write_serial
3117 3117 00000EDB F8 <1> clc
3118 3118 00000EDC C3 <1> ret
3119 3119 <1>
3120 3120 <1> comboot_getkeynoecho: ; 08 = get key w/o echo
3121 3121 00000EDD E84A00 <1> call comboot_getchar
3122 3122 00000EE0 F8 <1> clc
3123 3123 00000EE1 C3 <1> ret
3124 3124 <1>
3125 3125 <1> comboot_writestr: ; 09 = write DOS string
3126 3126 00000EE2 8E4626 <1> mov es,P_DS
3127 3127 00000EE5 8B7614 <1> mov si,P_DX
3128 3128 00000EE8 26AC <1> .loop: es lodsb
3129 3129 00000EEA 3C24 <1> cmp al,'$' ; End string with $ - bizarre
3130 3130 00000EEC 7405 <1> je .done
3131 3131 00000EEE E846F3 <1> call writechr
3132 3132 00000EF1 EBF5 <1> jmp short .loop
3133 3133 00000EF3 F8 <1> .done: clc
3134 3134 00000EF4 C3 <1> ret
3135 3135 <1>
3136 3136 <1> comboot_checkkey: ; 0B = check keyboard status
3137 3137 00000EF5 803E[6300]00 <1> cmp byte [APIKeyFlag],00h
3138 3138 00000EFA 7503 <1> jnz .waiting
3139 3139 00000EFC E8760B <1> call pollchar
3140 3140 00000EFF 0F94C0 <1> .waiting: setz al
3141 3141 00000F02 FEC8 <1> dec al ; AL = 0FFh if present, 0 if not
3142 3142 00000F04 88461C <1> mov P_AL,al
3143 3143 00000F07 F8 <1> clc
3144 3144 00000F08 C3 <1> ret
3145 3145 <1>
3146 3146 <1> comboot_checkver: ; 30 = check DOS version
3147 3147 <1> ; We return 0 in all DOS-compatible version registers,
3148 3148 <1> ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
3149 3149 00000F09 66C7461C00005359 <1> mov P_EAX,'SY' << 16
3150 3150 00000F11 66C746100000534C <1> mov P_EBX,'SL' << 16
3151 3151 00000F19 66C746180000494E <1> mov P_ECX,'IN' << 16
3152 3152 00000F21 66C7461400005558 <1> mov P_EDX,'UX' << 16
3153 3153 00000F29 C3 <1> ret
3154 3154 <1>
3155 3155 <1> comboot_getchar:
3156 3156 00000F2A 803E[6300]00 <1> cmp byte [APIKeyFlag],00h
3157 3157 00000F2F 7513 <1> jne .queued
3158 3158 00000F31 E86B0B <1> call getchar ; If not queued get input
3159 3159 00000F34 20C0 <1> and al,al ; Function key? (CF <- 0)
3160 3160 00000F36 7508 <1> jnz .done
3161 3161 00000F38 8826[6200] <1> mov [APIKeyWait],ah ; High part of key
3162 3162 00000F3C FE06[6300] <1> inc byte [APIKeyFlag] ; Set flag
3163 3163 00000F40 88461C <1> .done: mov P_AL,al
3164 3164 00000F43 C3 <1> ret
3165 3165 00000F44 A0[6200] <1> .queued: mov al,[APIKeyWait]
3166 3166 00000F47 FE0E[6300] <1> dec byte [APIKeyFlag]
3167 3167 00000F4B EBF3 <1> jmp .done
3168 3168 <1>
3169 3169 <1> ;
3170 3170 <1> ; INT 22h - SYSLINUX-specific system calls
3171 3171 <1> ; System call number in ax
3172 3172 <1> ;
3173 3173 <1> comboot_int22:
3174 3174 00000F4D FA <1> cli
3175 3175 00000F4E 1E <1> push ds
3176 3176 00000F4F 06 <1> push es
3177 3177 00000F50 0FA0 <1> push fs
3178 3178 00000F52 0FA8 <1> push gs
3179 3179 00000F54 6660 <1> pushad
3180 3180 00000F56 FC <1> cld
3181 3181 00000F57 8CCD <1> mov bp,cs
3182 3182 00000F59 8EDD <1> mov ds,bp
3183 3183 00000F5B 8EC5 <1> mov es,bp
3184 3184 00000F5D 89E5 <1> mov bp,sp ; Set up stack frame
3185 3185 <1>
3186 3186 00000F5F E86E0F <1> call adjust_screen ; The COMBOOT program might have changed the screen
3187 3187 <1>
3188 3188 00000F62 83F817 <1> cmp ax,int22_count
3189 3189 00000F65 7202 <1> jb .ok
3190 3190 00000F67 31C0 <1> xor ax,ax ; Function 0 -> unimplemented
3191 3191 <1> .ok:
3192 3192 00000F69 93 <1> xchg ax,bx
3193 3193 00000F6A 01DB <1> add bx,bx ; CF <- 0
3194 3194 00000F6C FF97[3400] <1> call [bx+int22_table]
3195 3195 00000F70 E918FF <1> jmp comboot_resume ; On return
3196 3196 <1>
3197 3197 <1> ;
3198 3198 <1> ; INT 22h AX=0000h Unimplemented call
3199 3199 <1> ;
3200 3200 <1> comapi_err:
3201 3201 00000F73 F9 <1> stc
3202 3202 00000F74 C3 <1> ret
3203 3203 <1>
3204 3204 <1> ;
3205 3205 <1> ; INT 22h AX=0001h Get SYSLINUX version
3206 3206 <1> ;
3207 3207 <1> comapi_get_version:
3208 3208 <1> ; Number of API functions supported
3209 3209 00000F75 C7461C1700 <1> mov P_AX,int22_count
3210 3210 <1> ; SYSLINUX version
3211 3211 00000F7A C746180B03 <1> mov P_CX,(VER_MAJOR << 8)+VER_MINOR
3212 3212 <1> ; SYSLINUX derivative ID byte
3213 3213 00000F7F C746143300 <1> mov P_DX,my_id
3214 3214 <1> ; For future use
3215 3215 00000F84 8C4E10 <1> mov P_BX,cs ; cs == 0
3216 3216 <1>
3217 3217 00000F87 8C5E24 <1> mov P_ES,ds
3218 3218 <1> ; ES:SI -> version banner
3219 3219 00000F8A C74604[7C03] <1> mov P_SI,syslinux_banner
3220 3220 <1> ; ES:DI -> copyright string
3221 3221 00000F8F C74600[9803] <1> mov P_DI,copyright_str
3222 3222 <1>
3223 3223 <1> comapi_nop:
3224 3224 00000F94 F8 <1> clc
3225 3225 00000F95 C3 <1> ret
3226 3226 <1>
3227 3227 <1> ;
3228 3228 <1> ; INT 22h AX=0002h Write string
3229 3229 <1> ;
3230 3230 <1> ; Write null-terminated string in ES:BX
3231 3231 <1> ;
3232 3232 <1> comapi_writestr:
3233 3233 00000F96 8E5E24 <1> mov ds,P_ES
3234 3234 00000F99 8B7610 <1> mov si,P_BX
3235 3235 00000F9C E88BF3 <1> call writestr
3236 3236 00000F9F F8 <1> clc
3237 3237 00000FA0 C3 <1> ret
3238 3238 <1>
3239 3239 <1> ;
3240 3240 <1> ; INT 22h AX=0003h Run command
3241 3241 <1> ;
3242 3242 <1> ; Terminates the COMBOOT program and executes the command line in
3243 3243 <1> ; ES:BX as if it had been entered by the user.
3244 3244 <1> ;
3245 3245 <1> comapi_run:
3246 3246 00000FA1 8E5E24 <1> mov ds,P_ES
3247 3247 00000FA4 8B7610 <1> mov si,P_BX
3248 3248 00000FA7 BF[0000] <1> mov di,command_line
3249 3249 00000FAA E8F911 <1> call strcpy
3250 3250 00000FAD 31C0 <1> xor ax,ax
3251 3251 00000FAF BB[D707] <1> mov bx,load_kernel ; Run a new kernel
3252 3252 00000FB2 E9EAFE <1> jmp comboot_exit_special ; Terminate task, clean up
3253 3253 <1>
3254 3254 <1> ;
3255 3255 <1> ; INT 22h AX=0004h Run default command
3256 3256 <1> ;
3257 3257 <1> ; Terminates the COMBOOT program and executes the default command line
3258 3258 <1> ; as if a timeout had happened or the user pressed <Enter>.
3259 3259 <1> ;
3260 3260 <1> comapi_run_default:
3261 3261 00000FB5 BB[BD07] <1> mov bx,auto_boot
3262 3262 00000FB8 E9E4FE <1> jmp comboot_exit_special
3263 3263 <1>
3264 3264 <1> ;
3265 3265 <1> ; INT 22h AX=0005h Force text mode
3266 3266 <1> ;
3267 3267 <1> ; Puts the video in standard text mode
3268 3268 <1> ;
3269 3269 <1> comapi_textmode:
3270 3270 00000FBB E8B110 <1> call vgaclearmode
3271 3271 00000FBE F8 <1> clc
3272 3272 00000FBF C3 <1> ret
3273 3273 <1>
3274 3274 <1> ;
3275 3275 <1> ; INT 22h AX=0006h Open file
3276 3276 <1> ;
3277 3277 <1> comapi_open:
3278 3278 00000FC0 1E <1> push ds
3279 3279 00000FC1 8E5E24 <1> mov ds,P_ES
3280 3280 00000FC4 8B7604 <1> mov si,P_SI
3281 3281 00000FC7 BF[0C1D] <1> mov di,InitRD
3282 3282 00000FCA 57 <1> push di
3283 3283 00000FCB E89406 <1> call mangle_name
3284 3284 00000FCE 5F <1> pop di
3285 3285 00000FCF 1F <1> pop ds
3286 3286 00000FD0 E85B05 <1> call searchdir
3287 3287 00000FD3 749E <1> jz comapi_err
3288 3288 00000FD5 89461C <1> mov P_AX,ax
3289 3289 00000FD8 89561E <1> mov P_HAX,dx
3290 3290 00000FDB C746180008 <1> mov P_CX,SECTOR_SIZE
3291 3291 00000FE0 897604 <1> mov P_SI,si
3292 3292 00000FE3 F8 <1> clc
3293 3293 00000FE4 C3 <1> ret
3294 3294 <1>
3295 3295 <1> ;
3296 3296 <1> ; INT 22h AX=0007h Read file
3297 3297 <1> ;
3298 3298 <1> comapi_read:
3299 3299 00000FE5 8E4624 <1> mov es,P_ES
3300 3300 00000FE8 8B5E10 <1> mov bx,P_BX
3301 3301 00000FEB 8B7604 <1> mov si,P_SI
3302 3302 00000FEE 8B4E18 <1> mov cx,P_CX
3303 3303 00000FF1 E8AA06 <1> call getfssec
3304 3304 00000FF4 7302 <1> jnc .noteof
3305 3305 00000FF6 31F6 <1> xor si,si ; SI <- 0 on EOF, CF <- 0
3306 3306 00000FF8 897604 <1> .noteof: mov P_SI,si
3307 3307 00000FFB C3 <1> ret
3308 3308 <1>
3309 3309 <1> ;
3310 3310 <1> ; INT 22h AX=0008h Close file
3311 3311 <1> ;
3312 3312 <1> comapi_close:
3313 3313 <1> ; Do nothing for now. Eventually implement
3314 3314 <1> ; an internal API for this.
3315 3315 00000FFC F8 <1> clc
3316 3316 00000FFD C3 <1> ret
3317 3317 <1>
3318 3318 <1> ;
3319 3319 <1> ; INT 22h AX=0009h Call PXE stack
3320 3320 <1> ;
3321 3321 <1> %if IS_PXELINUX
3322 3322 <1> comapi_pxecall:
3323 3323 <1> mov bx,P_BX
3324 3324 <1> mov es,P_ES
3325 3325 <1> mov di,P_DI
3326 3326 <1> call pxenv
3327 3327 <1> mov P_AX,ax
3328 3328 <1> clc
3329 3329 <1> ret
3330 3330 <1> %else
3331 3331 <1> comapi_pxecall equ comapi_err ; Not available
3332 3332 <1> %endif
3333 3333 <1>
3334 3334 <1> ;
3335 3335 <1> ; INT 22h AX=000Ah Get Derivative-Specific Info
3336 3336 <1> ;
3337 3337 <1> comapi_derinfo:
3338 3338 00000FFE C6461C33 <1> mov P_AL,my_id
3339 3339 <1> %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
3340 3340 <1> mov al,[DriveNumber]
3341 3341 <1> mov P_DL,al
3342 3342 <1> mov P_ES,cs
3343 3343 <1> mov P_BX,PartInfo
3344 3344 <1> %elif IS_PXELINUX
3345 3345 <1> mov ax,[APIVer]
3346 3346 <1> mov P_DX,ax
3347 3347 <1> mov ax,[StrucPtr]
3348 3348 <1> mov P_BX,ax
3349 3349 <1> mov ax,[StrucPtr+2]
3350 3350 <1> mov P_ES,ax
3351 3351 <1> mov ax,[InitStack]
3352 3352 <1> mov P_SI,ax
3353 3353 <1> mov ax,[InitStack+2]
3354 3354 <1> mov P_FS,ax
3355 3355 <1> %elif IS_ISOLINUX
3356 3356 00001002 A0[6900] <1> mov al,[DriveNo]
3357 3357 00001005 884614 <1> mov P_DL,al
3358 3358 00001008 8C4E24 <1> mov P_ES,cs
3359 3359 0000100B C74610[7000] <1> mov P_BX,spec_packet
3360 3360 <1> %endif
3361 3361 00001010 F8 <1> clc
3362 3362 00001011 C3 <1> ret
3363 3363 <1>
3364 3364 <1> ;
3365 3365 <1> ; INT 22h AX=000Bh Get Serial Console Configuration
3366 3366 <1> ;
3367 3367 <1> comapi_serialcfg:
3368 3368 00001012 A1[B400] <1> mov ax,[SerialPort]
3369 3369 00001015 894614 <1> mov P_DX,ax
3370 3370 00001018 A1[5203] <1> mov ax,[BaudDivisor]
3371 3371 0000101B 894618 <1> mov P_CX,ax
3372 3372 0000101E A1[5403] <1> mov ax,[FlowControl]
3373 3373 00001021 08E0 <1> or al,ah
3374 3374 00001023 8A26[5603] <1> mov ah,[FlowIgnore]
3375 3375 00001027 C0EC04 <1> shr ah,4
3376 3376 0000102A F606[7200]01 <1> test byte [DisplayCon],01h
3377 3377 0000102F 7503 <1> jnz .normalconsole
3378 3378 00001031 80CC80 <1> or ah,80h
3379 3379 <1> .normalconsole:
3380 3380 00001034 894610 <1> mov P_BX,ax
3381 3381 00001037 F8 <1> clc
3382 3382 00001038 C3 <1> ret
3383 3383 <1>
3384 3384 <1> ;
3385 3385 <1> ; INT 22h AX=000Ch Perform final cleanup
3386 3386 <1> ;
3387 3387 <1> comapi_cleanup:
3388 3388 <1> %if IS_PXELINUX
3389 3389 <1> ; Unload PXE if requested
3390 3390 <1> test dl,3
3391 3391 <1> setnz [KeepPXE]
3392 3392 <1> sub bp,sp ; unload_pxe may move the stack around
3393 3393 <1> call unload_pxe
3394 3394 <1> add bp,sp ; restore frame pointer...
3395 3395 <1> %elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
3396 3396 <1> ; Restore original FDC table
3397 3397 <1> mov eax,[OrigFDCTabPtr]
3398 3398 <1> mov [fdctab],eax
3399 3399 <1> %endif
3400 3400 <1> ; Reset the floppy disk subsystem
3401 3401 00001039 31C0 <1> xor ax,ax
3402 3402 0000103B 31D2 <1> xor dx,dx
3403 3403 0000103D CD13 <1> int 13h
3404 3404 0000103F F8 <1> clc
3405 3405 00001040 C3 <1> ret
3406 3406 <1>
3407 3407 <1> ;
3408 3408 <1> ; INT 22h AX=000Dh Clean up then replace bootstrap
3409 3409 <1> ;
3410 3410 <1> comapi_chainboot:
3411 3411 00001041 E8F5FF <1> call comapi_cleanup
3412 3412 00001044 668B4600 <1> mov eax,P_EDI
3413 3413 00001048 66A3[0400] <1> mov [trackbuf+4],eax ; Copy from
3414 3414 0000104C 668B4618 <1> mov eax,P_ECX
3415 3415 00001050 66A3[0800] <1> mov [trackbuf+8],eax ; Total bytes
3416 3416 00001054 66B8007C0000 <1> mov eax,7C00h
3417 3417 0000105A 66A3[0000] <1> mov [trackbuf],eax ; Copy to
3418 3418 0000105E 66A3[0040] <1> mov [EntryPoint],eax ; CS:IP entry point
3419 3419 00001062 668B7604 <1> mov esi,P_ESI
3420 3420 00001066 668B5610 <1> mov edx,P_EBX
3421 3421 0000106A 8B5E26 <1> mov bx,P_DS
3422 3422 0000106D E90A03 <1> jmp replace_bootstrap_one
3423 3423 <1>
3424 3424 <1>
3425 3425 <1> ;
3426 3426 <1> ; INT 22h AX=000Eh Get configuration file name
3427 3427 <1> ;
3428 3428 <1> comapi_configfile:
3429 3429 00001070 8C4E24 <1> mov P_ES,cs
3430 3430 00001073 C74610[DB03] <1> mov P_BX,ConfigName
3431 3431 00001078 F8 <1> clc
3432 3432 00001079 C3 <1> ret
3433 3433 <1>
3434 3434 <1> ;
3435 3435 <1> ; INT 22h AX=000Fh Get IPAPPEND strings
3436 3436 <1> ;
3437 3437 <1> %if IS_PXELINUX
3438 3438 <1> comapi_ipappend:
3439 3439 <1> mov P_ES,cs
3440 3440 <1> mov P_CX,numIPAppends
3441 3441 <1> mov P_BX,IPAppends
3442 3442 <1> clc
3443 3443 <1> ret
3444 3444 <1>
3445 3445 <1> section .data
3446 3446 <1> alignb 2, db 0
3447 3447 <1> IPAppends dw IPOption
3448 3448 <1> dw BOOTIFStr
3449 3449 <1> numIPAppends equ ($-IPAppends)/2
3450 3450 <1>
3451 3451 <1> %else
3452 3452 <1> comapi_ipappend equ comapi_err
3453 3453 <1> %endif
3454 3454 <1>
3455 3455 <1> section .text
3456 3456 <1>
3457 3457 <1> ;
3458 3458 <1> ; INT 22h AX=0010h Resolve hostname
3459 3459 <1> ;
3460 3460 <1> %if IS_PXELINUX
3461 3461 <1> comapi_dnsresolv:
3462 3462 <1> mov ds,P_ES
3463 3463 <1> mov si,P_BX
3464 3464 <1> call dns_resolv
3465 3465 <1> mov P_EAX,eax
3466 3466 <1> ret
3467 3467 <1> %else
3468 3468 <1> comapi_dnsresolv equ comapi_err
3469 3469 <1> %endif
3470 3470 <1>
3471 3471 <1> section .text
3472 3472 <1>
3473 3473 <1> ;
3474 3474 <1> ; INT 22h AX=0011h Maximum number of shuffle descriptors
3475 3475 <1> ;
3476 3476 <1> comapi_maxshuffle:
3477 3477 0000107A C746185505 <1> mov P_CX,(2*trackbufsize)/12
3478 3478 0000107F C3 <1> ret
3479 3479 <1>
3480 3480 <1> ;
3481 3481 <1> ; INT 22h AX=0012h Cleanup, shuffle and boot
3482 3482 <1> ;
3483 3483 <1> comapi_shuffle:
3484 3484 00001080 E8B6FF <1> call comapi_cleanup
3485 3485 00001083 8B4E18 <1> mov cx,P_CX
3486 3486 00001086 81F95505 <1> cmp cx,(2*trackbufsize)/12
3487 3487 0000108A 7729 <1> ja .error
3488 3488 <1>
3489 3489 0000108C 51 <1> push cx ; On stack: descriptor count
3490 3490 <1>
3491 3491 0000108D 678D0C49 <1> lea cx,[ecx+ecx*2] ; CX *= 3
3492 3492 <1>
3493 3493 00001091 8E6624 <1> mov fs,P_ES
3494 3494 00001094 8B7600 <1> mov si,P_DI
3495 3495 00001097 BF[0000] <1> mov di,trackbuf
3496 3496 0000109A 57 <1> push di ; On stack: descriptor list address
3497 3497 0000109B 64F366A5 <1> fs rep movsd ; Copy the list
3498 3498 <1>
3499 3499 0000109F 668B4608 <1> mov eax,P_EBP
3500 3500 000010A3 66A3[0040] <1> mov [EntryPoint],eax ; CS:IP entry point
3501 3501 000010A7 668B7604 <1> mov esi,P_ESI
3502 3502 000010AB 668B5610 <1> mov edx,P_EBX
3503 3503 000010AF 8B5E26 <1> mov bx,P_DS
3504 3504 000010B2 E9CA02 <1> jmp replace_bootstrap
3505 3505 <1> .error:
3506 3506 000010B5 F9 <1> stc
3507 3507 000010B6 C3 <1> ret
3508 3508 <1>
3509 3509 <1> ;
3510 3510 <1> ; INT 22h AX=0013h Idle call
3511 3511 <1> ;
3512 3512 <1> ;
3513 3513 <1> ; *** FIX THIS ***
3514 3514 <1> ; The idle call seems to have detrimental effects on some machines when
3515 3515 <1> ; called from a COM32 context (WHY?) -- disable it for now.
3516 3516 <1> ;
3517 3517 <1> %if 0 ; def HAVE_IDLE
3518 3518 <1>
3519 3519 <1> comapi_idle:
3520 3520 <1> DO_IDLE
3521 3521 <1> clc
3522 3522 <1> ret
3523 3523 <1>
3524 3524 <1> %else
3525 3525 <1>
3526 3526 <1> comapi_idle equ comapi_err
3527 3527 <1>
3528 3528 <1> %endif
3529 3529 <1>
3530 3530 <1> ;
3531 3531 <1> ; INT 22h AX=0014h Local boot
3532 3532 <1> ;
3533 3533 <1> %if IS_PXELINUX || IS_ISOLINUX
3534 3534 <1> comapi_localboot:
3535 3535 000010B7 8B4614 <1> mov ax,P_DX
3536 3536 000010BA E9F403 <1> jmp local_boot
3537 3537 <1> %else
3538 3538 <1> comapi_localboot equ comapi_err
3539 3539 <1> %endif
3540 3540 <1>
3541 3541 <1> ;
3542 3542 <1> ; INT 22h AX=0015h Feature flags
3543 3543 <1> ;
3544 3544 <1> comapi_features:
3545 3545 000010BD 8C4E24 <1> mov P_ES,cs
3546 3546 000010C0 C74610[6500] <1> mov P_BX,feature_flags
3547 3547 000010C5 C746180100 <1> mov P_CX,feature_flags_len
3548 3548 000010CA F8 <1> clc
3549 3549 000010CB C3 <1> ret
3550 3550 <1>
3551 3551 <1> ;
3552 3552 <1> ; INT 22h AX=0016h Run kernel image
3553 3553 <1> ;
3554 3554 <1> comapi_runkernel:
3555 3555 000010CC 1E <1> push ds
3556 3556 000010CD 8E5E26 <1> mov ds,P_DS
3557 3557 000010D0 8B7604 <1> mov si,P_SI
3558 3558 000010D3 BF[0C19] <1> mov di,KernelName
3559 3559 000010D6 57 <1> push di
3560 3560 000010D7 E88805 <1> call mangle_name
3561 3561 000010DA 5F <1> pop di
3562 3562 000010DB 1F <1> pop ds
3563 3563 000010DC E84F04 <1> call searchdir
3564 3564 000010DF 0F8490FE <1> jz comapi_err
3565 3565 <1>
3566 3566 <1> ; The kernel image was found, so we can load it...
3567 3567 000010E3 8936[FC02] <1> mov [Kernel_SI],si
3568 3568 000010E7 A3[F802] <1> mov [Kernel_EAX],ax
3569 3569 000010EA 8916[FA02] <1> mov [Kernel_EAX+2],dx
3570 3570 <1>
3571 3571 <1> ; It's not just possible, but quite likely, that ES:BX
3572 3572 <1> ; points into real_mode_seg, so we need to exercise some
3573 3573 <1> ; special care here... use xfer_buf_seg as an intermediary
3574 3574 000010EE 1E <1> push ds
3575 3575 000010EF 06 <1> push es
3576 3576 000010F0 B80010 <1> mov ax,xfer_buf_seg
3577 3577 000010F3 8E5E24 <1> mov ds,P_ES
3578 3578 000010F6 8B7610 <1> mov si,P_BX
3579 3579 000010F9 8EC0 <1> mov es,ax
3580 3580 000010FB 31FF <1> xor di,di
3581 3581 000010FD E8A610 <1> call strcpy
3582 3582 00001100 07 <1> pop es
3583 3583 00001101 1F <1> pop ds
3584 3584 <1>
3585 3585 <1> %if IS_PXELINUX
3586 3586 <1> mov al,P_CL
3587 3587 <1> mov [IPAppend],al
3588 3588 <1> %endif
3589 3589 <1>
3590 3590 00001102 31C0 <1> xor ax,ax
3591 3591 00001104 BB[0A11] <1> mov bx,.finish
3592 3592 00001107 E995FD <1> jmp comboot_exit_special
3593 3593 <1>
3594 3594 <1> .finish:
3595 3595 <1> ; Copy the command line into its proper place
3596 3596 0000110A 1E <1> push ds
3597 3597 0000110B 06 <1> push es
3598 3598 0000110C B80010 <1> mov ax,xfer_buf_seg
3599 3599 0000110F BA0030 <1> mov dx,real_mode_seg
3600 3600 00001112 8ED8 <1> mov ds,ax
3601 3601 00001114 8EC2 <1> mov es,dx
3602 3602 00001116 31F6 <1> xor si,si
3603 3603 00001118 BF0090 <1> mov di,cmd_line_here
3604 3604 0000111B E88810 <1> call strcpy
3605 3605 0000111E 26C645FF20 <1> mov byte [es:di-1],' ' ; Simulate APPEND
3606 3606 00001123 07 <1> pop es
3607 3607 00001124 1F <1> pop ds
3608 3608 00001125 893E[AA00] <1> mov [CmdLinePtr],di
3609 3609 00001129 C706[0A03][6400] <1> mov word [CmdOptPtr],zero_string
3610 3610 0000112F E913F8 <1> jmp kernel_good_saved
3611 3611 <1>
3612 3612 <1> section .data
3613 3613 <1>
3614 3614 <1> %macro int21 2
3615 3615 <1> db %1
3616 3616 <1> dw %2
3617 3617 <1> %endmacro
3618 3618 <1>
3619 3619 <1> int21_table:
3620 3620 <1> int21 00h, comboot_return
3621 3621 00000016 00 <2> db %1
3622 3622 00000017 [420E] <2> dw %2
3623 3623 <1> int21 01h, comboot_getkey
3624 3624 00000019 01 <2> db %1
3625 3625 0000001A [BF0E] <2> dw %2
3626 3626 <1> int21 02h, comboot_writechr
3627 3627 0000001C 02 <2> db %1
3628 3628 0000001D [CD0E] <2> dw %2
3629 3629 <1> int21 04h, comboot_writeserial
3630 3630 0000001F 04 <2> db %1
3631 3631 00000020 [D50E] <2> dw %2
3632 3632 <1> int21 08h, comboot_getkeynoecho
3633 3633 00000022 08 <2> db %1
3634 3634 00000023 [DD0E] <2> dw %2
3635 3635 <1> int21 09h, comboot_writestr
3636 3636 00000025 09 <2> db %1
3637 3637 00000026 [E20E] <2> dw %2
3638 3638 <1> int21 0Bh, comboot_checkkey
3639 3639 00000028 0B <2> db %1
3640 3640 00000029 [F50E] <2> dw %2
3641 3641 <1> int21 30h, comboot_checkver
3642 3642 0000002B 30 <2> db %1
3643 3643 0000002C [090F] <2> dw %2
3644 3644 <1> int21 4Ch, comboot_return
3645 3645 0000002E 4C <2> db %1
3646 3646 0000002F [420E] <2> dw %2
3647 3647 <1> int21 -1, comboot_bogus
3648 3648 00000031 FF <2> db %1
3649 3649 00000032 [980E] <2> dw %2
3650 3650 <1> int21_count equ ($-int21_table)/3
3651 3651 <1>
3652 3652 <1> align 2, db 0
3653 3653 <1> int22_table:
3654 3654 00000034 [730F] <1> dw comapi_err ; 0000 unimplemented syscall
3655 3655 00000036 [750F] <1> dw comapi_get_version ; 0001 get SYSLINUX version
3656 3656 00000038 [960F] <1> dw comapi_writestr ; 0002 write string
3657 3657 0000003A [A10F] <1> dw comapi_run ; 0003 run specified command
3658 3658 0000003C [B50F] <1> dw comapi_run_default ; 0004 run default command
3659 3659 0000003E [BB0F] <1> dw comapi_textmode ; 0005 force text mode
3660 3660 00000040 [C00F] <1> dw comapi_open ; 0006 open file
3661 3661 00000042 [E50F] <1> dw comapi_read ; 0007 read file
3662 3662 00000044 [FC0F] <1> dw comapi_close ; 0008 close file
3663 3663 00000046 [730F] <1> dw comapi_pxecall ; 0009 call PXE stack
3664 3664 00000048 [FE0F] <1> dw comapi_derinfo ; 000A derivative-specific info
3665 3665 0000004A [1210] <1> dw comapi_serialcfg ; 000B get serial port config
3666 3666 0000004C [3910] <1> dw comapi_cleanup ; 000C perform final cleanup
3667 3667 0000004E [4110] <1> dw comapi_chainboot ; 000D clean up then bootstrap
3668 3668 00000050 [7010] <1> dw comapi_configfile ; 000E get name of config file
3669 3669 00000052 [730F] <1> dw comapi_ipappend ; 000F get ipappend strings
3670 3670 00000054 [730F] <1> dw comapi_dnsresolv ; 0010 resolve hostname
3671 3671 00000056 [7A10] <1> dw comapi_maxshuffle ; 0011 maximum shuffle descriptors
3672 3672 00000058 [8010] <1> dw comapi_shuffle ; 0012 cleanup, shuffle and boot
3673 3673 0000005A [730F] <1> dw comapi_idle ; 0013 idle call
3674 3674 0000005C [B710] <1> dw comapi_localboot ; 0014 local boot
3675 3675 0000005E [BD10] <1> dw comapi_features ; 0015 feature flags
3676 3676 00000060 [CC10] <1> dw comapi_runkernel ; 0016 run kernel image
3677 3677 <1> int22_count equ ($-int22_table)/2
3678 3678 <1>
3679 3679 00000062 00 <1> APIKeyWait db 0
3680 3680 00000063 00 <1> APIKeyFlag db 0
3681 3681 <1>
3682 3682 00000064 00 <1> zero_string db 0 ; Empty, null-terminated string
3683 3683 <1>
3684 3684 <1> ;
3685 3685 <1> ; This is the feature flag array for INT 22h AX=0015h
3686 3686 <1> feature_flags:
3687 3687 <1> %if IS_PXELINUX
3688 3688 <1> db 1 ; Have local boot, idle not noop
3689 3689 <1> %elif IS_ISOLINUX
3690 3690 00000065 03 <1> db 3 ; Have local boot, idle is noop
3691 3691 <1> %else
3692 3692 <1> db 2 ; No local boot, idle is noop
3693 3693 <1> %endif
3694 3694 <1> feature_flags_len equ ($-feature_flags)
3695 3695 %include "com32.inc"
3696 3696 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
3697 3697 <1> ;; -----------------------------------------------------------------------
3698 3698 <1> ;;
3699 3699 <1> ;; Copyright 1994-2003 H. Peter Anvin - All Rights Reserved
3700 3700 <1> ;;
3701 3701 <1> ;; This program is free software; you can redistribute it and/or modify
3702 3702 <1> ;; it under the terms of the GNU General Public License as published by
3703 3703 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
3704 3704 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
3705 3705 <1> ;; (at your option) any later version; incorporated herein by reference.
3706 3706 <1> ;;
3707 3707 <1> ;; -----------------------------------------------------------------------
3708 3708 <1>
3709 3709 <1> ;;
3710 3710 <1> ;; com32.inc
3711 3711 <1> ;;
3712 3712 <1> ;; Common code for running a COM32 image
3713 3713 <1> ;;
3714 3714 <1>
3715 3715 <1> ;
3716 3716 <1> ; Load a COM32 image. A COM32 image is the 32-bit analogue to a DOS
3717 3717 <1> ; .com file. A COM32 image is loaded at address 0x101000, with %esp
3718 3718 <1> ; set to the high end of usable memory.
3719 3719 <1> ;
3720 3720 <1> ; A COM32 image should begin with the magic bytes:
3721 3721 <1> ; B8 FF 4C CD 21, which is "mov eax,0x21cd4cff" in 32-bit mode and
3722 3722 <1> ; "mov ax,0x4cff; int 0x21" in 16-bit mode. This will abort the
3723 3723 <1> ; program with an error if run in 16-bit mode.
3724 3724 <1> ;
3725 3725 <1> pm_idt: equ 0x100000
3726 3726 <1> pm_entry: equ 0x101000
3727 3727 <1>
3728 3728 <1> bits 16
3729 3729 <1> section .data
3730 3730 <1> align 2, db 0
3731 3731 <1> com32_pmidt:
3732 3732 00000066 0008 <1> dw 8*256 ; Limit
3733 3733 00000068 00001000 <1> dd pm_idt ; Address
3734 3734 <1>
3735 3735 <1> com32_rmidt:
3736 3736 0000006C FFFF <1> dw 0ffffh ; Limit
3737 3737 0000006E 00000000 <1> dd 0 ; Address
3738 3738 <1>
3739 3739 <1> section .text
3740 3740 <1> is_com32_image:
3741 3741 00001132 56 <1> push si ; Save file handle
3742 3742 00001133 52 <1> push dx ; File length held in DX:AX
3743 3743 00001134 50 <1> push ax
3744 3744 <1>
3745 3745 00001135 E8E901 <1> call make_plain_cmdline
3746 3746 <1> ; Copy the command line into the low cmdline buffer
3747 3747 00001138 B80030 <1> mov ax,real_mode_seg
3748 3748 0000113B 8EE0 <1> mov fs,ax
3749 3749 0000113D BE0090 <1> mov si,cmd_line_here
3750 3750 00001140 BF[0000] <1> mov di,command_line
3751 3751 00001143 8B0E[AA00] <1> mov cx,[CmdLinePtr]
3752 3752 00001147 41 <1> inc cx ; Include final null
3753 3753 00001148 29F1 <1> sub cx,si
3754 3754 0000114A 64F3A4 <1> fs rep movsb
3755 3755 <1>
3756 3756 0000114D E8650F <1> call highmemsize ; We need the high memory size...
3757 3757 00001150 E8F4FC <1> call comboot_setup_api ; Set up the COMBOOT-style API
3758 3758 <1>
3759 3759 00001153 66BF00101000 <1> mov edi,pm_entry ; Load address
3760 3760 00001159 6658 <1> pop eax ; File length
3761 3761 0000115B 5E <1> pop si ; File handle
3762 3762 0000115C 31D2 <1> xor dx,dx ; No padding
3763 3763 0000115E E8840C <1> call load_high
3764 3764 00001161 E8B9F1 <1> call crlf
3765 3765 <1>
3766 3766 <1> com32_start:
3767 3767 00001164 66BB[AD110000] <1> mov ebx,com32_call_start ; Where to go in PM
3768 3768 <1>
3769 3769 <1> com32_enter_pm:
3770 3770 0000116A FA <1> cli
3771 3771 0000116B 8CC8 <1> mov ax,cs
3772 3772 0000116D 8ED8 <1> mov ds,ax
3773 3773 0000116F 8926[0440] <1> mov [SavedSSSP],sp
3774 3774 00001173 8C16[0640] <1> mov [SavedSSSP+2],ss
3775 3775 00001177 FC <1> cld
3776 3776 00001178 E8(4B01) <1> call a20_test
3777 3777 0000117B 7503 <1> jnz .a20ok
3778 3778 0000117D E8(CC00) <1> call enable_a20
3779 3779 <1>
3780 3780 <1> .a20ok:
3781 3781 00001180 0F0116[0000] <1> lgdt [bcopy_gdt] ; We can use the same GDT just fine
3782 3782 00001185 0F011E[6600] <1> lidt [com32_pmidt] ; Set up the IDT
3783 3783 0000118A 0F20C0 <1> mov eax,cr0
3784 3784 0000118D 0C01 <1> or al,1
3785 3785 0000118F 0F22C0 <1> mov cr0,eax ; Enter protected mode
3786 3786 00001192 EA[9711]2000 <1> jmp 20h:.in_pm
3787 3787 <1>
3788 3788 <1> bits 32
3789 3789 <1> .in_pm:
3790 3790 00001197 31C0 <1> xor eax,eax ; Available for future use...
3791 3791 00001199 8EE0 <1> mov fs,eax
3792 3792 0000119B 8EE8 <1> mov gs,eax
3793 3793 <1>
3794 3794 0000119D B028 <1> mov al,28h ; Set up data segments
3795 3795 0000119F 8EC0 <1> mov es,eax
3796 3796 000011A1 8ED8 <1> mov ds,eax
3797 3797 000011A3 8ED0 <1> mov ss,eax
3798 3798 <1>
3799 3799 000011A5 8B25[28030000] <1> mov esp,[PMESP] ; Load protmode %esp if available
3800 3800 000011AB FFE3 <1> jmp ebx ; Go to where we need to go
3801 3801 <1>
3802 3802 <1> ;
3803 3803 <1> ; This is invoked right before the actually starting the COM32
3804 3804 <1> ; progam, in 32-bit mode...
3805 3805 <1> ;
3806 3806 <1> com32_call_start:
3807 3807 <1> ;
3808 3808 <1> ; Point the stack to the end of high memory
3809 3809 <1> ;
3810 3810 000011AD 678B26[7803] <1> mov esp,[word HighMemSize]
3811 3811 <1>
3812 3812 <1> ;
3813 3813 <1> ; Set up the protmode IDT and the interrupt jump buffers
3814 3814 <1> ; We set these up in the system area at 0x100000,
3815 3815 <1> ; but we could also put them beyond the stack.
3816 3816 <1> ;
3817 3817 000011B2 BF00001000 <1> mov edi,pm_idt
3818 3818 <1>
3819 3819 <1> ; Form an interrupt gate descriptor
3820 3820 000011B7 B800082000 <1> mov eax,0x00200000+((pm_idt+8*256)&0x0000ffff)
3821 3821 000011BC BB00EE1000 <1> mov ebx,0x0000ee00+((pm_idt+8*256)&0xffff0000)
3822 3822 000011C1 31C9 <1> xor ecx,ecx
3823 3823 000011C3 FEC5 <1> inc ch ; ecx <- 256
3824 3824 <1>
3825 3825 000011C5 51 <1> push ecx
3826 3826 <1> .make_idt:
3827 3827 000011C6 AB <1> stosd
3828 3828 000011C7 83C008 <1> add eax,8
3829 3829 000011CA 93 <1> xchg eax,ebx
3830 3830 000011CB AB <1> stosd
3831 3831 000011CC 93 <1> xchg eax,ebx
3832 3832 000011CD E2F7 <1> loop .make_idt
3833 3833 <1>
3834 3834 000011CF 59 <1> pop ecx
3835 3835 <1>
3836 3836 <1> ; Each entry in the interrupt jump buffer contains
3837 3837 <1> ; the following instructions:
3838 3838 <1> ;
3839 3839 <1> ; 00000000 60 pushad
3840 3840 <1> ; 00000001 B0xx mov al,<interrupt#>
3841 3841 <1> ; 00000003 E9xxxxxxxx jmp com32_handle_interrupt
3842 3842 <1>
3843 3843 000011D0 B860B000E9 <1> mov eax,0e900b060h
3844 3844 000011D5 BB[840AF0FF] <1> mov ebx,com32_handle_interrupt-(pm_idt+8*256+8)
3845 3845 <1>
3846 3846 <1> .make_ijb:
3847 3847 000011DA AB <1> stosd
3848 3848 000011DB 284FFE <1> sub [edi-2],cl ; Interrupt #
3849 3849 000011DE 93 <1> xchg eax,ebx
3850 3850 000011DF AB <1> stosd
3851 3851 000011E0 83E808 <1> sub eax,8
3852 3852 000011E3 93 <1> xchg eax,ebx
3853 3853 000011E4 E2F4 <1> loop .make_ijb
3854 3854 <1>
3855 3855 <1> ; Now everything is set up for interrupts...
3856 3856 <1>
3857 3857 000011E6 68[9F120000] <1> push dword com32_farcall ; Farcall entry point
3858 3858 000011EB 6800000100 <1> push dword (1 << 16) ; 64K bounce buffer
3859 3859 000011F0 6800000300 <1> push dword (comboot_seg << 4) ; Bounce buffer address
3860 3860 000011F5 68[A7120000] <1> push dword com32_intcall ; Intcall entry point
3861 3861 000011FA 68[00000000] <1> push dword command_line ; Command line pointer
3862 3862 000011FF 6A05 <1> push dword 5 ; Argument count
3863 3863 00001201 FB <1> sti ; Interrupts OK now
3864 3864 00001202 E8(00101000) <1> call pm_entry ; Run the program...
3865 3865 <1> ; ... on return, fall through to com32_exit ...
3866 3866 <1>
3867 3867 <1> com32_exit:
3868 3868 00001207 66BB[4C12] <1> mov bx,com32_done ; Return to command loop
3869 3869 <1>
3870 3870 <1> com32_enter_rm:
3871 3871 0000120B FA <1> cli
3872 3872 0000120C FC <1> cld
3873 3873 0000120D 8925[28030000] <1> mov [PMESP],esp ; Save exit %esp
3874 3874 00001213 31E4 <1> xor esp,esp ; Make sure the high bits are zero
3875 3875 00001215 EA[1C120000]0800 <1> jmp 08h:.in_pm16 ; Return to 16-bit mode first
3876 3876 <1>
3877 3877 <1> bits 16
3878 3878 <1> .in_pm16:
3879 3879 0000121C B81800 <1> mov ax,18h ; Real-mode-like segment
3880 3880 0000121F 8EC0 <1> mov es,ax
3881 3881 00001221 8ED8 <1> mov ds,ax
3882 3882 00001223 8ED0 <1> mov ss,ax
3883 3883 00001225 8EE0 <1> mov fs,ax
3884 3884 00001227 8EE8 <1> mov gs,ax
3885 3885 <1>
3886 3886 00001229 0F011E[6C00] <1> lidt [com32_rmidt] ; Real-mode IDT (rm needs no GDT)
3887 3887 0000122E 0F20C0 <1> mov eax,cr0
3888 3888 00001231 24FE <1> and al,~1
3889 3889 00001233 0F22C0 <1> mov cr0,eax
3890 3890 00001236 EA[3B12]0000 <1> jmp 0:.in_rm
3891 3891 <1>
3892 3892 <1> .in_rm: ; Back in real mode
3893 3893 0000123B 8CC8 <1> mov ax,cs ; Set up sane segments
3894 3894 0000123D 8ED8 <1> mov ds,ax
3895 3895 0000123F 8EC0 <1> mov es,ax
3896 3896 00001241 8EE0 <1> mov fs,ax
3897 3897 00001243 8EE8 <1> mov gs,ax
3898 3898 00001245 0FB226[0440] <1> lss sp,[SavedSSSP] ; Restore stack
3899 3899 0000124A FFE3 <1> jmp bx ; Go to whereever we need to go...
3900 3900 <1>
3901 3901 <1> com32_done:
3902 3902 0000124C E8(6D01) <1> call disable_a20
3903 3903 0000124F FB <1> sti
3904 3904 00001250 E968F4 <1> jmp enter_command
3905 3905 <1>
3906 3906 <1> ;
3907 3907 <1> ; 16-bit support code
3908 3908 <1> ;
3909 3909 <1> bits 16
3910 3910 <1>
3911 3911 <1> ;
3912 3912 <1> ; 16-bit interrupt-handling code
3913 3913 <1> ;
3914 3914 <1> com32_int_rm:
3915 3915 00001253 9C <1> pushf ; Flags on stack
3916 3916 00001254 0E <1> push cs ; Return segment
3917 3917 00001255 68[5B12] <1> push word .cont ; Return address
3918 3918 00001258 6652 <1> push dword edx ; Segment:offset of IVT entry
3919 3919 0000125A CB <1> retf ; Invoke IVT routine
3920 3920 <1> .cont: ; ... on resume ...
3921 3921 0000125B 66BB[9D120000] <1> mov ebx,com32_int_resume
3922 3922 00001261 E906FF <1> jmp com32_enter_pm ; Go back to PM
3923 3923 <1>
3924 3924 <1> ;
3925 3925 <1> ; 16-bit system call handling code
3926 3926 <1> ;
3927 3927 <1> com32_sys_rm:
3928 3928 00001264 0FA9 <1> pop gs
3929 3929 00001266 0FA1 <1> pop fs
3930 3930 00001268 07 <1> pop es
3931 3931 00001269 1F <1> pop ds
3932 3932 0000126A 6661 <1> popad
3933 3933 0000126C 669D <1> popfd
3934 3934 0000126E 2E8926[2C03] <1> mov [cs:Com32SysSP],sp
3935 3935 00001273 CB <1> retf ; Invoke routine
3936 3936 <1> .return:
3937 3937 <1> ; We clean up SP here because we don't know if the
3938 3938 <1> ; routine returned with RET, RETF or IRET
3939 3939 00001274 2E8B26[2C03] <1> mov sp,[cs:Com32SysSP]
3940 3940 00001279 669C <1> pushfd
3941 3941 0000127B 6660 <1> pushad
3942 3942 0000127D 1E <1> push ds
3943 3943 0000127E 06 <1> push es
3944 3944 0000127F 0FA0 <1> push fs
3945 3945 00001281 0FA8 <1> push gs
3946 3946 00001283 66BB[F7120000] <1> mov ebx,com32_sys_resume
3947 3947 00001289 E9DEFE <1> jmp com32_enter_pm
3948 3948 <1>
3949 3949 <1> ;
3950 3950 <1> ; 32-bit support code
3951 3951 <1> ;
3952 3952 <1> bits 32
3953 3953 <1>
3954 3954 <1> ;
3955 3955 <1> ; This is invoked on getting an interrupt in protected mode. At
3956 3956 <1> ; this point, we need to context-switch to real mode and invoke
3957 3957 <1> ; the interrupt routine.
3958 3958 <1> ;
3959 3959 <1> ; When this gets invoked, the registers are saved on the stack and
3960 3960 <1> ; AL contains the register number.
3961 3961 <1> ;
3962 3962 <1> com32_handle_interrupt:
3963 3963 0000128C 0FB6C0 <1> movzx eax,al
3964 3964 0000128F 31DB <1> xor ebx,ebx ; Actually makes the code smaller
3965 3965 00001291 8B1483 <1> mov edx,[ebx+eax*4] ; Get the segment:offset of the routine
3966 3966 00001294 66BB[5312] <1> mov bx,com32_int_rm
3967 3967 00001298 E96EFFFFFF <1> jmp com32_enter_rm ; Go to real mode
3968 3968 <1>
3969 3969 <1> com32_int_resume:
3970 3970 0000129D 61 <1> popad
3971 3971 0000129E CF <1> iret
3972 3972 <1>
3973 3973 <1> ;
3974 3974 <1> ; Intcall/farcall invocation. We manifest a structure on the real-mode stack,
3975 3975 <1> ; containing the com32sys_t structure from <com32.h> as well as
3976 3976 <1> ; the following entries (from low to high address):
3977 3977 <1> ; - Target offset
3978 3978 <1> ; - Target segment
3979 3979 <1> ; - Return offset
3980 3980 <1> ; - Return segment (== real mode cs == 0)
3981 3981 <1> ; - Return flags
3982 3982 <1> ;
3983 3983 <1> com32_farcall:
3984 3984 0000129F 9C <1> pushfd ; Save IF among other things...
3985 3985 000012A0 60 <1> pushad ; We only need to save some, but...
3986 3986 <1>
3987 3987 000012A1 8B442428 <1> mov eax,[esp+10*4] ; CS:IP
3988 3988 000012A5 EB0E <1> jmp com32_syscall
3989 3989 <1>
3990 3990 <1>
3991 3991 <1> com32_intcall:
3992 3992 000012A7 9C <1> pushfd ; Save IF among other things...
3993 3993 000012A8 60 <1> pushad ; We only need to save some, but...
3994 3994 <1>
3995 3995 000012A9 0FB6442428 <1> movzx eax,byte [esp+10*4] ; INT number
3996 3996 000012AE 8B048500000000 <1> mov eax,[eax*4] ; Get CS:IP from low memory
3997 3997 <1>
3998 3998 <1> com32_syscall:
3999 3999 000012B5 FC <1> cld
4000 4000 <1>
4001 4001 000012B6 670FB73E[0440] <1> movzx edi,word [word SavedSSSP]
4002 4002 000012BC 670FB71E[0640] <1> movzx ebx,word [word SavedSSSP+2]
4003 4003 000012C2 83EF36 <1> sub edi,54 ; Allocate 54 bytes
4004 4004 000012C5 6667893E[0440] <1> mov [word SavedSSSP],di
4005 4005 000012CB C1E304 <1> shl ebx,4
4006 4006 000012CE 01DF <1> add edi,ebx ; Create linear address
4007 4007 <1>
4008 4008 000012D0 8B74242C <1> mov esi,[esp+11*4] ; Source regs
4009 4009 000012D4 31C9 <1> xor ecx,ecx
4010 4010 000012D6 B10B <1> mov cl,11 ; 44 bytes to copy
4011 4011 000012D8 F3A5 <1> rep movsd
4012 4012 <1>
4013 4013 <1> ; EAX is already set up to be CS:IP
4014 4014 000012DA AB <1> stosd ; Save in stack frame
4015 4015 000012DB B8[74120000] <1> mov eax,com32_sys_rm.return ; Return seg:offs
4016 4016 000012E0 AB <1> stosd ; Save in stack frame
4017 4017 000012E1 8B47F4 <1> mov eax,[edi-12] ; Return flags
4018 4018 000012E4 25D70C2000 <1> and eax,0x200cd7 ; Mask (potentially) unsafe flags
4019 4019 000012E9 8947F4 <1> mov [edi-12],eax ; Primary flags entry
4020 4020 000012EC 66AB <1> stosw ; Return flags
4021 4021 <1>
4022 4022 000012EE 66BB[6412] <1> mov bx,com32_sys_rm
4023 4023 000012F2 E914FFFFFF <1> jmp com32_enter_rm ; Go to real mode
4024 4024 <1>
4025 4025 <1> ; On return, the 44-byte return structure is on the
4026 4026 <1> ; real-mode stack, plus the 10 additional bytes used
4027 4027 <1> ; by the target address (see above.)
4028 4028 <1> com32_sys_resume:
4029 4029 000012F7 670FB736[0440] <1> movzx esi,word [word SavedSSSP]
4030 4030 000012FD 670FB706[0640] <1> movzx eax,word [word SavedSSSP+2]
4031 4031 00001303 8B7C2430 <1> mov edi,[esp+12*4] ; Dest regs
4032 4032 00001307 C1E004 <1> shl eax,4
4033 4033 0000130A 01C6 <1> add esi,eax ; Create linear address
4034 4034 0000130C 21FF <1> and edi,edi ; NULL pointer?
4035 4035 0000130E 7502 <1> jnz .do_copy
4036 4036 00001310 89F7 <1> .no_copy: mov edi,esi ; Do a dummy copy-to-self
4037 4037 00001312 31C9 <1> .do_copy: xor ecx,ecx
4038 4038 00001314 B10B <1> mov cl,11 ; 44 bytes
4039 4039 00001316 F3A5 <1> rep movsd ; Copy register block
4040 4040 <1>
4041 4041 00001318 678306[0440]36 <1> add dword [word SavedSSSP],54 ; Remove from stack
4042 4042 <1>
4043 4043 0000131E 61 <1> popad
4044 4044 0000131F 9D <1> popfd
4045 4045 00001320 C3 <1> ret ; Return to 32-bit program
4046 4046 <1>
4047 4047 <1> bits 16
4048 4048 <1>
4049 4049 <1> section .bss
4050 4050 00000327 <res 00000001> <1> alignb 4
4051 4051 00000328 <res 00000004> <1> PMESP resd 1 ; Protected-mode ESP
4052 4052 0000032C <res 00000002> <1> Com32SysSP resw 1 ; SP saved during COM32 syscall
4053 4053 <1>
4054 4054 <1> section .text
4055 4055 %include "cmdline.inc"
4056 4056 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
4057 4057 <1> ;; -----------------------------------------------------------------------
4058 4058 <1> ;;
4059 4059 <1> ;; Copyright 2003 H. Peter Anvin - All Rights Reserved
4060 4060 <1> ;;
4061 4061 <1> ;; This program is free software; you can redistribute it and/or modify
4062 4062 <1> ;; it under the terms of the GNU General Public License as published by
4063 4063 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
4064 4064 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
4065 4065 <1> ;; (at your option) any later version; incorporated herein by reference.
4066 4066 <1> ;;
4067 4067 <1> ;; -----------------------------------------------------------------------
4068 4068 <1>
4069 4069 <1> ;;
4070 4070 <1> ;; cmdline.inc
4071 4071 <1> ;;
4072 4072 <1> ;; Common routine to assemble [null-terminated] command line into
4073 4073 <1> ;; real_mode_seg:cmd_line_here.
4074 4074 <1> ;; Not used by plain kernel due to BOOT_IMAGE= etc.
4075 4075 <1> ;;
4076 4076 <1>
4077 4077 <1> ;
4078 4078 <1> ; Assumes DS == CS
4079 4079 <1> make_plain_cmdline:
4080 4080 00001321 06 <1> push es
4081 4081 <1> ; ui.inc has already copied any APPEND options
4082 4082 00001322 B80030 <1> mov ax,real_mode_seg
4083 4083 00001325 8EC0 <1> mov es,ax
4084 4084 <1>
4085 4085 00001327 8B36[0A03] <1> mov si,[CmdOptPtr]
4086 4086 0000132B 8B3E[AA00] <1> mov di,[CmdLinePtr]
4087 4087 <1>
4088 4088 0000132F E8740E <1> call strcpy
4089 4089 <1>
4090 4090 00001332 4F <1> dec di
4091 4091 00001333 893E[AA00] <1> mov [CmdLinePtr],di
4092 4092 <1>
4093 4093 00001337 07 <1> pop es
4094 4094 00001338 C3 <1> ret
4095 4095 <1>
4096 4096 <1>
4097 4097
4098 4098 ;
4099 4099 ; Boot sector loading code
4100 4100 ;
4101 4101 %include "bootsect.inc"
4102 4102 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
4103 4103 <1> ;; -----------------------------------------------------------------------
4104 4104 <1> ;;
4105 4105 <1> ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
4106 4106 <1> ;;
4107 4107 <1> ;; This program is free software; you can redistribute it and/or modify
4108 4108 <1> ;; it under the terms of the GNU General Public License as published by
4109 4109 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
4110 4110 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
4111 4111 <1> ;; (at your option) any later version; incorporated herein by reference.
4112 4112 <1> ;;
4113 4113 <1> ;; -----------------------------------------------------------------------
4114 4114 <1>
4115 4115 <1> ;;
4116 4116 <1> ;; bootsect.inc
4117 4117 <1> ;;
4118 4118 <1> ;; Load a boot sector (or other bootstrap program.)
4119 4119 <1> ;;
4120 4120 <1> ;; Unlike previous versions of this software, this doesn't require that
4121 4121 <1> ;; the length is 512 bytes. This allows PXE bootstraps and WinNT
4122 4122 <1> ;; "CD boot sectors" to be invoked.
4123 4123 <1> ;;
4124 4124 <1>
4125 4125 <1> ;
4126 4126 <1> ; Load a boot sector
4127 4127 <1> ;
4128 4128 <1> is_bootsector:
4129 4129 <1> %if IS_SYSLINUX || IS_MDSLINUX
4130 4130 <1> ; Transfer zero bytes
4131 4131 <1> mov byte [CopySuper],0
4132 4132 <1> jmp short load_bootsec
4133 4133 <1>
4134 4134 <1> is_bss_sector:
4135 4135 <1> ; Transfer the superblock
4136 4136 <1> mov byte [CopySuper],superblock_len
4137 4137 <1> %endif
4138 4138 <1> load_bootsec:
4139 4139 00001339 92 <1> xchg dx,ax
4140 4140 0000133A 66C1E010 <1> shl eax,16
4141 4141 0000133E 92 <1> xchg dx,ax ; Now EAX = file length
4142 4142 0000133F 66BF00001000 <1> mov edi, 100000h
4143 4143 00001345 66893E[0400] <1> mov [trackbuf+4],edi ; Copy from this address
4144 4144 0000134A 6657 <1> push edi ; Save load address
4145 4145 0000134C 31D2 <1> xor dx,dx ; No padding
4146 4146 0000134E E8940A <1> call load_high
4147 4147 00001351 E8C9EF <1> call crlf
4148 4148 <1>
4149 4149 00001354 6681EF00001000 <1> sub edi,100000h
4150 4150 0000135B 66893E[0800] <1> mov [trackbuf+8],edi ; Save length
4151 4151 <1>
4152 4152 00001360 66B8007C0000 <1> mov eax,7C00h ; Entry point
4153 4153 00001366 66A3[0000] <1> mov [trackbuf],eax ; Copy to this address
4154 4154 0000136A 66A3[0040] <1> mov [EntryPoint],eax ; Jump to this address when done
4155 4155 <1>
4156 4156 <1> %if IS_SYSLINUX || IS_MDSLINUX
4157 4157 <1> movzx ecx,byte [CopySuper]
4158 4158 <1> jcxz .not_bss
4159 4159 <1>
4160 4160 <1> ; For a BSS boot sector we have to patch.
4161 4161 <1> mov esi,superblock
4162 4162 <1> mov edi,100000h+(superblock-bootsec)
4163 4163 <1> call bcopy
4164 4164 <1>
4165 4165 <1> .not_bss:
4166 4166 <1> %endif
4167 4167 <1>
4168 4168 0000136E 6631D2 <1> xor edx,edx
4169 4169 00001371 6631F6 <1> xor esi,esi
4170 4170 <1> %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
4171 4171 <1> ; Restore original FDC table
4172 4172 <1> mov eax,[OrigFDCTabPtr]
4173 4173 <1> mov [fdctab],eax
4174 4174 <1>
4175 4175 <1> mov dl,[DriveNumber]
4176 4176 <1> mov si,PartInfo ; Partition info buffer
4177 4177 <1> mov di,800h-18 ; Put partition info here
4178 4178 <1> push di
4179 4179 <1> mov cx,8 ; 16 bytes
4180 4180 <1> xor ax,ax
4181 4181 <1> rep movsw
4182 4182 <1> pop si ; DS:SI points to partition info
4183 4183 <1> %elif IS_ISOLINUX
4184 4184 00001374 8A16[6900] <1> mov dl,[DriveNo]
4185 4185 <1> %elif IS_PXELINUX
4186 4186 <1> mov byte [KeepPXE],1 ; Chainloading another NBP
4187 4187 <1> call reset_pxe
4188 4188 <1> %endif
4189 4189 00001378 31DB <1> xor bx,bx
4190 4190 <1>
4191 4191 <1> ;
4192 4192 <1> ; replace_bootstrap for the special case where we have exactly one
4193 4193 <1> ; descriptor, and it's the first entry in the trackbuf
4194 4194 <1> ;
4195 4195 <1>
4196 4196 <1> replace_bootstrap_one:
4197 4197 0000137A 68[0000] <1> push word trackbuf ; Address of descriptor list
4198 4198 0000137D 6A01 <1> push word 1 ; Length of descriptor list
4199 4199 <1> ; Fall through
4200 4200 <1>
4201 4201 <1> ;
4202 4202 <1> ; Entrypoint for "shut down and replace bootstrap" -- also invoked by
4203 4203 <1> ; the COMBOOT API. This routine expects two words on the stack:
4204 4204 <1> ; address of the copy list (versus DS) and count. Additionally,
4205 4205 <1> ; the values of ESI and EDX are passed on to the new bootstrap;
4206 4206 <1> ; the value of BX becomes the new DS.
4207 4207 <1> ;
4208 4208 <1> replace_bootstrap:
4209 4209 <1> ;
4210 4210 <1> ; Prepare for shutting down
4211 4211 <1> ;
4212 4212 0000137F E8ED0C <1> call vgaclearmode
4213 4213 <1>
4214 4214 <1> ;
4215 4215 <1> ; Set up initial stack frame (not used by PXE if keeppxe is
4216 4216 <1> ; set - we use the PXE stack then.)
4217 4217 <1> ; AFTER THIS POINT ONLY .earlybss IS AVAILABLE, NOT .bss
4218 4218 <1> ;
4219 4219 00001382 31C0 <1> xor ax,ax
4220 4220 00001384 8ED8 <1> mov ds,ax
4221 4221 00001386 8EC0 <1> mov es,ax
4222 4222 <1>
4223 4223 <1> %if IS_PXELINUX
4224 4224 <1> test byte [KeepPXE],01h
4225 4225 <1> jz .stdstack
4226 4226 <1> les di,[InitStack] ; Reset stack to PXE original
4227 4227 <1> jmp .stackok
4228 4228 <1> %endif
4229 4229 <1> .stdstack:
4230 4230 00001388 BFD47B <1> mov di,7C00h-44
4231 4231 0000138B 57 <1> push di
4232 4232 0000138C B91600 <1> mov cx,22 ; 44 bytes
4233 4233 0000138F F3AB <1> rep stosw
4234 4234 00001391 5F <1> pop di
4235 4235 <1> .stackok:
4236 4236 <1>
4237 4237 00001392 266689551C <1> mov [es:di+28],edx
4238 4238 00001397 266689750C <1> mov [es:di+12],esi
4239 4239 0000139C 26895D06 <1> mov [es:di+6],bx
4240 4240 <1>
4241 4241 000013A0 58 <1> pop ax ; Copy list count
4242 4242 000013A1 5B <1> pop bx ; Copy from...
4243 4243 <1>
4244 4244 000013A2 FA <1> cli
4245 4245 000013A3 8CC1 <1> mov cx,es
4246 4246 000013A5 8ED1 <1> mov ss,cx
4247 4247 000013A7 660FB7E7 <1> movzx esp,di
4248 4248 <1>
4249 4249 000013AB E9(CD01) <1> jmp shuffle_and_boot
4250 4250 <1>
4251 4251 <1> %if IS_SYSLINUX || IS_MDSLINUX
4252 4252 <1> ; Nothing
4253 4253 <1> %else
4254 4254 <1> is_bss_sector:
4255 4255 000013AE BE[1503] <1> mov si,err_bssimage
4256 4256 000013B1 E876EF <1> call cwritestr
4257 4257 000013B4 E904F3 <1> jmp enter_command
4258 4258 <1> %endif
4259 4259
4260 4260 ;
4261 4261 ; Enable disk emulation. The kind of disk we emulate is dependent on the size of
4262 4262 ; the file: 1200K, 1440K or 2880K floppy, otherwise harddisk.
4263 4263 ;
4264 4264 is_disk_image:
4265 4265 TRACER CR
4266 4266 TRACER LF
4267 4267 TRACER 'D'
4268 4268 TRACER ':'
4269 4269
4270 4270 000013B7 66C1E210 shl edx,16
4271 4271 000013BB 89C2 mov dx,ax ; Set EDX <- file size
4272 4272 000013BD BF[2C05] mov di,img_table
4273 4273 000013C0 B90300 mov cx,img_table_count
4274 4274 000013C3 668B04 mov eax,[si+file_sector] ; Starting LBA of file
4275 4275 000013C6 66A3[E400] mov [dsp_lba],eax ; Location of file
4276 4276 000013CA C606[E200]00 mov byte [dsp_drive], 0 ; 00h floppy, 80h hard disk
4277 4277 .search_table:
4278 4278 TRACER 't'
4279 4279 000013CF 668B4504 mov eax,[di+4]
4280 4280 000013D3 663B15 cmp edx,[di]
4281 4281 000013D6 0F848500 je .type_found
4282 4282 000013DA 83C708 add di,8
4283 4283 000013DD E2F0 loop .search_table
4284 4284
4285 4285 ; Hard disk image. Need to examine the partition table
4286 4286 ; in order to deduce the C/H/S geometry. Sigh.
4287 4287 .hard_disk_image:
4288 4288 TRACER 'h'
4289 4289 000013DF 6681FA00020000 cmp edx,512
4290 4290 000013E6 0F82A900 jb .bad_image
4291 4291
4292 4292 000013EA BB[0000] mov bx,trackbuf
4293 4293 000013ED B90100 mov cx,1 ; Load 1 sector
4294 4294 000013F0 E8AB02 call getfssec
4295 4295
4296 4296 000013F3 813E[FE01]55AA cmp word [trackbuf+510],0aa55h ; Boot signature
4297 4297 000013F9 0F859600 jne .bad_image ; Image not bootable
4298 4298
4299 4299 000013FD B90400 mov cx,4 ; 4 partition entries
4300 4300 00001400 BF[BE01] mov di,trackbuf+446 ; Start of partition table
4301 4301
4302 4302 00001403 31C0 xor ax,ax ; Highest sector(al) head(ah)
4303 4303
4304 4304 .part_scan:
4305 4305 00001405 807D0400 cmp byte [di+4], 0
4306 4306 00001409 740C jz .part_loop
4307 4307 0000140B 8D7501 lea si,[di+1]
4308 4308 0000140E E88B00 call .hs_check
4309 4309 00001411 83C604 add si,byte 4
4310 4310 00001414 E88500 call .hs_check
4311 4311 .part_loop:
4312 4312 00001417 83C710 add di,byte 16
4313 4313 0000141A E2E9 loop .part_scan
4314 4314
4315 4315 0000141C 6650 push eax ; H/S
4316 4316 0000141E 6652 push edx ; File size
4317 4317 00001420 88E3 mov bl,ah
4318 4318 00001422 30FF xor bh,bh
4319 4319 00001424 43 inc bx ; # of heads in BX
4320 4320 00001425 30E4 xor ah,ah ; # of sectors in AX
4321 4321 00001427 6698 cwde ; EAX[31:16] <- 0
4322 4322 00001429 F7E3 mul bx
4323 4323 0000142B 66C1E009 shl eax,9 ; Convert to bytes
4324 4324 ; Now eax contains the number of bytes per cylinder
4325 4325 0000142F 665B pop ebx ; File size
4326 4326 00001431 6631D2 xor edx,edx
4327 4327 00001434 66F7F3 div ebx
4328 4328 00001437 6621D2 and edx,edx
4329 4329 0000143A 7402 jz .no_remainder
4330 4330 0000143C 6640 inc eax ; Fractional cylinder...
4331 4331 ; Now (e)ax contains the number of cylinders
4332 4332 0000143E 663D00040000 .no_remainder: cmp eax,1024
4333 4333 00001444 7603 jna .ok_cyl
4334 4334 00001446 B80004 mov ax,1024 ; Max possible #
4335 4335 00001449 48 .ok_cyl: dec ax ; Convert to max cylinder no
4336 4336 0000144A 665B pop ebx ; S(bl) H(bh)
4337 4337 0000144C C0E406 shl ah,6
4338 4338 0000144F 08E3 or bl,ah
4339 4339 00001451 93 xchg ax,bx
4340 4340 00001452 66C1E010 shl eax,16
4341 4341 00001456 88DC mov ah,bl
4342 4342 00001458 B004 mov al,4 ; Hard disk boot
4343 4343 0000145A C606[E200]80 mov byte [dsp_drive], 80h ; Drive 80h = hard disk
4344 4344
4345 4345 .type_found:
4346 4346 TRACER 'T'
4347 4347 0000145F 8A1E[7100] mov bl,[sp_media]
4348 4348 00001463 80E3F0 and bl,0F0h ; Copy controller info bits
4349 4349 00001466 08D8 or al,bl
4350 4350 00001468 A2[E100] mov [dsp_media],al ; Emulation type
4351 4351 0000146B 66C1E808 shr eax,8
4352 4352 0000146F 66A3[F000] mov [dsp_chs],eax ; C/H/S geometry
4353 4353 00001473 A1[7800] mov ax,[sp_devspec] ; Copy device spec
4354 4354 00001476 A3[E800] mov [dsp_devspec],ax
4355 4355 00001479 A0[7300] mov al,[sp_controller] ; Copy controller index
4356 4356 0000147C A2[E300] mov [dsp_controller],al
4357 4357
4358 4358 TRACER 'V'
4359 4359 0000147F E8ED0B call vgaclearmode ; Reset video
4360 4360
4361 4361 00001482 B8004C mov ax,4C00h ; Enable emulation and boot
4362 4362 00001485 BE[E000] mov si,dspec_packet
4363 4363 00001488 8A16[6900] mov dl,[DriveNo]
4364 4364 0000148C 0FB226[6000] lss sp,[InitStack]
4365 4365 TRACER 'X'
4366 4366
4367 4367 00001491 CD13 int 13h
4368 4368
4369 4369 ; If this returns, we have problems
4370 4370 .bad_image:
4371 4371 00001493 BE[E803] mov si,err_disk_image
4372 4372 00001496 E891EE call cwritestr
4373 4373 00001499 E91FF2 jmp enter_command
4374 4374
4375 4375 ;
4376 4376 ; Look for the highest seen H/S geometry
4377 4377 ; We compute cylinders separately
4378 4378 ;
4379 4379 .hs_check:
4380 4380 0000149C 8A1C mov bl,[si] ; Head #
4381 4381 0000149E 38E3 cmp bl,ah
4382 4382 000014A0 7602 jna .done_track
4383 4383 000014A2 88DC mov ah,bl ; New highest head #
4384 4384 000014A4 8A5C01 .done_track: mov bl,[si+1]
4385 4385 000014A7 80E33F and bl,3Fh ; Sector #
4386 4386 000014AA 38C3 cmp bl,al
4387 4387 000014AC 7602 jna .done_sector
4388 4388 000014AE 88D8 mov al,bl
4389 4389 000014B0 C3 .done_sector: ret
4390 4390
4391 4391 ;
4392 4392 ; Boot a specified local disk. AX specifies the BIOS disk number; or
4393 4393 ; 0xFFFF in case we should execute INT 18h ("next device.")
4394 4394 ;
4395 4395 local_boot:
4396 4396 000014B1 E8BB0B call vgaclearmode
4397 4397 000014B4 2E0FB226[0000] lss sp,[cs:Stack] ; Restore stack pointer
4398 4398 000014BA 31D2 xor dx,dx
4399 4399 000014BC 8EDA mov ds,dx
4400 4400 000014BE 8EC2 mov es,dx
4401 4401 000014C0 8EE2 mov fs,dx
4402 4402 000014C2 8EEA mov gs,dx
4403 4403 000014C4 BE[5A03] mov si,localboot_msg
4404 4404 000014C7 E860EE call writestr
4405 4405 000014CA 83F8FF cmp ax,-1
4406 4406 000014CD 742F je .int18
4407 4407
4408 4408 ; Load boot sector from the specified BIOS device and jump to it.
4409 4409 000014CF 88C2 mov dl,al
4410 4410 000014D1 30F6 xor dh,dh
4411 4411 000014D3 52 push dx
4412 4412 000014D4 31C0 xor ax,ax ; Reset drive
4413 4413 000014D6 E8B6ED call xint13
4414 4414 000014D9 B80102 mov ax,0201h ; Read one sector
4415 4415 000014DC B90100 mov cx,0001h ; C/H/S = 0/0/1 (first sector)
4416 4416 000014DF BB[0000] mov bx,trackbuf
4417 4417 000014E2 E8AAED call xint13
4418 4418 000014E5 5A pop dx
4419 4419 000014E6 FA cli ; Abandon hope, ye who enter here
4420 4420 000014E7 BE[0000] mov si,trackbuf
4421 4421 000014EA BF007C mov di,07C00h
4422 4422 000014ED B90002 mov cx,512 ; Probably overkill, but should be safe
4423 4423 000014F0 F366A5 rep movsd
4424 4424 000014F3 2E0FB226[6000] lss sp,[cs:InitStack]
4425 4425 000014F9 EA007C0000 jmp 0:07C00h ; Jump to new boot sector
4426 4426
4427 4427 .int18:
4428 4428 000014FE CD18 int 18h ; Hope this does the right thing...
4429 4429 00001500 E9F4ED jmp kaboom ; If we returned, oh boy...
4430 4430
4431 4431 ;
4432 4432 ; Abort loading code
4433 4433 ;
4434 4434 %include "abort.inc"
4435 4435 <1> ; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
4436 4436 <1> ; -----------------------------------------------------------------------
4437 4437 <1> ;
4438 4438 <1> ; Copyright 2005 H. Peter Anvin - All Rights Reserved
4439 4439 <1> ;
4440 4440 <1> ; This program is free software; you can redistribute it and/or modify
4441 4441 <1> ; it under the terms of the GNU General Public License as published by
4442 4442 <1> ; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
4443 4443 <1> ; Boston MA 02111-1307, USA; either version 2 of the License, or
4444 4444 <1> ; (at your option) any later version; incorporated herein by reference.
4445 4445 <1> ;
4446 4446 <1> ; -----------------------------------------------------------------------
4447 4447 <1>
4448 4448 <1> ;
4449 4449 <1> ; abort.inc
4450 4450 <1> ;
4451 4451 <1> ; Code to terminate a kernel load
4452 4452 <1> ;
4453 4453 <1>
4454 4454 <1> section .text
4455 4455 <1> ;
4456 4456 <1> ; abort_check: let the user abort with <ESC> or <Ctrl-C>
4457 4457 <1> ;
4458 4458 <1> abort_check:
4459 4459 00001503 E86F05 <1> call pollchar
4460 4460 00001506 740D <1> jz .ret1
4461 4461 00001508 60 <1> pusha
4462 4462 00001509 E89305 <1> call getchar
4463 4463 0000150C 3C1B <1> cmp al,27 ; <ESC>
4464 4464 0000150E 7406 <1> je .kill
4465 4465 00001510 3C03 <1> cmp al,3 ; <Ctrl-C>
4466 4466 00001512 7402 <1> je .kill
4467 4467 00001514 61 <1> .ret2: popa
4468 4468 00001515 C3 <1> .ret1: ret
4469 4469 <1>
4470 4470 00001516 BE[B503] <1> .kill: mov si,aborted_msg
4471 4471 <1>
4472 4472 <1> ; ... fall through ...
4473 4473 <1>
4474 4474 <1> ;
4475 4475 <1> ; abort_load: Called by various routines which wants to print a fatal
4476 4476 <1> ; error message and return to the command prompt. Since this
4477 4477 <1> ; may happen at just about any stage of the boot process, assume
4478 4478 <1> ; our state is messed up, and just reset the segment registers
4479 4479 <1> ; and the stack forcibly.
4480 4480 <1> ;
4481 4481 <1> ; SI = offset (in _text) of error message to print
4482 4482 <1> ;
4483 4483 <1> abort_load:
4484 4484 00001519 8CC8 <1> mov ax,cs ; Restore CS = DS = ES
4485 4485 0000151B 8ED8 <1> mov ds,ax
4486 4486 0000151D 8EC0 <1> mov es,ax
4487 4487 <1> %if IS_SYSLINUX || IS_EXTLINUX
4488 4488 <1> mov ss,ax ; Just in case...
4489 4489 <1> mov sp,StackBuf-2*3 ; Reset stack
4490 4490 <1> %elif IS_PXELINUX
4491 4491 <1> lss esp,[BaseStack]
4492 4492 <1> %elif IS_ISOLINUX
4493 4493 0000151F 0FB226[CC05] <1> lss sp,[StackPtr]
4494 4494 <1> %else
4495 4495 <1> NEED TO KNOW HOW TO RESET STACK
4496 4496 <1> %endif
4497 4497 00001524 FB <1> sti
4498 4498 00001525 E802EE <1> call cwritestr ; Expects SI -> error msg
4499 4499 <1>
4500 4500 <1> ; Return to the command prompt
4501 4501 00001528 E990F1 <1> jmp enter_command
4502 4502
4503 4503 ;
4504 4504 ; searchdir:
4505 4505 ;
4506 4506 ; Open a file
4507 4507 ;
4508 4508 ; On entry:
4509 4509 ; DS:DI = filename
4510 4510 ; If successful:
4511 4511 ; ZF clear
4512 4512 ; SI = file pointer
4513 4513 ; DX:AX or EAX = file length in bytes
4514 4514 ; If unsuccessful
4515 4515 ; ZF set
4516 4516 ;
4517 4517 ; Assumes CS == DS == ES, and trashes BX and CX.
4518 4518 ;
4519 4519 ; searchdir_iso is a special entry point for ISOLINUX only. In addition
4520 4520 ; to the above, searchdir_iso passes a file flag mask in AL. This is useful
4521 4521 ; for searching for directories.
4522 4522 ;
4523 4523 alloc_failure:
4524 4524 0000152B 31C0 xor ax,ax ; ZF <- 1
4525 4525 0000152D C3 ret
4526 4526
4527 4527 searchdir:
4528 4528 0000152E 30C0 xor al,al
4529 4529 searchdir_iso:
4530 4530 00001530 A2[6A00] mov [ISOFlags],al
4531 4531 TRACER 'S'
4532 4532 00001533 E8D100 call allocate_file ; Temporary file structure for directory
4533 4533 00001536 75F3 jnz alloc_failure
4534 4534 00001538 06 push es
4535 4535 00001539 1E push ds
4536 4536 0000153A 07 pop es ; ES = DS
4537 4537 0000153B BE[4000] mov si,CurDir
4538 4538 0000153E 803D2F cmp byte [di],'/' ; If filename begins with slash
4539 4539 00001541 7504 jne .not_rooted
4540 4540 00001543 47 inc di ; Skip leading slash
4541 4541 00001544 BE[4C00] mov si,RootDir ; Reference root directory instead
4542 4542 .not_rooted:
4543 4543 00001547 668B4408 mov eax,[si+dir_clust]
4544 4544 0000154B 66894704 mov [bx+file_left],eax
4545 4545 0000154F 668B04 mov eax,[si+dir_lba]
4546 4546 00001552 668907 mov [bx+file_sector],eax
4547 4547 00001555 668B5404 mov edx,[si+dir_len]
4548 4548
4549 4549 .look_for_slash:
4550 4550 00001559 89F8 mov ax,di
4551 4551 .scan:
4552 4552 0000155B 8A0D mov cl,[di]
4553 4553 0000155D 47 inc di
4554 4554 0000155E 20C9 and cl,cl
4555 4555 00001560 7415 jz .isfile
4556 4556 00001562 80F92F cmp cl,'/'
4557 4557 00001565 75F4 jne .scan
4558 4558 00001567 C645FF00 mov [di-1],byte 0 ; Terminate at directory name
4559 4559 0000156B B102 mov cl,02h ; Search for directory
4560 4560 0000156D 860E[6A00] xchg cl,[ISOFlags]
4561 4561
4562 4562 00001571 57 push di ; Save these...
4563 4563 00001572 51 push cx
4564 4564
4565 4565 ; Create recursion stack frame...
4566 4566 00001573 68[F615] push word .resume ; Where to "return" to
4567 4567 00001576 06 push es
4568 4568 00001577 97 .isfile: xchg ax,di
4569 4569
4570 4570 .getsome:
4571 4571 ; Get a chunk of the directory
4572 4572 ; This relies on the fact that ISOLINUX doesn't change SI
4573 4573 00001578 BE[0000] mov si,trackbuf
4574 4574 TRACER 'g'
4575 4575 0000157B 6660 pushad
4576 4576 0000157D 87DE xchg bx,si
4577 4577 0000157F 8B0E[4405] mov cx,[BufSafe]
4578 4578 00001583 E81801 call getfssec
4579 4579 00001586 6661 popad
4580 4580
4581 4581 .compare:
4582 4582 00001588 660FB604 movzx eax,byte [si] ; Length of directory entry
4583 4583 0000158C 3C21 cmp al,33
4584 4584 0000158E 7229 jb .next_sector
4585 4585 TRACER 'c'
4586 4586 00001590 8A4C19 mov cl,[si+25]
4587 4587 00001593 320E[6A00] xor cl,[ISOFlags]
4588 4588 00001597 F6C18E test cl, byte 8Eh ; Unwanted file attributes!
4589 4589 0000159A 750E jnz .not_file
4590 4590 0000159C 60 pusha
4591 4591 0000159D 0FB64C20 movzx cx,byte [si+32] ; File identifier length
4592 4592 000015A1 83C621 add si,byte 33 ; File identifier offset
4593 4593 TRACER 'i'
4594 4594 000015A4 E87400 call iso_compare_names
4595 4595 000015A7 61 popa
4596 4596 000015A8 7422 je .success
4597 4597 .not_file:
4598 4598 000015AA 6629C2 sub edx,eax ; Decrease bytes left
4599 4599 000015AD 7615 jbe .failure
4600 4600 000015AF 01C6 add si,ax ; Advance pointer
4601 4601
4602 4602 .check_overrun:
4603 4603 ; Did we finish the buffer?
4604 4604 000015B1 81FE[0020] cmp si,trackbuf+trackbufsize
4605 4605 000015B5 72D1 jb .compare ; No, keep going
4606 4606
4607 4607 000015B7 EBBF jmp short .getsome ; Get some more directory
4608 4608
4609 4609 .next_sector:
4610 4610 ; Advance to the beginning of next sector
4611 4611 000015B9 8D84FF07 lea ax,[si+SECTOR_SIZE-1]
4612 4612 000015BD 2500F8 and ax,~(SECTOR_SIZE-1)
4613 4613 000015C0 29F0 sub ax,si
4614 4614 000015C2 EBE6 jmp short .not_file ; We still need to do length checks
4615 4615
4616 4616 000015C4 6631C0 .failure: xor eax,eax ; ZF = 1
4617 4617 000015C7 668907 mov [bx+file_sector],eax
4618 4618 000015CA 07 pop es
4619 4619 000015CB C3 ret
4620 4620
4621 4621 .success:
4622 4622 000015CC 668B4402 mov eax,[si+2] ; Location of extent
4623 4623 000015D0 668907 mov [bx+file_sector],eax
4624 4624 000015D3 668B440A mov eax,[si+10] ; Data length
4625 4625 000015D7 6650 push eax
4626 4626 000015D9 6605FF070000 add eax,SECTOR_SIZE-1
4627 4627 000015DF 66C1E80B shr eax,SECTOR_SHIFT
4628 4628 000015E3 66894704 mov [bx+file_left],eax
4629 4629 000015E7 6658 pop eax
4630 4630 000015E9 6689C2 mov edx,eax
4631 4631 000015EC 66C1EA10 shr edx,16
4632 4632 000015F0 21DB and bx,bx ; ZF = 0
4633 4633 000015F2 89DE mov si,bx
4634 4634 000015F4 07 pop es
4635 4635 000015F5 C3 ret
4636 4636
4637 4637 .resume: ; We get here if we were only doing part of a lookup
4638 4638 ; This relies on the fact that .success returns bx == si
4639 4639 000015F6 6692 xchg edx,eax ; Directory length in edx
4640 4640 000015F8 59 pop cx ; Old ISOFlags
4641 4641 000015F9 5F pop di ; Next filename pointer
4642 4642 000015FA C645FF2F mov byte [di-1], '/' ; Restore slash
4643 4643 000015FE 880E[6A00] mov [ISOFlags],cl ; Restore the flags
4644 4644 00001602 74C0 jz .failure ; Did we fail? If so fail for real!
4645 4645 00001604 E952FF jmp .look_for_slash ; Otherwise, next level
4646 4646
4647 4647 ;
4648 4648 ; allocate_file: Allocate a file structure
4649 4649 ;
4650 4650 ; If successful:
4651 4651 ; ZF set
4652 4652 ; BX = file pointer
4653 4653 ; In unsuccessful:
4654 4654 ; ZF clear
4655 4655 ;
4656 4656 allocate_file:
4657 4657 TRACER 'a'
4658 4658 00001607 51 push cx
4659 4659 00001608 BB[F800] mov bx,Files
4660 4660 0000160B B94000 mov cx,MAX_OPEN
4661 4661 0000160E 66833F00 .check: cmp dword [bx], byte 0
4662 4662 00001612 7405 je .found
4663 4663 00001614 83C308 add bx,open_file_t_size ; ZF = 0
4664 4664 00001617 E2F5 loop .check
4665 4665 ; ZF = 0 if we fell out of the loop
4666 4666 00001619 59 .found: pop cx
4667 4667 0000161A C3 ret
4668 4668
4669 4669 ;
4670 4670 ; iso_compare_names:
4671 4671 ; Compare the names DS:SI and DS:DI and report if they are
4672 4672 ; equal from an ISO 9660 perspective. SI is the name from
4673 4673 ; the filesystem; CX indicates its length, and ';' terminates.
4674 4674 ; DI is expected to end with a null.
4675 4675 ;
4676 4676 ; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment
4677 4677 ;
4678 4678
4679 4679 iso_compare_names:
4680 4680 ; First, terminate and canonicalize input filename
4681 4681 0000161B 57 push di
4682 4682 0000161C BF[0000] mov di,ISOFileName
4683 4683 0000161F E311 .canon_loop: jcxz .canon_end
4684 4684 00001621 AC lodsb
4685 4685 00001622 49 dec cx
4686 4686 00001623 3C3B cmp al,';'
4687 4687 00001625 740B je .canon_end
4688 4688 00001627 20C0 and al,al
4689 4689 00001629 7407 je .canon_end
4690 4690 0000162B AA stosb
4691 4691 0000162C 81FF[3F00] cmp di,ISOFileNameEnd-1 ; Guard against buffer overrun
4692 4692 00001630 72ED jb .canon_loop
4693 4693 .canon_end:
4694 4694 00001632 81FF[0000] cmp di,ISOFileName
4695 4695 00001636 7609 jbe .canon_done
4696 4696 00001638 807DFF2E cmp byte [di-1],'.' ; Remove terminal dots
4697 4697 0000163C 7503 jne .canon_done
4698 4698 0000163E 4F dec di
4699 4699 0000163F EBF1 jmp short .canon_end
4700 4700 .canon_done:
4701 4701 00001641 C60500 mov [di],byte 0 ; Null-terminate string
4702 4702 00001644 5F pop di
4703 4703 00001645 BE[0000] mov si,ISOFileName
4704 4704 .compare:
4705 4705 00001648 AC lodsb
4706 4706 00001649 8A25 mov ah,[di]
4707 4707 0000164B 47 inc di
4708 4708 0000164C 21C0 and ax,ax
4709 4709 0000164E 7411 jz .success ; End of string for both
4710 4710 00001650 20C0 and al,al ; Is either one end of string?
4711 4711 00001652 740B jz .failure ; If so, failure
4712 4712 00001654 20E4 and ah,ah
4713 4713 00001656 7407 jz .failure
4714 4714 00001658 0D2020 or ax,2020h ; Convert to lower case
4715 4715 0000165B 38E0 cmp al,ah
4716 4716 0000165D 74E9 je .compare
4717 4717 0000165F 21C0 .failure: and ax,ax ; ZF = 0 (at least one will be nonzero)
4718 4718 00001661 C3 .success: ret
4719 4719
4720 4720 ;
4721 4721 ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed
4722 4722 ; to by ES:DI; ends on encountering any whitespace.
4723 4723 ;
4724 4724 ; This verifies that a filename is < FILENAME_MAX characters,
4725 4725 ; doesn't contain whitespace, zero-pads the output buffer,
4726 4726 ; and removes trailing dots and redundant slashes,
4727 4727 ; so "repe cmpsb" can do a compare, and the
4728 4728 ; path-searching routine gets a bit of an easier job.
4729 4729 ;
4730 4730 mangle_name:
4731 4731 00001662 53 push bx
4732 4732 00001663 31C0 xor ax,ax
4733 4733 00001665 B9FF00 mov cx,FILENAME_MAX-1
4734 4734 00001668 89FB mov bx,di
4735 4735
4736 4736 .mn_loop:
4737 4737 0000166A AC lodsb
4738 4738 0000166B 3C20 cmp al,' ' ; If control or space, end
4739 4739 0000166D 760F jna .mn_end
4740 4740 0000166F 38E0 cmp al,ah ; Repeated slash?
4741 4741 00001671 7409 je .mn_skip
4742 4742 00001673 30E4 xor ah,ah
4743 4743 00001675 3C2F cmp al,'/'
4744 4744 00001677 7502 jne .mn_ok
4745 4745 00001679 88C4 mov ah,al
4746 4746 0000167B AA .mn_ok stosb
4747 4747 0000167C E2EC .mn_skip: loop .mn_loop
4748 4748 .mn_end:
4749 4749 0000167E 39FB cmp bx,di ; At the beginning of the buffer?
4750 4750 00001680 7610 jbe .mn_zero
4751 4751 00001682 807DFF2E cmp byte [di-1],'.' ; Terminal dot?
4752 4752 00001686 7406 je .mn_kill
4753 4753 00001688 807DFF2F cmp byte [di-1],'/' ; Terminal slash?
4754 4754 0000168C 7504 jne .mn_zero
4755 4755 0000168E 4F .mn_kill: dec di ; If so, remove it
4756 4756 0000168F 41 inc cx
4757 4757 00001690 EBEC jmp short .mn_end
4758 4758 .mn_zero:
4759 4759 00001692 41 inc cx ; At least one null byte
4760 4760 00001693 31C0 xor ax,ax ; Zero-fill name
4761 4761 00001695 F3AA rep stosb
4762 4762 00001697 5B pop bx
4763 4763 00001698 C3 ret ; Done
4764 4764
4765 4765 ;
4766 4766 ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled
4767 4767 ; filename to the conventional representation. This is needed
4768 4768 ; for the BOOT_IMAGE= parameter for the kernel.
4769 4769 ; NOTE: A 13-byte buffer is mandatory, even if the string is
4770 4770 ; known to be shorter.
4771 4771 ;
4772 4772 ; DS:SI -> input mangled file name
4773 4773 ; ES:DI -> output buffer
4774 4774 ;
4775 4775 ; On return, DI points to the first byte after the output name,
4776 4776 ; which is set to a null byte.
4777 4777 ;
4778 4778 00001699 E80A0B unmangle_name: call strcpy
4779 4779 0000169C 4F dec di ; Point to final null byte
4780 4780 0000169D C3 ret
4781 4781
4782 4782 ;
4783 4783 ; getfssec: Get multiple clusters from a file, given the file pointer.
4784 4784 ;
4785 4785 ; On entry:
4786 4786 ; ES:BX -> Buffer
4787 4787 ; SI -> File pointer
4788 4788 ; CX -> Cluster count
4789 4789 ; On exit:
4790 4790 ; SI -> File pointer (or 0 on EOF)
4791 4791 ; CF = 1 -> Hit EOF
4792 4792 ;
4793 4793 getfssec:
4794 4794 TRACER 'F'
4795 4795
4796 4796 0000169E 1E push ds
4797 4797 0000169F 0E push cs
4798 4798 000016A0 1F pop ds ; DS <- CS
4799 4799
4800 4800 000016A1 660FB7C9 movzx ecx,cx
4801 4801 000016A5 663B4C04 cmp ecx,[si+file_left]
4802 4802 000016A9 7604 jna .ok_size
4803 4803 000016AB 668B4C04 mov ecx,[si+file_left]
4804 4804 .ok_size:
4805 4805
4806 4806 000016AF 89CD mov bp,cx
4807 4807 000016B1 51 push cx
4808 4808 000016B2 56 push si
4809 4809 000016B3 668B04 mov eax,[si+file_sector]
4810 4810 TRACER 'l'
4811 4811 000016B6 E893EB call getlinsec
4812 4812 000016B9 6631C9 xor ecx,ecx
4813 4813 000016BC 5E pop si
4814 4814 000016BD 59 pop cx
4815 4815
4816 4816 000016BE 66010C add [si+file_sector],ecx
4817 4817 000016C1 66294C04 sub [si+file_left],ecx
4818 4818 000016C5 7709 ja .not_eof ; CF = 0
4819 4819
4820 4820 000016C7 6631C9 xor ecx,ecx
4821 4821 000016CA 66890C mov [si+file_sector],ecx ; Mark as unused
4822 4822 000016CD 31F6 xor si,si
4823 4823 000016CF F9 stc
4824 4824
4825 4825 .not_eof:
4826 4826 000016D0 1F pop ds
4827 4827 TRACER 'f'
4828 4828 000016D1 C3 ret
4829 4829
4830 4830 ; -----------------------------------------------------------------------------
4831 4831 ; Common modules
4832 4832 ; -----------------------------------------------------------------------------
4833 4833
4834 4834 %include "getc.inc" ; getc et al
4835 4835 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
4836 4836 <1> ;; -----------------------------------------------------------------------
4837 4837 <1> ;;
4838 4838 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
4839 4839 <1> ;;
4840 4840 <1> ;; This program is free software; you can redistribute it and/or modify
4841 4841 <1> ;; it under the terms of the GNU General Public License as published by
4842 4842 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
4843 4843 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
4844 4844 <1> ;; (at your option) any later version; incorporated herein by reference.
4845 4845 <1> ;;
4846 4846 <1> ;; -----------------------------------------------------------------------
4847 4847 <1>
4848 4848 <1> ;;
4849 4849 <1> ;; getc.inc
4850 4850 <1> ;;
4851 4851 <1> ;; Simple file handling library (open, getc, ungetc)
4852 4852 <1> ;;
4853 4853 <1>
4854 4854 <1> ;
4855 4855 <1> ; open,getc: Load a file a character at a time for parsing in a manner
4856 4856 <1> ; similar to the C library getc routine. Only one simultaneous
4857 4857 <1> ; use is supported. Note: "open" trashes the trackbuf.
4858 4858 <1> ;
4859 4859 <1> ; open: Input: mangled filename in DS:DI
4860 4860 <1> ; Output: ZF set on file not found or zero length
4861 4861 <1> ;
4862 4862 <1> ; openfd: Input: file handle in SI
4863 4863 <1> ; Output: none
4864 4864 <1> ;
4865 4865 <1> ; getc: Output: CF set on end of file
4866 4866 <1> ; Character loaded in AL
4867 4867 <1> ;
4868 4868 <1> open:
4869 4869 000016D2 E859FE <1> call searchdir
4870 4870 000016D5 7425 <1> jz openfd.ret
4871 4871 <1> openfd:
4872 4872 000016D7 9C <1> pushf
4873 4873 000016D8 A3[4003] <1> mov [FBytes],ax
4874 4874 000016DB 8916[4203] <1> mov [FBytes+2],dx
4875 4875 000016DF 66A1[4003] <1> mov eax,[FBytes]
4876 4876 000016E3 6605FF070000 <1> add eax,SECTOR_SIZE-1
4877 4877 000016E9 66C1E80B <1> shr eax,SECTOR_SHIFT
4878 4878 000016ED 66A3[4403] <1> mov [FSectors],eax ; Number of sectors
4879 4879 000016F1 8936[4803] <1> mov [FNextClust],si ; Cluster pointer
4880 4880 000016F5 A1[4A05] <1> mov ax,[EndOfGetCBuf] ; Pointer at end of buffer ->
4881 4881 000016F8 A3[4A03] <1> mov [FPtr],ax ; nothing loaded yet
4882 4882 000016FB 9D <1> popf ; Restore no ZF
4883 4883 000016FC C3 <1> .ret: ret
4884 4884 <1>
4885 4885 <1> getc:
4886 4886 000016FD F9 <1> stc ; If we exit here -> EOF
4887 4887 000016FE 668B0E[4003] <1> mov ecx,[FBytes]
4888 4888 00001703 67E33F <1> jecxz .ret
4889 4889 00001706 8B36[4A03] <1> mov si,[FPtr]
4890 4890 0000170A 3B36[4A05] <1> cmp si,[EndOfGetCBuf]
4891 4891 0000170E 722A <1> jb .loaded
4892 4892 <1> ; Buffer empty -- load another set
4893 4893 00001710 668B0E[4403] <1> mov ecx,[FSectors]
4894 4894 00001715 6683F904 <1> cmp ecx,trackbufsize >> SECTOR_SHIFT
4895 4895 00001719 7606 <1> jna .oksize
4896 4896 0000171B 66B904000000 <1> mov ecx,trackbufsize >> SECTOR_SHIFT
4897 4897 00001721 66290E[4403] <1> .oksize: sub [FSectors],ecx ; Reduce remaining clusters
4898 4898 00001726 8B36[4803] <1> mov si,[FNextClust]
4899 4899 0000172A 06 <1> push es ; ES may be != DS, save old ES
4900 4900 0000172B 1E <1> push ds
4901 4901 0000172C 07 <1> pop es
4902 4902 0000172D BB[0020] <1> mov bx,getcbuf
4903 4903 00001730 53 <1> push bx
4904 4904 00001731 E86AFF <1> call getfssec ; Load a trackbuf full of data
4905 4905 00001734 8936[4803] <1> mov [FNextClust],si ; Store new next pointer
4906 4906 00001738 5E <1> pop si ; SI -> newly loaded data
4907 4907 00001739 07 <1> pop es ; Restore ES
4908 4908 0000173A AC <1> .loaded: lodsb ; Load a byte, increment SI
4909 4909 0000173B 8936[4A03] <1> mov [FPtr],si ; Update next byte pointer
4910 4910 0000173F 66FF0E[4003] <1> dec dword [FBytes] ; Update bytes left counter
4911 4911 00001744 F8 <1> clc ; Not EOF
4912 4912 00001745 C3 <1> .ret: ret
4913 4913 <1>
4914 4914 <1> ;
4915 4915 <1> ; ungetc: Push a character (in AL) back into the getc buffer
4916 4916 <1> ; Note: if more than one byte is pushed back, this may cause
4917 4917 <1> ; bytes to be written below the getc buffer boundary. If there
4918 4918 <1> ; is a risk for this to occur, the getcbuf base address should
4919 4919 <1> ; be moved up.
4920 4920 <1> ;
4921 4921 <1> ungetc:
4922 4922 00001746 8B36[4A03] <1> mov si,[FPtr]
4923 4923 0000174A 4E <1> dec si
4924 4924 0000174B 8804 <1> mov [si],al
4925 4925 0000174D 8936[4A03] <1> mov [FPtr],si
4926 4926 00001751 66FF06[4003] <1> inc dword [FBytes]
4927 4927 00001756 C3 <1> ret
4928 4928 <1>
4929 4929 <1> ;
4930 4930 <1> ; skipspace: Skip leading whitespace using "getc". If we hit end-of-line
4931 4931 <1> ; or end-of-file, return with carry set; ZF = true of EOF
4932 4932 <1> ; ZF = false for EOLN; otherwise CF = ZF = 0.
4933 4933 <1> ;
4934 4934 <1> ; Otherwise AL = first character after whitespace
4935 4935 <1> ;
4936 4936 <1> skipspace:
4937 4937 00001757 E8A3FF <1> .loop: call getc
4938 4938 0000175A 720D <1> jc .eof
4939 4939 0000175C 3C1A <1> cmp al,1Ah ; DOS EOF
4940 4940 0000175E 7409 <1> je .eof
4941 4941 00001760 3C0A <1> cmp al,0Ah
4942 4942 00001762 7409 <1> je .eoln
4943 4943 00001764 3C20 <1> cmp al,' '
4944 4944 00001766 76EF <1> jbe .loop
4945 4945 00001768 C3 <1> ret ; CF = ZF = 0
4946 4946 00001769 38C0 <1> .eof: cmp al,al ; Set ZF
4947 4947 0000176B F9 <1> stc ; Set CF
4948 4948 0000176C C3 <1> ret
4949 4949 0000176D 04FF <1> .eoln: add al,0FFh ; Set CF, clear ZF
4950 4950 0000176F C3 <1> ret
4951 4951 <1>
4952 4952 <1> ;
4953 4953 <1> ; getint: Load an integer from the getc file.
4954 4954 <1> ; Return CF if error; otherwise return integer in EBX
4955 4955 <1> ;
4956 4956 <1> getint:
4957 4957 00001770 BF[3003] <1> mov di,NumBuf
4958 4958 00001773 81FF[3F03] <1> .getnum: cmp di,NumBufEnd ; Last byte in NumBuf
4959 4959 00001777 730F <1> jae .loaded
4960 4960 00001779 57 <1> push di
4961 4961 0000177A E880FF <1> call getc
4962 4962 0000177D 5F <1> pop di
4963 4963 0000177E 7208 <1> jc .loaded
4964 4964 00001780 AA <1> stosb
4965 4965 00001781 3C2D <1> cmp al,'-'
4966 4966 00001783 73EE <1> jnb .getnum
4967 4967 00001785 E8BEFF <1> call ungetc ; Unget non-numeric
4968 4968 00001788 C60500 <1> .loaded: mov byte [di],0
4969 4969 0000178B BE[3003] <1> mov si,NumBuf
4970 4970 <1> ; Fall through to parseint
4971 4971 <1>
4972 4972 <1> ;
4973 4973 <1> ; parseint: Convert an integer to a number in EBX
4974 4974 <1> ; Get characters from string in DS:SI
4975 4975 <1> ; Return CF on error
4976 4976 <1> ; DS:SI points to first character after number
4977 4977 <1> ;
4978 4978 <1> ; Syntaxes accepted: [-]dec, [-]0+oct, [-]0x+hex, val+K, val+M
4979 4979 <1> ;
4980 4980 <1> parseint:
4981 4981 0000178E 6650 <1> push eax
4982 4982 00001790 6651 <1> push ecx
4983 4983 00001792 55 <1> push bp
4984 4984 00001793 6631C0 <1> xor eax,eax ; Current digit (keep eax == al)
4985 4985 00001796 6689C3 <1> mov ebx,eax ; Accumulator
4986 4986 00001799 6689D9 <1> mov ecx,ebx ; Base
4987 4987 0000179C 31ED <1> xor bp,bp ; Used for negative flag
4988 4988 0000179E AC <1> .begin: lodsb
4989 4989 0000179F 3C2D <1> cmp al,'-'
4990 4990 000017A1 7505 <1> jne .not_minus
4991 4991 000017A3 83F501 <1> xor bp,1 ; Set unary minus flag
4992 4992 000017A6 EBF6 <1> jmp short .begin
4993 4993 <1> .not_minus:
4994 4994 000017A8 3C30 <1> cmp al,'0'
4995 4995 000017AA 724F <1> jb .err
4996 4996 000017AC 7408 <1> je .octhex
4997 4997 000017AE 3C39 <1> cmp al,'9'
4998 4998 000017B0 7749 <1> ja .err
4999 4999 000017B2 B10A <1> mov cl,10 ; Base = decimal
5000 5000 000017B4 EB17 <1> jmp short .foundbase
5001 5001 <1> .octhex:
5002 5002 000017B6 AC <1> lodsb
5003 5003 000017B7 3C30 <1> cmp al,'0'
5004 5004 000017B9 7225 <1> jb .km ; Value is zero
5005 5005 000017BB 0C20 <1> or al,20h ; Downcase
5006 5006 000017BD 3C78 <1> cmp al,'x'
5007 5007 000017BF 7408 <1> je .ishex
5008 5008 000017C1 3C37 <1> cmp al,'7'
5009 5009 000017C3 7736 <1> ja .err
5010 5010 000017C5 B108 <1> mov cl,8 ; Base = octal
5011 5011 000017C7 EB04 <1> jmp short .foundbase
5012 5012 <1> .ishex:
5013 5013 000017C9 B030 <1> mov al,'0' ; No numeric value accrued yet
5014 5014 000017CB B110 <1> mov cl,16 ; Base = hex
5015 5015 <1> .foundbase:
5016 5016 000017CD E83A00 <1> call unhexchar
5017 5017 000017D0 720E <1> jc .km ; Not a (hex) digit
5018 5018 000017D2 38C8 <1> cmp al,cl
5019 5019 000017D4 730A <1> jae .km ; Invalid for base
5020 5020 000017D6 660FAFD9 <1> imul ebx,ecx ; Multiply accumulated by base
5021 5021 000017DA 6601C3 <1> add ebx,eax ; Add current digit
5022 5022 000017DD AC <1> lodsb
5023 5023 000017DE EBED <1> jmp short .foundbase
5024 5024 <1> .km:
5025 5025 000017E0 4E <1> dec si ; Back up to last non-numeric
5026 5026 000017E1 AC <1> lodsb
5027 5027 000017E2 0C20 <1> or al,20h
5028 5028 000017E4 3C6B <1> cmp al,'k'
5029 5029 000017E6 7416 <1> je .isk
5030 5030 000017E8 3C6D <1> cmp al,'m'
5031 5031 000017EA 7418 <1> je .ism
5032 5032 000017EC 4E <1> dec si ; Back up
5033 5033 000017ED 21ED <1> .fini: and bp,bp
5034 5034 000017EF 7404 <1> jz .ret ; CF=0!
5035 5035 000017F1 66F7DB <1> neg ebx ; Value was negative
5036 5036 000017F4 F8 <1> .done: clc
5037 5037 000017F5 5D <1> .ret: pop bp
5038 5038 000017F6 6659 <1> pop ecx
5039 5039 000017F8 6658 <1> pop eax
5040 5040 000017FA C3 <1> ret
5041 5041 000017FB F9 <1> .err: stc
5042 5042 000017FC EBF7 <1> jmp short .ret
5043 5043 000017FE 66C1E30A <1> .isk: shl ebx,10 ; x 2^10
5044 5044 00001802 EBF0 <1> jmp short .done
5045 5045 00001804 66C1E314 <1> .ism: shl ebx,20 ; x 2^20
5046 5046 00001808 EBEA <1> jmp short .done
5047 5047 <1>
5048 5048 <1>
5049 5049 <1> section .bss
5050 5050 0000032E <res 00000001>- <1> alignb 4
5051 5051 0000032E <rept> <1>
5052 5052 00000330 <res 0000000F> <1> NumBuf resb 15 ; Buffer to load number
5053 5053 0000033F <res 00000001> <1> NumBufEnd resb 1 ; Last byte in NumBuf
5054 5054 00000340 <res 00000004> <1> FBytes resd 1 ; Number of bytes left in getc file
5055 5055 00000344 <res 00000004> <1> FSectors resd 1 ; Number of sectors in getc file
5056 5056 00000348 <res 00000002> <1> FNextClust resw 1 ; Pointer to next cluster in d:o
5057 5057 0000034A <res 00000002> <1> FPtr resw 1 ; Pointer to next char in buffer
5058 5058 <1>
5059 5059 <1> ;
5060 5060 <1> ; unhexchar: Convert a hexadecimal digit in AL to the equivalent number;
5061 5061 <1> ; return CF=1 if not a hex digit
5062 5062 <1> ;
5063 5063 <1> section .text
5064 5064 <1> unhexchar:
5065 5065 0000180A 3C30 <1> cmp al,'0'
5066 5066 0000180C 7215 <1> jb .ret ; If failure, CF == 1 already
5067 5067 0000180E 3C39 <1> cmp al,'9'
5068 5068 00001810 7703 <1> ja .notdigit
5069 5069 00001812 2C30 <1> sub al,'0' ; CF <- 0
5070 5070 00001814 C3 <1> ret
5071 5071 00001815 0C20 <1> .notdigit: or al,20h ; upper case -> lower case
5072 5072 00001817 3C61 <1> cmp al,'a'
5073 5073 00001819 7208 <1> jb .ret ; If failure, CF == 1 already
5074 5074 0000181B 3C66 <1> cmp al,'f'
5075 5075 0000181D 7703 <1> ja .err
5076 5076 0000181F 2C57 <1> sub al,'a'-10 ; CF <- 0
5077 5077 00001821 C3 <1> ret
5078 5078 00001822 F9 <1> .err: stc
5079 5079 00001823 C3 <1> .ret: ret
5080 5080 <1>
5081 5081 <1> ;
5082 5082 <1> ;
5083 5083 <1> ; getline: Get a command line, converting control characters to spaces
5084 5084 <1> ; and collapsing streches to one; a space is appended to the
5085 5085 <1> ; end of the string, unless the line is empty.
5086 5086 <1> ; The line is terminated by ^J, ^Z or EOF and is written
5087 5087 <1> ; to ES:DI. On return, DI points to first char after string.
5088 5088 <1> ; CF is set if we hit EOF.
5089 5089 <1> ;
5090 5090 <1> getline:
5091 5091 00001824 E830FF <1> call skipspace
5092 5092 00001827 B201 <1> mov dl,1 ; Empty line -> empty string.
5093 5093 00001829 742B <1> jz .eof ; eof
5094 5094 0000182B 7226 <1> jc .eoln ; eoln
5095 5095 0000182D E816FF <1> call ungetc
5096 5096 00001830 52 <1> .fillloop: push dx
5097 5097 00001831 57 <1> push di
5098 5098 00001832 E8C8FE <1> call getc
5099 5099 00001835 5F <1> pop di
5100 5100 00001836 5A <1> pop dx
5101 5101 00001837 721E <1> jc .ret ; CF set!
5102 5102 00001839 3C20 <1> cmp al,' '
5103 5103 0000183B 7605 <1> jna .ctrl
5104 5104 0000183D 31D2 <1> xor dx,dx
5105 5105 0000183F AA <1> .store: stosb
5106 5106 00001840 EBEE <1> jmp short .fillloop
5107 5107 00001842 3C0A <1> .ctrl: cmp al,10
5108 5108 00001844 7411 <1> je .ret ; CF clear!
5109 5109 00001846 3C1A <1> cmp al,26
5110 5110 00001848 740C <1> je .eof
5111 5111 0000184A 20D2 <1> and dl,dl
5112 5112 0000184C 75E2 <1> jnz .fillloop ; Ignore multiple spaces
5113 5113 0000184E B020 <1> mov al,' ' ; Ctrl -> space
5114 5114 00001850 42 <1> inc dx
5115 5115 00001851 EBEC <1> jmp short .store
5116 5116 00001853 F8 <1> .eoln: clc ; End of line is not end of file
5117 5117 00001854 EB01 <1> jmp short .ret
5118 5118 00001856 F9 <1> .eof: stc
5119 5119 00001857 9C <1> .ret: pushf ; We want the last char to be space!
5120 5120 00001858 20D2 <1> and dl,dl
5121 5121 0000185A 7503 <1> jnz .xret
5122 5122 0000185C B020 <1> mov al,' '
5123 5123 0000185E AA <1> stosb
5124 5124 0000185F 9D <1> .xret: popf
5125 5125 00001860 C3 <1> ret
5126 5126 %include "conio.inc" ; Console I/O
5127 5127 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
5128 5128 <1> ;; -----------------------------------------------------------------------
5129 5129 <1> ;;
5130 5130 <1> ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
5131 5131 <1> ;;
5132 5132 <1> ;; This program is free software; you can redistribute it and/or modify
5133 5133 <1> ;; it under the terms of the GNU General Public License as published by
5134 5134 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
5135 5135 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
5136 5136 <1> ;; (at your option) any later version; incorporated herein by reference.
5137 5137 <1> ;;
5138 5138 <1> ;; -----------------------------------------------------------------------
5139 5139 <1>
5140 5140 <1> ;;
5141 5141 <1> ;; conio.inc
5142 5142 <1> ;;
5143 5143 <1> ;; Console I/O code, except:
5144 5144 <1> ;; writechr, writestr - module-dependent
5145 5145 <1> ;; cwritestr, crlf - writestr.inc
5146 5146 <1> ;; writehex* - writehex.inc
5147 5147 <1> ;;
5148 5148 <1>
5149 5149 <1> ;
5150 5150 <1> ; loadkeys: Load a LILO-style keymap; SI and DX:AX set by searchdir
5151 5151 <1> ;
5152 5152 <1> section .text
5153 5153 <1>
5154 5154 <1> loadkeys:
5155 5155 00001861 21D2 <1> and dx,dx ; Should be 256 bytes exactly
5156 5156 00001863 751A <1> jne loadkeys_ret
5157 5157 00001865 3D0001 <1> cmp ax,256
5158 5158 00001868 7515 <1> jne loadkeys_ret
5159 5159 <1>
5160 5160 0000186A BB[0000] <1> mov bx,trackbuf
5161 5161 0000186D B90100 <1> mov cx,1 ; 1 cluster should be >= 256 bytes
5162 5162 00001870 E82BFE <1> call getfssec
5163 5163 <1>
5164 5164 00001873 BE[0000] <1> mov si,trackbuf
5165 5165 00001876 BF[080E] <1> mov di,KbdMap
5166 5166 00001879 B94000 <1> mov cx,256 >> 2
5167 5167 0000187C F366A5 <1> rep movsd
5168 5168 <1>
5169 5169 0000187F C3 <1> loadkeys_ret: ret
5170 5170 <1>
5171 5171 <1> ;
5172 5172 <1> ; get_msg_file: Load a text file and write its contents to the screen,
5173 5173 <1> ; interpreting color codes. Is called with SI and DX:AX
5174 5174 <1> ; set by routine searchdir
5175 5175 <1> ;
5176 5176 <1> get_msg_file:
5177 5177 00001880 06 <1> push es
5178 5178 00001881 66C1E210 <1> shl edx,16 ; EDX <- DX:AX (length of file)
5179 5179 00001885 89C2 <1> mov dx,ax
5180 5180 00001887 B80010 <1> mov ax,xfer_buf_seg ; Use for temporary storage
5181 5181 0000188A 8EC0 <1> mov es,ax
5182 5182 <1>
5183 5183 0000188C C606[5703]07 <1> mov byte [TextAttribute],07h ; Default grey on white
5184 5184 00001891 C606[5803]07 <1> mov byte [DisplayMask],07h ; Display text in all modes
5185 5185 00001896 E88001 <1> call msg_initvars
5186 5186 <1>
5187 5187 00001899 6652 <1> get_msg_chunk: push edx ; EDX = length of file
5188 5188 0000189B 31DB <1> xor bx,bx ; == xbs_textbuf
5189 5189 0000189D 8B0E[4405] <1> mov cx,[BufSafe]
5190 5190 000018A1 E8FAFD <1> call getfssec
5191 5191 000018A4 665A <1> pop edx
5192 5192 000018A6 56 <1> push si ; Save current cluster
5193 5193 000018A7 31F6 <1> xor si,si ; == xbs_textbuf
5194 5194 000018A9 8B0E[4805] <1> mov cx,[BufSafeBytes] ; Number of bytes left in chunk
5195 5195 <1> print_msg_file:
5196 5196 000018AD 51 <1> push cx
5197 5197 000018AE 6652 <1> push edx
5198 5198 000018B0 26AC <1> es lodsb
5199 5199 000018B2 3C1A <1> cmp al,1Ah ; DOS EOF?
5200 5200 000018B4 7418 <1> je msg_done_pop
5201 5201 000018B6 56 <1> push si
5202 5202 000018B7 8A0E[CE00] <1> mov cl,[UsingVGA]
5203 5203 000018BB FEC1 <1> inc cl ; 01h = text mode, 02h = graphics
5204 5204 000018BD FF16[4C03] <1> call [NextCharJump] ; Do what shall be done
5205 5205 000018C1 5E <1> pop si
5206 5206 000018C2 665A <1> pop edx
5207 5207 000018C4 59 <1> pop cx
5208 5208 000018C5 664A <1> dec edx
5209 5209 000018C7 7408 <1> jz msg_done
5210 5210 000018C9 E2E2 <1> loop print_msg_file
5211 5211 000018CB 5E <1> pop si
5212 5212 000018CC EBCB <1> jmp short get_msg_chunk
5213 5213 <1> msg_done_pop:
5214 5214 000018CE 83C406 <1> add sp,byte 6 ; Drop pushed EDX, CX
5215 5215 <1> msg_done:
5216 5216 000018D1 5E <1> pop si
5217 5217 000018D2 07 <1> pop es
5218 5218 000018D3 C3 <1> ret
5219 5219 <1> msg_putchar: ; Normal character
5220 5220 000018D4 3C0F <1> cmp al,0Fh ; ^O = color code follows
5221 5221 000018D6 7467 <1> je msg_ctrl_o
5222 5222 000018D8 3C0D <1> cmp al,0Dh ; Ignore <CR>
5223 5223 000018DA 745A <1> je msg_ignore
5224 5224 000018DC 3C0A <1> cmp al,0Ah ; <LF> = newline
5225 5225 000018DE 7466 <1> je msg_newline
5226 5226 000018E0 3C0C <1> cmp al,0Ch ; <FF> = clear screen
5227 5227 000018E2 0F849500 <1> je msg_formfeed
5228 5228 000018E6 3C07 <1> cmp al,07h ; <BEL> = beep
5229 5229 000018E8 744D <1> je msg_beep
5230 5230 000018EA 3C19 <1> cmp al,19h ; <EM> = return to text mode
5231 5231 000018EC 0F840601 <1> je msg_novga
5232 5232 000018F0 3C18 <1> cmp al,18h ; <CAN> = VGA filename follows
5233 5233 000018F2 0F84CF00 <1> je msg_vga
5234 5234 000018F6 7306 <1> jnb .not_modectl
5235 5235 000018F8 3C10 <1> cmp al,10h ; 10h to 17h are mode controls
5236 5236 000018FA 0F832B01 <1> jae msg_modectl
5237 5237 <1> .not_modectl:
5238 5238 <1>
5239 5239 000018FE E82F01 <1> msg_normal: call write_serial_displaymask ; Write to serial port
5240 5240 00001901 840E[5803] <1> test [DisplayMask],cl
5241 5241 00001905 742F <1> jz msg_ignore ; Not screen
5242 5242 00001907 F606[7200]01 <1> test byte [DisplayCon],01h
5243 5243 0000190C 7428 <1> jz msg_ignore
5244 5244 0000190E 8A1E[5703] <1> mov bl,[TextAttribute]
5245 5245 00001912 8A3E6204 <1> mov bh,[BIOS_page]
5246 5246 00001916 B409 <1> mov ah,09h ; Write character/attribute
5247 5247 00001918 B90100 <1> mov cx,1 ; One character only
5248 5248 0000191B CD10 <1> int 10h ; Write to screen
5249 5249 0000191D A0[4E03] <1> mov al,[CursorCol]
5250 5250 00001920 40 <1> inc ax
5251 5251 00001921 3A06[5003] <1> cmp al,[VidCols]
5252 5252 00001925 7725 <1> ja msg_line_wrap ; Screen wraparound
5253 5253 00001927 A2[4E03] <1> mov [CursorCol],al
5254 5254 <1>
5255 5255 0000192A 8A3E6204 <1> msg_gotoxy: mov bh,[BIOS_page]
5256 5256 0000192E 8B16[4E03] <1> mov dx,[CursorDX]
5257 5257 00001932 B402 <1> mov ah,02h ; Set cursor position
5258 5258 00001934 CD10 <1> int 10h
5259 5259 00001936 C3 <1> msg_ignore: ret
5260 5260 <1>
5261 5261 00001937 B8070E <1> msg_beep: mov ax,0E07h ; Beep
5262 5262 0000193A 31DB <1> xor bx,bx
5263 5263 0000193C CD10 <1> int 10h
5264 5264 0000193E C3 <1> ret
5265 5265 <1>
5266 5266 <1> msg_ctrl_o: ; ^O = color code follows
5267 5267 0000193F C706[4C03][9C19] <1> mov word [NextCharJump],msg_setbg
5268 5268 00001945 C3 <1> ret
5269 5269 <1> msg_newline: ; Newline char or end of line
5270 5270 00001946 BE[C905] <1> mov si,crlf_msg
5271 5271 00001949 E81701 <1> call write_serial_str_displaymask
5272 5272 <1> msg_line_wrap: ; Screen wraparound
5273 5273 0000194C 840E[5803] <1> test [DisplayMask],cl
5274 5274 00001950 74E4 <1> jz msg_ignore
5275 5275 00001952 C606[4E03]00 <1> mov byte [CursorCol],0
5276 5276 00001957 A0[4F03] <1> mov al,[CursorRow]
5277 5277 0000195A 40 <1> inc ax
5278 5278 0000195B 3A06[5103] <1> cmp al,[VidRows]
5279 5279 0000195F 7705 <1> ja msg_scroll
5280 5280 00001961 A2[4F03] <1> mov [CursorRow],al
5281 5281 00001964 EBC4 <1> jmp short msg_gotoxy
5282 5282 00001966 31C9 <1> msg_scroll: xor cx,cx ; Upper left hand corner
5283 5283 00001968 8B16[5003] <1> mov dx,[ScreenSize]
5284 5284 0000196C 8836[4F03] <1> mov [CursorRow],dh ; New cursor at the bottom
5285 5285 00001970 8A3E[7400] <1> mov bh,[ScrollAttribute]
5286 5286 00001974 B80106 <1> mov ax,0601h ; Scroll up one line
5287 5287 00001977 CD10 <1> int 10h
5288 5288 00001979 EBAF <1> jmp short msg_gotoxy
5289 5289 <1> msg_formfeed: ; Form feed character
5290 5290 0000197B BE[C103] <1> mov si,crff_msg
5291 5291 0000197E E8E200 <1> call write_serial_str_displaymask
5292 5292 00001981 840E[5803] <1> test [DisplayMask],cl
5293 5293 00001985 74AF <1> jz msg_ignore
5294 5294 00001987 31C9 <1> xor cx,cx
5295 5295 00001989 890E[4E03] <1> mov [CursorDX],cx ; Upper lefthand corner
5296 5296 0000198D 8B16[5003] <1> mov dx,[ScreenSize]
5297 5297 00001991 8A3E[5703] <1> mov bh,[TextAttribute]
5298 5298 00001995 B80006 <1> mov ax,0600h ; Clear screen region
5299 5299 00001998 CD10 <1> int 10h
5300 5300 0000199A EB8E <1> jmp msg_gotoxy
5301 5301 <1> msg_setbg: ; Color background character
5302 5302 0000199C E86BFE <1> call unhexchar
5303 5303 0000199F 722F <1> jc msg_color_bad
5304 5304 000019A1 C0E004 <1> shl al,4
5305 5305 000019A4 840E[5803] <1> test [DisplayMask],cl
5306 5306 000019A8 7403 <1> jz .dontset
5307 5307 000019AA A2[5703] <1> mov [TextAttribute],al
5308 5308 <1> .dontset:
5309 5309 000019AD C706[4C03][B419] <1> mov word [NextCharJump],msg_setfg
5310 5310 000019B3 C3 <1> ret
5311 5311 <1> msg_setfg: ; Color foreground character
5312 5312 000019B4 E853FE <1> call unhexchar
5313 5313 000019B7 7217 <1> jc msg_color_bad
5314 5314 000019B9 840E[5803] <1> test [DisplayMask],cl
5315 5315 000019BD 7404 <1> jz .dontset
5316 5316 000019BF 0806[5703] <1> or [TextAttribute],al ; setbg set foreground to 0
5317 5317 <1> .dontset:
5318 5318 000019C3 EB10 <1> jmp short msg_putcharnext
5319 5319 <1> msg_vga:
5320 5320 000019C5 C706[4C03][DC19] <1> mov word [NextCharJump],msg_filename
5321 5321 000019CB BF[253E] <1> mov di, VGAFileBuf
5322 5322 000019CE EB21 <1> jmp short msg_setvgafileptr
5323 5323 <1>
5324 5324 <1> msg_color_bad:
5325 5325 000019D0 C606[5703]07 <1> mov byte [TextAttribute],07h ; Default attribute
5326 5326 <1> msg_putcharnext:
5327 5327 000019D5 C706[4C03][D418] <1> mov word [NextCharJump],msg_putchar
5328 5328 000019DB C3 <1> ret
5329 5329 <1>
5330 5330 <1> msg_filename: ; Getting VGA filename
5331 5331 000019DC 3C0A <1> cmp al,0Ah ; <LF> = end of filename
5332 5332 000019DE 741B <1> je msg_viewimage
5333 5333 000019E0 3C20 <1> cmp al,' '
5334 5334 000019E2 7611 <1> jbe msg_ret ; Ignore space/control char
5335 5335 000019E4 8B3E[123E] <1> mov di,[VGAFilePtr]
5336 5336 000019E8 81FF[253F] <1> cmp di,VGAFileBufEnd
5337 5337 000019EC 7307 <1> jnb msg_ret
5338 5338 000019EE 8805 <1> mov [di],al ; Can't use stosb (DS:)
5339 5339 000019F0 47 <1> inc di
5340 5340 <1> msg_setvgafileptr:
5341 5341 000019F1 893E[123E] <1> mov [VGAFilePtr],di
5342 5342 000019F5 C3 <1> msg_ret: ret
5343 5343 <1>
5344 5344 <1> msg_novga:
5345 5345 000019F6 E87606 <1> call vgaclearmode
5346 5346 000019F9 EB1E <1> jmp short msg_initvars
5347 5347 <1>
5348 5348 <1> msg_viewimage:
5349 5349 000019FB 06 <1> push es
5350 5350 000019FC 1E <1> push ds
5351 5351 000019FD 07 <1> pop es ; ES <- DS
5352 5352 000019FE 8B36[123E] <1> mov si,[VGAFilePtr]
5353 5353 00001A02 C60400 <1> mov byte [si],0 ; Zero-terminate filename
5354 5354 00001A05 BE[253E] <1> mov si,VGAFileBuf
5355 5355 00001A08 BF[253F] <1> mov di,VGAFileMBuf
5356 5356 00001A0B 57 <1> push di
5357 5357 00001A0C E853FC <1> call mangle_name
5358 5358 00001A0F 5F <1> pop di
5359 5359 00001A10 E81BFB <1> call searchdir
5360 5360 00001A13 07 <1> pop es
5361 5361 00001A14 74BF <1> jz msg_putcharnext ; Not there
5362 5362 00001A16 E8D004 <1> call vgadisplayfile
5363 5363 <1> ; Fall through
5364 5364 <1>
5365 5365 <1> ; Subroutine to initialize variables, also needed
5366 5366 <1> ; after loading a graphics file
5367 5367 <1> msg_initvars:
5368 5368 00001A19 60 <1> pusha
5369 5369 00001A1A 8A3E6204 <1> mov bh,[BIOS_page]
5370 5370 00001A1E B403 <1> mov ah,03h ; Read cursor position
5371 5371 00001A20 CD10 <1> int 10h
5372 5372 00001A22 8916[4E03] <1> mov [CursorDX],dx
5373 5373 00001A26 61 <1> popa
5374 5374 00001A27 EBAC <1> jmp short msg_putcharnext ; Initialize state machine
5375 5375 <1>
5376 5376 <1> msg_modectl:
5377 5377 00001A29 2407 <1> and al,07h
5378 5378 00001A2B A2[5803] <1> mov [DisplayMask],al
5379 5379 00001A2E EBA5 <1> jmp short msg_putcharnext
5380 5380 <1>
5381 5381 <1> ;
5382 5382 <1> ; write_serial: If serial output is enabled, write character on serial port
5383 5383 <1> ; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0
5384 5384 <1> ;
5385 5385 <1> write_serial_displaymask:
5386 5386 00001A30 F606[5803]04 <1> test byte [DisplayMask], 04h
5387 5387 00001A35 742B <1> jz write_serial.end
5388 5388 <1> write_serial:
5389 5389 00001A37 669C <1> pushfd
5390 5390 00001A39 6660 <1> pushad
5391 5391 00001A3B 8B1E[B400] <1> mov bx,[SerialPort]
5392 5392 00001A3F 21DB <1> and bx,bx
5393 5393 00001A41 741B <1> je .noserial
5394 5394 00001A43 50 <1> push ax
5395 5395 00001A44 8A26[5503] <1> mov ah,[FlowInput]
5396 5396 <1> .waitspace:
5397 5397 <1> ; Wait for space in transmit register
5398 5398 00001A48 8D5705 <1> lea dx,[bx+5] ; DX -> LSR
5399 5399 00001A4B EC <1> in al,dx
5400 5400 00001A4C A820 <1> test al,20h
5401 5401 00001A4E 74F8 <1> jz .waitspace
5402 5402 <1>
5403 5403 <1> ; Wait for input flow control
5404 5404 00001A50 42 <1> inc dx ; DX -> MSR
5405 5405 00001A51 EC <1> in al,dx
5406 5406 00001A52 20E0 <1> and al,ah
5407 5407 00001A54 38E0 <1> cmp al,ah
5408 5408 00001A56 75F0 <1> jne .waitspace
5409 5409 <1> .no_flow:
5410 5410 <1>
5411 5411 00001A58 87D3 <1> xchg dx,bx ; DX -> THR
5412 5412 00001A5A 58 <1> pop ax
5413 5413 00001A5B E8(C600) <1> call slow_out ; Send data
5414 5414 00001A5E 6661 <1> .noserial: popad
5415 5415 00001A60 669D <1> popfd
5416 5416 00001A62 C3 <1> .end: ret
5417 5417 <1>
5418 5418 <1> ;
5419 5419 <1> ; write_serial_str: write_serial for strings
5420 5420 <1> ; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0
5421 5421 <1> ;
5422 5422 <1> write_serial_str_displaymask:
5423 5423 00001A63 F606[5803]04 <1> test byte [DisplayMask], 04h
5424 5424 00001A68 740A <1> jz write_serial_str.end
5425 5425 <1>
5426 5426 <1> write_serial_str:
5427 5427 00001A6A AC <1> .loop lodsb
5428 5428 00001A6B 20C0 <1> and al,al
5429 5429 00001A6D 7405 <1> jz .end
5430 5430 00001A6F E8C5FF <1> call write_serial
5431 5431 00001A72 EBF6 <1> jmp short .loop
5432 5432 00001A74 C3 <1> .end: ret
5433 5433 <1>
5434 5434 <1> ;
5435 5435 <1> ; pollchar: check if we have an input character pending (ZF = 0)
5436 5436 <1> ;
5437 5437 <1> pollchar:
5438 5438 00001A75 6660 <1> pushad
5439 5439 00001A77 B411 <1> mov ah,11h ; Poll keyboard
5440 5440 00001A79 CD16 <1> int 16h
5441 5441 00001A7B 751F <1> jnz .done ; Keyboard response
5442 5442 00001A7D 8B16[B400] <1> mov dx,[SerialPort]
5443 5443 00001A81 21D2 <1> and dx,dx
5444 5444 00001A83 7417 <1> jz .done ; No serial port -> no input
5445 5445 00001A85 83C205 <1> add dx,byte 5 ; DX -> LSR
5446 5446 00001A88 EC <1> in al,dx
5447 5447 00001A89 A801 <1> test al,1 ; ZF = 0 if data pending
5448 5448 00001A8B 740F <1> jz .done
5449 5449 00001A8D 42 <1> inc dx ; DX -> MSR
5450 5450 00001A8E 8A26[5603] <1> mov ah,[FlowIgnore] ; Required status bits
5451 5451 00001A92 EC <1> in al,dx
5452 5452 00001A93 20E0 <1> and al,ah
5453 5453 00001A95 38E0 <1> cmp al,ah
5454 5454 00001A97 0F95C0 <1> setne al
5455 5455 00001A9A FEC8 <1> dec al ; Set ZF = 0 if equal
5456 5456 00001A9C 6661 <1> .done: popad
5457 5457 00001A9E C3 <1> ret
5458 5458 <1>
5459 5459 <1> ;
5460 5460 <1> ; getchar: Read a character from keyboard or serial port
5461 5461 <1> ;
5462 5462 <1> getchar:
5463 5463 <1> RESET_IDLE
5464 5464 <2>
5465 5465 <1> .again:
5466 5466 <1> DO_IDLE
5467 5467 <2>
5468 5468 00001A9F B411 <1> mov ah,11h ; Poll keyboard
5469 5469 00001AA1 CD16 <1> int 16h
5470 5470 00001AA3 7522 <1> jnz .kbd ; Keyboard input?
5471 5471 00001AA5 8B1E[B400] <1> mov bx,[SerialPort]
5472 5472 00001AA9 21DB <1> and bx,bx
5473 5473 00001AAB 74F2 <1> jz .again
5474 5474 00001AAD 8D5705 <1> lea dx,[bx+5] ; DX -> LSR
5475 5475 00001AB0 EC <1> in al,dx
5476 5476 00001AB1 A801 <1> test al,1
5477 5477 00001AB3 74EA <1> jz .again
5478 5478 00001AB5 42 <1> inc dx ; DX -> MSR
5479 5479 00001AB6 8A26[5603] <1> mov ah,[FlowIgnore]
5480 5480 00001ABA EC <1> in al,dx
5481 5481 00001ABB 20E0 <1> and al,ah
5482 5482 00001ABD 38E0 <1> cmp al,ah
5483 5483 00001ABF 75DE <1> jne .again
5484 5484 00001AC1 30E4 <1> .serial: xor ah,ah ; Avoid confusion
5485 5485 00001AC3 87D3 <1> xchg dx,bx ; Data port
5486 5486 00001AC5 EC <1> in al,dx
5487 5487 00001AC6 C3 <1> ret
5488 5488 00001AC7 B410 <1> .kbd: mov ah,10h ; Get keyboard input
5489 5489 00001AC9 CD16 <1> int 16h
5490 5490 00001ACB 3CE0 <1> cmp al,0E0h
5491 5491 00001ACD 7502 <1> jnz .not_ext
5492 5492 00001ACF 30C0 <1> xor al,al
5493 5493 <1> .not_ext:
5494 5494 00001AD1 20C0 <1> and al,al
5495 5495 00001AD3 7404 <1> jz .func_key
5496 5496 00001AD5 BB[080E] <1> mov bx,KbdMap ; Convert character sets
5497 5497 00001AD8 D7 <1> xlatb
5498 5498 00001AD9 C3 <1> .func_key: ret
5499 5499 <1>
5500 5500 <1> %ifdef DEBUG_TRACERS
5501 5501 <1> ;
5502 5502 <1> ; debug hack to print a character with minimal code impact
5503 5503 <1> ;
5504 5504 <1> debug_tracer: pushad
5505 5505 <1> pushfd
5506 5506 <1> mov bp,sp
5507 5507 <1> mov bx,[bp+9*4] ; Get return address
5508 5508 <1> mov al,[cs:bx] ; Get data byte
5509 5509 <1> inc word [bp+9*4] ; Return to after data byte
5510 5510 <1> call writechr
5511 5511 <1> popfd
5512 5512 <1> popad
5513 5513 <1> ret
5514 5514 <1> %endif ; DEBUG_TRACERS
5515 5515 <1>
5516 5516 <1> section .data
5517 5517 <1> ; This is a word to pc_setint16 can set it
5518 5518 00000072 0100 <1> DisplayCon dw 01h ; Console display enabled
5519 5519 <1>
5520 5520 00000074 07 <1> ScrollAttribute db 07h ; Grey on white (normal text color)
5521 5521 <1>
5522 5522 <1> section .bss
5523 5523 <1> alignb 2
5524 5524 0000034C <res 00000002> <1> NextCharJump resw 1 ; Routine to interpret next print char
5525 5525 <1> CursorDX equ $
5526 5526 0000034E <res 00000001> <1> CursorCol resb 1 ; Cursor column for message file
5527 5527 0000034F <res 00000001> <1> CursorRow resb 1 ; Cursor row for message file
5528 5528 <1> ScreenSize equ $
5529 5529 00000350 <res 00000001> <1> VidCols resb 1 ; Columns on screen-1
5530 5530 00000351 <res 00000001> <1> VidRows resb 1 ; Rows on screen-1
5531 5531 <1>
5532 5532 <1> ; Serial console stuff...
5533 5533 00000352 <res 00000002> <1> BaudDivisor resw 1 ; Baud rate divisor
5534 5534 <1> FlowControl equ $
5535 5535 00000354 <res 00000001> <1> FlowOutput resb 1 ; Outputs to assert for serial flow
5536 5536 00000355 <res 00000001> <1> FlowInput resb 1 ; Input bits for serial flow
5537 5537 00000356 <res 00000001> <1> FlowIgnore resb 1 ; Ignore input unless these bits set
5538 5538 <1>
5539 5539 00000357 <res 00000001> <1> TextAttribute resb 1 ; Text attribute for message file
5540 5540 00000358 <res 00000001> <1> DisplayMask resb 1 ; Display modes mask
5541 5541 %include "parseconfig.inc" ; High-level config file handling
5542 5542 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
5543 5543 <1> ;; -----------------------------------------------------------------------
5544 5544 <1> ;;
5545 5545 <1> ;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
5546 5546 <1> ;;
5547 5547 <1> ;; This program is free software; you can redistribute it and/or modify
5548 5548 <1> ;; it under the terms of the GNU General Public License as published by
5549 5549 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
5550 5550 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
5551 5551 <1> ;; (at your option) any later version; incorporated herein by reference.
5552 5552 <1> ;;
5553 5553 <1> ;; -----------------------------------------------------------------------
5554 5554 <1>
5555 5555 <1> ;;
5556 5556 <1> ;; parseconfig.inc
5557 5557 <1> ;;
5558 5558 <1> ;; Configuration file operations
5559 5559 <1> ;;
5560 5560 <1>
5561 5561 <1> section .text
5562 5562 <1> ;
5563 5563 <1> ; "default" command
5564 5564 <1> ;
5565 5565 00001ADA BF[0402] <1> pc_default: mov di,default_cmd
5566 5566 00001ADD E844FD <1> call getline
5567 5567 00001AE0 C645FF00 <1> mov byte [di-1],0 ; null-terminate
5568 5568 00001AE4 C3 <1> ret
5569 5569 <1>
5570 5570 <1> ;
5571 5571 <1> ; "ontimeout" command
5572 5572 <1> ;
5573 5573 00001AE5 BF[080A] <1> pc_ontimeout: mov di,Ontimeout
5574 5574 00001AE8 E839FD <1> call getline
5575 5575 00001AEB 81EF[090A] <1> sub di,Ontimeout+1 ; Don't need final space
5576 5576 00001AEF 893E[A600] <1> mov [OntimeoutLen],di
5577 5577 00001AF3 C3 <1> ret
5578 5578 <1>
5579 5579 <1> ;
5580 5580 <1> ; "onerror" command
5581 5581 <1> ;
5582 5582 00001AF4 BF[080C] <1> pc_onerror: mov di,Onerror
5583 5583 00001AF7 E82AFD <1> call getline
5584 5584 00001AFA 81EF[080C] <1> sub di,Onerror
5585 5585 00001AFE 893E[A800] <1> mov [OnerrorLen],di
5586 5586 00001B02 C3 <1> ret
5587 5587 <1>
5588 5588 <1> ;
5589 5589 <1> ; "append" command
5590 5590 <1> ;
5591 5591 00001B03 803E[B800]00 <1> pc_append: cmp byte [VKernel],0
5592 5592 00001B08 770F <1> ja .vk
5593 5593 00001B0A BF[0808] <1> mov di,AppendBuf
5594 5594 00001B0D E814FD <1> call getline
5595 5595 00001B10 81EF[0808] <1> sub di,AppendBuf
5596 5596 00001B14 893E[A400] <1> .app1: mov [AppendLen],di
5597 5597 00001B18 C3 <1> ret
5598 5598 00001B19 BF[0806] <1> .vk: mov di,VKernelBuf+vk_append ; "append" command (vkernel)
5599 5599 00001B1C E805FD <1> call getline
5600 5600 00001B1F 81EF[0806] <1> sub di,VKernelBuf+vk_append
5601 5601 00001B23 83FF02 <1> cmp di,byte 2
5602 5602 00001B26 7509 <1> jne .app2
5603 5603 00001B28 803E[0806]2D <1> cmp byte [VKernelBuf+vk_append],'-'
5604 5604 00001B2D 7502 <1> jne .app2
5605 5605 00001B2F 31FF <1> xor di,di ; If "append -" -> null string
5606 5606 00001B31 893E[0406] <1> .app2: mov [VKernelBuf+vk_appendlen],di
5607 5607 00001B35 C3 <1> ret
5608 5608 <1>
5609 5609 <1> ;
5610 5610 <1> ; "ipappend" command (PXELINUX only)
5611 5611 <1> ;
5612 5612 <1> %if IS_PXELINUX
5613 5613 <1> pc_ipappend: call getint
5614 5614 <1> jc .err
5615 5615 <1> cmp byte [VKernel],0
5616 5616 <1> jne .vk
5617 5617 <1> mov [IPAppend],bl
5618 5618 <1> .err: ret
5619 5619 <1> .vk: mov [VKernelBuf+vk_ipappend],bl
5620 5620 <1> ret
5621 5621 <1> %endif
5622 5622 <1>
5623 5623 <1> ;
5624 5624 <1> ; "localboot" command (PXELINUX, ISOLINUX)
5625 5625 <1> ;
5626 5626 <1> %if IS_PXELINUX || IS_ISOLINUX
5627 5627 00001B36 E837FC <1> pc_localboot: call getint
5628 5628 00001B39 803E[B800]00 <1> cmp byte [VKernel],0 ; ("label" section only)
5629 5629 00001B3E 740E <1> je .err
5630 5630 00001B40 BF[0405] <1> mov di,VKernelBuf+vk_rname
5631 5631 00001B43 31C0 <1> xor ax,ax
5632 5632 00001B45 B90001 <1> mov cx,FILENAME_MAX
5633 5633 00001B48 F3AA <1> rep stosb ; Null kernel name
5634 5634 <1> %if IS_PXELINUX
5635 5635 <1> ; PXELINUX uses the first 4 bytes of vk_rname for the
5636 5636 <1> ; mangled IP address
5637 5637 <1> mov [VKernelBuf+vk_rname+5], bx ; Return type
5638 5638 <1> %else
5639 5639 00001B4A 891E[0505] <1> mov [VKernelBuf+vk_rname+1], bx ; Return type
5640 5640 <1> %endif
5641 5641 00001B4E C3 <1> .err: ret
5642 5642 <1> %endif
5643 5643 <1>
5644 5644 <1> ;
5645 5645 <1> ; "kernel" command
5646 5646 00001B4F 803E[B800]00 <1> pc_kernel: cmp byte [VKernel],0
5647 5647 00001B54 7409 <1> je .err ; ("label" section only)
5648 5648 00001B56 E84801 <1> call pc_getline
5649 5649 00001B59 BF[0405] <1> mov di,VKernelBuf+vk_rname
5650 5650 00001B5C E803FB <1> call mangle_name
5651 5651 00001B5F C3 <1> .err: ret
5652 5652 <1>
5653 5653 <1> ;
5654 5654 <1> ; "timeout", "totaltimeout" command
5655 5655 <1> ;
5656 5656 <1> ; N.B. 1/10 s ~ 1.D2162AABh clock ticks
5657 5657 <1> ;
5658 5658 00001B60 50 <1> pc_timeout: push ax
5659 5659 00001B61 E80CFC <1> call getint
5660 5660 00001B64 5E <1> pop si
5661 5661 00001B65 720F <1> jc .err
5662 5662 00001B67 66B8AB2A16D2 <1> mov eax,0D2162AABh
5663 5663 00001B6D 66F7E3 <1> mul ebx ; clock ticks per 1/10 s
5664 5664 00001B70 6601D3 <1> add ebx,edx
5665 5665 00001B73 66891C <1> mov [si],ebx
5666 5666 00001B76 C3 <1> .err: ret
5667 5667 <1>
5668 5668 <1>
5669 5669 <1> ;
5670 5670 <1> ; "totaltimeout" command
5671 5671 <1> ;
5672 5672 <1> pc_totaltimeout:
5673 5673 <1>
5674 5674 <1> ;
5675 5675 <1> ; Generic integer variable setting commands:
5676 5676 <1> ; "prompt", "implicit"
5677 5677 <1> ;
5678 5678 <1> pc_setint16:
5679 5679 00001B77 50 <1> push ax
5680 5680 00001B78 E8F5FB <1> call getint
5681 5681 00001B7B 5E <1> pop si
5682 5682 00001B7C 7202 <1> jc .err
5683 5683 00001B7E 891C <1> mov [si],bx
5684 5684 00001B80 C3 <1> .err: ret
5685 5685 <1>
5686 5686 <1> ;
5687 5687 <1> ; Generic file-processing commands:
5688 5688 <1> ; "display", "font", "kbdmap"
5689 5689 <1> ;
5690 5690 00001B81 50 <1> pc_filecmd: push ax ; Function to tailcall
5691 5691 00001B82 E81C01 <1> call pc_getline
5692 5692 00001B85 BF[0C1C] <1> mov di,MNameBuf
5693 5693 00001B88 57 <1> push di
5694 5694 00001B89 E8D6FA <1> call mangle_name
5695 5695 00001B8C 5F <1> pop di
5696 5696 00001B8D E89EF9 <1> call searchdir ; tailcall
5697 5697 00001B90 7501 <1> jnz .ok
5698 5698 00001B92 58 <1> pop ax ; Drop the successor function
5699 5699 00001B93 C3 <1> .ok: ret ; Tailcall if OK, error return
5700 5700 <1>
5701 5701 <1> ;
5702 5702 <1> ; "serial" command
5703 5703 <1> ;
5704 5704 00001B94 E8D9FB <1> pc_serial: call getint
5705 5705 00001B97 7207 <1> jc .err
5706 5706 00001B99 53 <1> push bx ; Serial port #
5707 5707 00001B9A E8BAFB <1> call skipspace
5708 5708 00001B9D 7302 <1> jnc .ok
5709 5709 00001B9F 5B <1> pop bx
5710 5710 00001BA0 C3 <1> .err: ret
5711 5711 <1> .ok:
5712 5712 00001BA1 E8A2FB <1> call ungetc
5713 5713 00001BA4 E8C9FB <1> call getint
5714 5714 00001BA7 C706[5403]0000 <1> mov [FlowControl], word 0 ; Default to no flow control
5715 5715 00001BAD 7229 <1> jc .nobaud
5716 5716 <1> .valid_baud:
5717 5717 00001BAF 6653 <1> push ebx
5718 5718 00001BB1 E8A3FB <1> call skipspace
5719 5719 00001BB4 7208 <1> jc .no_flow
5720 5720 00001BB6 E88DFB <1> call ungetc
5721 5721 00001BB9 E8B4FB <1> call getint ; Hardware flow control?
5722 5722 00001BBC 7302 <1> jnc .valid_flow
5723 5723 <1> .no_flow:
5724 5724 00001BBE 31DB <1> xor bx,bx ; Default -> no flow control
5725 5725 <1> .valid_flow:
5726 5726 00001BC0 80E70F <1> and bh,0Fh ; FlowIgnore
5727 5727 00001BC3 C0E704 <1> shl bh,4
5728 5728 00001BC6 883E[5603] <1> mov [FlowIgnore],bh
5729 5729 00001BCA 88DF <1> mov bh,bl
5730 5730 00001BCC 81E303F0 <1> and bx,0F003h ; Valid bits
5731 5731 00001BD0 891E[5403] <1> mov [FlowControl],bx
5732 5732 00001BD4 665B <1> pop ebx ; Baud rate
5733 5733 00001BD6 EB06 <1> jmp short .parse_baud
5734 5734 <1> .nobaud:
5735 5735 00001BD8 66BB80250000 <1> mov ebx,DEFAULT_BAUD ; No baud rate given
5736 5736 <1> .parse_baud:
5737 5737 00001BDE 5F <1> pop di ; Serial port #
5738 5738 00001BDF 6683FB4B <1> cmp ebx,byte 75
5739 5739 00001BE3 72BB <1> jb .err ; < 75 baud == bogus
5740 5740 00001BE5 66B800C20100 <1> mov eax,BAUD_DIVISOR
5741 5741 00001BEB 6699 <1> cdq
5742 5742 00001BED 66F7F3 <1> div ebx
5743 5743 00001BF0 A3[5203] <1> mov [BaudDivisor],ax
5744 5744 00001BF3 50 <1> push ax ; Baud rate divisor
5745 5745 00001BF4 83FF03 <1> cmp di,3
5746 5746 00001BF7 7706 <1> ja .port_is_io ; If port > 3 then port is I/O addr
5747 5747 00001BF9 D1E7 <1> shl di,1
5748 5748 00001BFB 8BBD0004 <1> mov di,[di+serial_base] ; Get the I/O port from the BIOS
5749 5749 <1> .port_is_io:
5750 5750 00001BFF 893E[B400] <1> mov [SerialPort],di
5751 5751 <1>
5752 5752 <1> ;
5753 5753 <1> ; Begin code to actually set up the serial port
5754 5754 <1> ;
5755 5755 00001C03 8D5503 <1> lea dx,[di+3] ; DX -> LCR
5756 5756 00001C06 B083 <1> mov al,83h ; Enable DLAB
5757 5757 00001C08 E8(C600) <1> call slow_out
5758 5758 <1>
5759 5759 00001C0B 58 <1> pop ax ; Divisor
5760 5760 00001C0C 89FA <1> mov dx,di ; DX -> LS
5761 5761 00001C0E E8(C600) <1> call slow_out
5762 5762 <1>
5763 5763 00001C11 42 <1> inc dx ; DX -> MS
5764 5764 00001C12 88E0 <1> mov al,ah
5765 5765 00001C14 E8(C600) <1> call slow_out
5766 5766 <1>
5767 5767 00001C17 B003 <1> mov al,03h ; Disable DLAB
5768 5768 00001C19 42 <1> inc dx ; DX -> LCR
5769 5769 00001C1A 42 <1> inc dx
5770 5770 00001C1B E8(C600) <1> call slow_out
5771 5771 <1>
5772 5772 00001C1E EC <1> in al,dx ; Read back LCR (detect missing hw)
5773 5773 00001C1F 3C03 <1> cmp al,03h ; If nothing here we'll read 00 or FF
5774 5774 00001C21 752E <1> jne .serial_port_bad ; Assume serial port busted
5775 5775 00001C23 4A <1> dec dx
5776 5776 00001C24 4A <1> dec dx ; DX -> IER
5777 5777 00001C25 30C0 <1> xor al,al ; IRQ disable
5778 5778 00001C27 E8(C600) <1> call slow_out
5779 5779 <1>
5780 5780 00001C2A 42 <1> inc dx ; DX -> FCR/IIR
5781 5781 00001C2B B001 <1> mov al,01h
5782 5782 00001C2D E8(C600) <1> call slow_out ; Enable FIFOs if present
5783 5783 00001C30 EC <1> in al,dx
5784 5784 00001C31 3CC0 <1> cmp al,0C0h ; FIFOs enabled and usable?
5785 5785 00001C33 7305 <1> jae .fifo_ok
5786 5786 00001C35 31C0 <1> xor ax,ax ; Disable FIFO if unusable
5787 5787 00001C37 E8(C600) <1> call slow_out
5788 5788 <1> .fifo_ok:
5789 5789 <1>
5790 5790 00001C3A 42 <1> inc dx
5791 5791 00001C3B 42 <1> inc dx ; DX -> MCR
5792 5792 00001C3C EC <1> in al,dx
5793 5793 00001C3D 0A06[5403] <1> or al,[FlowOutput] ; Assert bits
5794 5794 00001C41 E8(C600) <1> call slow_out
5795 5795 <1>
5796 5796 <1> ; Show some life
5797 5797 00001C44 BE[7C03] <1> mov si,syslinux_banner
5798 5798 00001C47 E820FE <1> call write_serial_str
5799 5799 00001C4A BE[9803] <1> mov si,copyright_str
5800 5800 00001C4D E81AFE <1> call write_serial_str
5801 5801 00001C50 C3 <1> ret
5802 5802 <1>
5803 5803 <1> .serial_port_bad:
5804 5804 00001C51 C706[B400]0000 <1> mov [SerialPort], word 0
5805 5805 00001C57 C3 <1> ret
5806 5806 <1>
5807 5807 <1> ;
5808 5808 <1> ; "F"-key command
5809 5809 <1> ;
5810 5810 00001C58 50 <1> pc_fkey: push ax
5811 5811 00001C59 E84500 <1> call pc_getline
5812 5812 00001C5C 5F <1> pop di
5813 5813 00001C5D E802FA <1> call mangle_name ; Mangle file name
5814 5814 00001C60 C3 <1> ret
5815 5815 <1>
5816 5816 <1> ;
5817 5817 <1> ; "label" command
5818 5818 <1> ;
5819 5819 00001C61 E85800 <1> pc_label: call commit_vk ; Commit any current vkernel
5820 5820 00001C64 BF[0404] <1> mov di,VKernelBuf ; Erase the vkernelbuf for better compression
5821 5821 00001C67 B90202 <1> mov cx,(vk_size >> 1)
5822 5822 00001C6A 31C0 <1> xor ax,ax
5823 5823 00001C6C F3AB <1> rep stosw
5824 5824 00001C6E E83000 <1> call pc_getline
5825 5825 00001C71 BF[0404] <1> mov di,VKernelBuf+vk_vname
5826 5826 00001C74 E8EBF9 <1> call mangle_name ; Mangle virtual name
5827 5827 00001C77 C606[B800]01 <1> mov byte [VKernel],1 ; We've seen a "label" statement
5828 5828 00001C7C BE[0404] <1> mov si,VKernelBuf+vk_vname ; By default, rname == vname
5829 5829 00001C7F BF[0405] <1> mov di,VKernelBuf+vk_rname
5830 5830 00001C82 B90001 <1> mov cx,FILENAME_MAX
5831 5831 00001C85 F3A4 <1> rep movsb
5832 5832 00001C87 BE[0808] <1> mov si,AppendBuf ; Default append==global append
5833 5833 00001C8A BF[0806] <1> mov di,VKernelBuf+vk_append
5834 5834 00001C8D 8B0E[A400] <1> mov cx,[AppendLen]
5835 5835 00001C91 890E[0406] <1> mov [VKernelBuf+vk_appendlen],cx
5836 5836 00001C95 F3A4 <1> rep movsb
5837 5837 <1> %if IS_PXELINUX ; PXELINUX only
5838 5838 <1> mov al,[IPAppend] ; Default ipappend==global ipappend
5839 5839 <1> mov [VKernelBuf+vk_ipappend],al
5840 5840 <1> %endif
5841 5841 00001C97 C3 <1> ret
5842 5842 <1>
5843 5843 <1> ;
5844 5844 <1> ; "say" command
5845 5845 <1> ;
5846 5846 00001C98 E80600 <1> pc_say: call pc_getline ; "say" command
5847 5847 00001C9B E88CE6 <1> call writestr
5848 5848 00001C9E E97CE6 <1> jmp crlf ; tailcall
5849 5849 <1>
5850 5850 <1> ;
5851 5851 <1> ; Comment line
5852 5852 <1> ;
5853 5853 <1> pc_comment: ; Fall into pc_getline
5854 5854 <1>
5855 5855 <1> ;
5856 5856 <1> ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
5857 5857 <1> ;
5858 5858 00001CA1 BF[0000] <1> pc_getline: mov di,trackbuf
5859 5859 00001CA4 57 <1> push di
5860 5860 00001CA5 E87CFB <1> call getline
5861 5861 00001CA8 30C0 <1> xor al,al
5862 5862 00001CAA AA <1> stosb ; Null-terminate
5863 5863 00001CAB 5E <1> pop si
5864 5864 00001CAC C3 <1> ret
5865 5865 <1>
5866 5866 <1> ;
5867 5867 <1> ; Main loop for configuration file parsing
5868 5868 <1> ;
5869 5869 <1> parse_config:
5870 5870 00001CAD BF[0404] <1> mov di,VKernelBuf ; Clear VKernelBuf at start
5871 5871 00001CB0 31C0 <1> xor ax,ax
5872 5872 00001CB2 B90404 <1> mov cx,vk_size
5873 5873 00001CB5 F3AA <1> rep stosb
5874 5874 <1> .again:
5875 5875 00001CB7 E8C400 <1> call getcommand
5876 5876 00001CBA 73FB <1> jnc .again ; If not EOF do it again
5877 5877 <1> ;
5878 5878 <1> ; The fall through to commit_vk to commit any final
5879 5879 <1> ; VKernel being read
5880 5880 <1> ;
5881 5881 <1> ;
5882 5882 <1> ; commit_vk: Store the current VKernelBuf into buffer segment
5883 5883 <1> ;
5884 5884 <1> commit_vk:
5885 5885 <1> ; For better compression, clean up the append field
5886 5886 00001CBC A1[0406] <1> mov ax,[VKernelBuf+vk_appendlen]
5887 5887 00001CBF BF[0806] <1> mov di,VKernelBuf+vk_append
5888 5888 00001CC2 01C7 <1> add di,ax
5889 5889 00001CC4 B90002 <1> mov cx,max_cmd_len+1
5890 5890 00001CC7 29C1 <1> sub cx,ax
5891 5891 00001CC9 31C0 <1> xor ax,ax
5892 5892 00001CCB F3AA <1> rep stosb
5893 5893 <1>
5894 5894 <1> ; Pack temporarily into trackbuf
5895 5895 00001CCD BE[0404] <1> mov si,VKernelBuf
5896 5896 00001CD0 BF[0000] <1> mov di,trackbuf
5897 5897 00001CD3 B90404 <1> mov cx,vk_size
5898 5898 00001CD6 E82100 <1> call rllpack
5899 5899 <1> ; Now DX = number of bytes
5900 5900 00001CD9 8B3E[B600] <1> mov di,[VKernelBytes]
5901 5901 00001CDD 89D1 <1> mov cx,dx
5902 5902 00001CDF 01FA <1> add dx,di
5903 5903 00001CE1 7210 <1> jc .overflow ; If > 1 segment
5904 5904 00001CE3 8916[B600] <1> mov [VKernelBytes],dx
5905 5905 00001CE7 BE[0000] <1> mov si,trackbuf
5906 5906 00001CEA 06 <1> push es
5907 5907 00001CEB 680020 <1> push word vk_seg
5908 5908 00001CEE 07 <1> pop es
5909 5909 00001CEF F3A4 <1> rep movsb
5910 5910 00001CF1 07 <1> pop es
5911 5911 00001CF2 C3 <1> ret
5912 5912 <1> .overflow:
5913 5913 00001CF3 BE[7500] <1> mov si,vk_overflow_msg
5914 5914 00001CF6 E831E6 <1> call writestr
5915 5915 00001CF9 C3 <1> ret
5916 5916 <1>
5917 5917 <1> section .data
5918 5918 00000075 4F7574206F66206D65- <1> vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
5919 5919 0000007E 6D6F72792070617273- <1>
5920 5920 00000087 696E6720636F6E6669- <1>
5921 5921 00000090 672066696C650D0A00 <1>
5922 5922 <1>
5923 5923 00000099 00<rept> <1> align 4, db 0
5924 5924 0000009C 00000000 <1> KbdTimeout dd 0 ; Keyboard timeout (if any)
5925 5925 000000A0 00000000 <1> TotalTimeout dd 0 ; Total timeout (if any)
5926 5926 000000A4 0000 <1> AppendLen dw 0 ; Bytes in append= command
5927 5927 000000A6 0000 <1> OntimeoutLen dw 0 ; Bytes in ontimeout command
5928 5928 000000A8 0000 <1> OnerrorLen dw 0 ; Bytes in onerror command
5929 5929 000000AA 0090 <1> CmdLinePtr dw cmd_line_here ; Command line advancing pointer
5930 5930 000000AC 0000 <1> ForcePrompt dw 0 ; Force prompt
5931 5931 000000AE 0000 <1> NoEscape dw 0 ; No escape
5932 5932 000000B0 0100 <1> AllowImplicit dw 1 ; Allow implicit kernels
5933 5933 000000B2 0100 <1> AllowOptions dw 1 ; User-specified options allowed
5934 5934 000000B4 0000 <1> SerialPort dw 0 ; Serial port base (or 0 for no serial port)
5935 5935 000000B6 0000 <1> VKernelBytes dw 0 ; Number of bytes used by vkernels
5936 5936 000000B8 00 <1> VKernel db 0 ; Have we seen any "label" statements?
5937 5937 <1>
5938 5938 <1> section .latebss
5939 5939 <1> alignb 4 ; For the good of REP MOVSD
5940 5940 00000000 <res 00000201> <1> command_line resb max_cmd_len+2 ; Command line buffer
5941 5941 00000201 <res 00000001>- <1> alignb 4
5942 5942 00000201 <rept> <1>
5943 5943 00000204 <res 00000200> <1> default_cmd resb max_cmd_len+1 ; "default" command line
5944 5944 <1>
5945 5945 <1> %include "rllpack.inc"
5946 5946 <2> ; -*- fundamental -*-
5947 5947 <2> ; -----------------------------------------------------------------------
5948 5948 <2> ;
5949 5949 <2> ; Copyright 2004 H. Peter Anvin - All Rights Reserved
5950 5950 <2> ;
5951 5951 <2> ; This program is free software; you can redistribute it and/or modify
5952 5952 <2> ; it under the terms of the GNU General Public License as published by
5953 5953 <2> ; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
5954 5954 <2> ; Boston MA 02111-1307, USA; either version 2 of the License, or
5955 5955 <2> ; (at your option) any later version; incorporated herein by reference.
5956 5956 <2> ;
5957 5957 <2> ; -----------------------------------------------------------------------
5958 5958 <2> ; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
5959 5959 <2>
5960 5960 <2> ;
5961 5961 <2> ; rllpack.inc
5962 5962 <2> ;
5963 5963 <2> ; Very simple RLL compressor/decompressor, used to pack binary structures
5964 5964 <2> ; together.
5965 5965 <2> ;
5966 5966 <2> ; Format of leading byte
5967 5967 <2> ; 1-128 = x verbatim bytes follow
5968 5968 <2> ; 129-255 = (x-126) times subsequent byte
5969 5969 <2> ; 0 = end of data
5970 5970 <2> ;
5971 5971 <2>
5972 5972 <2> section .text
5973 5973 <2>
5974 5974 <2> ;
5975 5975 <2> ; rllpack:
5976 5976 <2> ; Pack CX bytes from DS:SI into ES:DI
5977 5977 <2> ; Returns updated SI, DI and CX = number of bytes output
5978 5978 <2> ;
5979 5979 <2> rllpack:
5980 5980 00001CFA 50 <2> push ax
5981 5981 00001CFB 53 <2> push bx
5982 5982 00001CFC 51 <2> push cx
5983 5983 00001CFD 55 <2> push bp
5984 5984 00001CFE 57 <2> push di
5985 5985 <2> .startseq:
5986 5986 00001CFF 31C0 <2> xor ax,ax ; Zero byte
5987 5987 00001D01 31DB <2> xor bx,bx ; Run length zero
5988 5988 00001D03 89FD <2> mov bp,di ; Pointer to header byte
5989 5989 00001D05 AA <2> stosb ; Store header byte (might be zero)
5990 5990 00001D06 E349 <2> jcxz .done_null
5991 5991 <2> .stdbyte:
5992 5992 00001D08 AC <2> lodsb
5993 5993 00001D09 AA <2> stosb
5994 5994 00001D0A 49 <2> dec cx
5995 5995 00001D0B 38C4 <2> cmp ah,al
5996 5996 00001D0D 740F <2> je .same
5997 5997 <2> .diff:
5998 5998 00001D0F 88C4 <2> mov ah,al
5999 5999 00001D11 31DB <2> xor bx,bx
6000 6000 <2> .plainbyte:
6001 6001 00001D13 43 <2> inc bx
6002 6002 00001D14 26FE4600 <2> inc byte [es:bp]
6003 6003 00001D18 E334 <2> jcxz .done
6004 6004 00001D1A 79EC <2> jns .stdbyte
6005 6005 00001D1C EBE1 <2> jmp .startseq
6006 6006 <2> .same:
6007 6007 00001D1E 80FB02 <2> cmp bl,2
6008 6008 00001D21 72F0 <2> jb .plainbyte
6009 6009 <2> ; 3 bytes or more in a row, time to convert sequence
6010 6010 00001D23 26285E00 <2> sub byte [es:bp],bl
6011 6011 00001D27 7501 <2> jnz .normal
6012 6012 00001D29 4F <2> dec di ; We killed a whole stretch, remove start byte
6013 6013 <2> .normal:
6014 6014 00001D2A 43 <2> inc bx
6015 6015 00001D2B 29DF <2> sub di,bx
6016 6016 00001D2D 89FD <2> mov bp,di
6017 6017 00001D2F 88D8 <2> mov al,bl
6018 6018 00001D31 047E <2> add al,126
6019 6019 00001D33 AA <2> stosb
6020 6020 00001D34 88E0 <2> mov al,ah
6021 6021 00001D36 AA <2> stosb
6022 6022 <2> .getrun:
6023 6023 00001D37 E315 <2> jcxz .done
6024 6024 00001D39 80FB81 <2> cmp bl,255-126
6025 6025 00001D3C 73C1 <2> jae .startseq
6026 6026 00001D3E AC <2> lodsb
6027 6027 00001D3F 38E0 <2> cmp al,ah
6028 6028 00001D41 7508 <2> jne .nomatch
6029 6029 00001D43 43 <2> inc bx
6030 6030 00001D44 26FE4600 <2> inc byte [es:bp]
6031 6031 00001D48 49 <2> dec cx
6032 6032 00001D49 EBEC <2> jmp .getrun
6033 6033 <2> .nomatch:
6034 6034 00001D4B 4E <2> dec si
6035 6035 00001D4C EBB1 <2> jmp .startseq
6036 6036 <2> .done:
6037 6037 00001D4E 30C0 <2> xor al,al
6038 6038 00001D50 AA <2> stosb
6039 6039 <2> .done_null:
6040 6040 00001D51 5A <2> pop dx
6041 6041 00001D52 29FA <2> sub dx,di
6042 6042 00001D54 F7DA <2> neg dx
6043 6043 00001D56 5D <2> pop bp
6044 6044 00001D57 59 <2> pop cx
6045 6045 00001D58 5B <2> pop bx
6046 6046 00001D59 58 <2> pop ax
6047 6047 00001D5A C3 <2> ret
6048 6048 <2> ;
6049 6049 <2> ; rllunpack:
6050 6050 <2> ; Unpack bytes from DS:SI into ES:DI
6051 6051 <2> ; On return SI, DI are updated and CX contains number of bytes output
6052 6052 <2> ;
6053 6053 <2> rllunpack:
6054 6054 00001D5B 50 <2> push ax
6055 6055 00001D5C 57 <2> push di
6056 6056 00001D5D 31C9 <2> xor cx,cx
6057 6057 <2> .header:
6058 6058 00001D5F AC <2> lodsb
6059 6059 00001D60 20C0 <2> and al,al
6060 6060 00001D62 7413 <2> jz .done
6061 6061 00001D64 3C81 <2> cmp al,129
6062 6062 00001D66 7306 <2> jae .isrun
6063 6063 <2> ; Not a run
6064 6064 00001D68 88C1 <2> mov cl,al
6065 6065 00001D6A F3A4 <2> rep movsb
6066 6066 00001D6C EBF1 <2> jmp .header
6067 6067 <2> .isrun:
6068 6068 00001D6E 2C7E <2> sub al,126
6069 6069 00001D70 88C1 <2> mov cl,al
6070 6070 00001D72 AC <2> lodsb
6071 6071 00001D73 F3AA <2> rep stosb
6072 6072 00001D75 EBE8 <2> jmp .header
6073 6073 <2> .done:
6074 6074 00001D77 59 <2> pop cx
6075 6075 00001D78 29F9 <2> sub cx,di
6076 6076 00001D7A F7D9 <2> neg cx
6077 6077 00001D7C 58 <2> pop ax
6078 6078 00001D7D C3 <2> ret
6079 6079 %include "parsecmd.inc" ; Low-level config file handling
6080 6080 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
6081 6081 <1> ;; -----------------------------------------------------------------------
6082 6082 <1> ;;
6083 6083 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
6084 6084 <1> ;;
6085 6085 <1> ;; This program is free software; you can redistribute it and/or modify
6086 6086 <1> ;; it under the terms of the GNU General Public License as published by
6087 6087 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
6088 6088 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
6089 6089 <1> ;; (at your option) any later version; incorporated herein by reference.
6090 6090 <1> ;;
6091 6091 <1> ;; -----------------------------------------------------------------------
6092 6092 <1>
6093 6093 <1> ;;
6094 6094 <1> ;; parsecmd.inc
6095 6095 <1> ;;
6096 6096 <1> ;; Command line parser code
6097 6097 <1> ;;
6098 6098 <1>
6099 6099 <1> section .text
6100 6100 <1>
6101 6101 <1> ; -------------------------------------------------------------------------
6102 6102 <1> ; getcommand: Get a keyword from the current "getc" file and match it
6103 6103 <1> ; against a list of keywords (keywd_table). Each entry in
6104 6104 <1> ; that table should have the following form:
6105 6105 <1> ; <32 bit hash value> <16 bit handler offset>
6106 6106 <1> ;
6107 6107 <1> ; The handler is called, and upon return this function
6108 6108 <1> ; returns with CF = 0. On EOF, this function returns
6109 6109 <1> ; with CF = 1.
6110 6110 <1> ; -------------------------------------------------------------------------
6111 6111 <1>
6112 6112 <1> getcommand:
6113 6113 <1> .find:
6114 6114 00001D7E E8D6F9 <1> call skipspace ; Skip leading whitespace
6115 6115 00001D81 7455 <1> jz .eof ; End of file
6116 6116 00001D83 72F9 <1> jc .find ; End of line: try again
6117 6117 <1>
6118 6118 <1> ; Do this explicitly so #foo is treated as a comment
6119 6119 00001D85 3C23 <1> cmp al,'#' ; Leading hash mark -> comment
6120 6120 00001D87 7451 <1> je .skipline
6121 6121 <1>
6122 6122 00001D89 0C20 <1> or al,20h ; Convert to lower case
6123 6123 00001D8B 660FB6D8 <1> movzx ebx,al ; Hash for a one-char keyword
6124 6124 <1> .read_loop:
6125 6125 00001D8F 6653 <1> push ebx
6126 6126 00001D91 E869F9 <1> call getc
6127 6127 00001D94 665B <1> pop ebx
6128 6128 00001D96 7240 <1> jc .eof
6129 6129 00001D98 3C20 <1> cmp al,' ' ; Whitespace
6130 6130 00001D9A 760A <1> jbe .done
6131 6131 00001D9C 0C20 <1> or al,20h
6132 6132 00001D9E 66C1C305 <1> rol ebx,5
6133 6133 00001DA2 30C3 <1> xor bl,al
6134 6134 00001DA4 EBE9 <1> jmp short .read_loop
6135 6135 00001DA6 E89DF9 <1> .done: call ungetc
6136 6136 00001DA9 E8ABF9 <1> call skipspace
6137 6137 00001DAC 742A <1> jz .eof
6138 6138 00001DAE 7219 <1> jc .noparm
6139 6139 00001DB0 E893F9 <1> call ungetc ; Return nonwhitespace char to buf
6140 6140 00001DB3 BE[1804] <1> mov si,keywd_table
6141 6141 00001DB6 B91F00 <1> mov cx,keywd_count
6142 6142 <1> .table_search:
6143 6143 00001DB9 66AD <1> lodsd
6144 6144 00001DBB 6639C3 <1> cmp ebx,eax
6145 6145 00001DBE 7413 <1> je .found_keywd
6146 6146 00001DC0 66AD <1> lodsd ; Skip entrypoint/argument
6147 6147 00001DC2 E2F5 <1> loop .table_search
6148 6148 <1>
6149 6149 <1> ; Otherwise unrecognized keyword
6150 6150 00001DC4 BE[F801] <1> mov si,err_badcfg
6151 6151 00001DC7 EB05 <1> jmp short .error
6152 6152 <1>
6153 6153 <1> ; No parameter
6154 6154 <1> .noparm:
6155 6155 00001DC9 BE[1A02] <1> mov si,err_noparm
6156 6156 00001DCC B00A <1> mov al,10 ; Already at EOL
6157 6157 <1> .error:
6158 6158 00001DCE E859E5 <1> call cwritestr
6159 6159 00001DD1 EB07 <1> jmp short .skipline
6160 6160 <1>
6161 6161 00001DD3 AD <1> .found_keywd: lodsw ; Load argument into ax
6162 6162 00001DD4 FF14 <1> call [si]
6163 6163 00001DD6 F8 <1> clc
6164 6164 00001DD7 C3 <1> ret
6165 6165 <1>
6166 6166 00001DD8 F9 <1> .eof: stc
6167 6167 00001DD9 C3 <1> ret
6168 6168 <1>
6169 6169 00001DDA 3C0A <1> .skipline: cmp al,10 ; Search for LF
6170 6170 00001DDC 74A0 <1> je .find
6171 6171 00001DDE E81CF9 <1> call getc
6172 6172 00001DE1 72F5 <1> jc .eof
6173 6173 00001DE3 EBF5 <1> jmp short .skipline
6174 6174 <1>
6175 6175 <1> section .latebss
6176 6176 <1> alignb 4
6177 6177 <1> vk_size equ (vk_end + 3) & ~3
6178 6178 00000404 <res 00000404> <1> VKernelBuf: resb vk_size ; "Current" vkernel
6179 6179 00000808 <res 00000200> <1> AppendBuf resb max_cmd_len+1 ; append=
6180 6180 00000A08 <res 00000200> <1> Ontimeout resb max_cmd_len+1 ; ontimeout
6181 6181 00000C08 <res 00000200> <1> Onerror resb max_cmd_len+1 ; onerror
6182 6182 00000E08 <res 00000100> <1> KbdMap resb 256 ; Keyboard map
6183 6183 00000F08 <res 00000A00> <1> FKeyName resb 10*FILENAME_MAX ; File names for F-key help
6184 6184 00001908 <res 00000002> <1> KernelCNameLen resw 1 ; Length of unmangled kernel name
6185 6185 0000190A <res 00000002> <1> InitRDCNameLen resw 1 ; Length of unmangled initrd name
6186 6186 <1> %if IS_SYSLINUX
6187 6187 <1> KernelName resb FILENAME_MAX+1 ; Mangled name for kernel
6188 6188 <1> KernelCName resb FILENAME_MAX+2 ; Unmangled kernel name
6189 6189 <1> InitRDCName resb FILENAME_MAX+2 ; Unmangled initrd name
6190 6190 <1> %else
6191 6191 0000190C <res 00000100> <1> KernelName resb FILENAME_MAX ; Mangled name for kernel
6192 6192 00001A0C <res 00000100> <1> KernelCName resb FILENAME_MAX ; Unmangled kernel name
6193 6193 00001B0C <res 00000100> <1> InitRDCName resb FILENAME_MAX ; Unmangled initrd name
6194 6194 <1> %endif
6195 6195 00001C0C <res 00000100> <1> MNameBuf resb FILENAME_MAX
6196 6196 00001D0C <res 00000100> <1> InitRD resb FILENAME_MAX
6197 6197 %include "bcopy32.inc" ; 32-bit bcopy
6198 6198 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
6199 6199 <1> ;; -----------------------------------------------------------------------
6200 6200 <1> ;;
6201 6201 <1> ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
6202 6202 <1> ;;
6203 6203 <1> ;; This program is free software; you can redistribute it and/or modify
6204 6204 <1> ;; it under the terms of the GNU General Public License as published by
6205 6205 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
6206 6206 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
6207 6207 <1> ;; (at your option) any later version; incorporated herein by reference.
6208 6208 <1> ;;
6209 6209 <1> ;; -----------------------------------------------------------------------
6210 6210 <1>
6211 6211 <1> ;;
6212 6212 <1> ;; bcopy32.inc
6213 6213 <1> ;;
6214 6214 <1> ;; 32-bit bcopy routine for real mode
6215 6215 <1> ;;
6216 6216 <1>
6217 6217 <1> ;
6218 6218 <1> ; 32-bit bcopy routine for real mode
6219 6219 <1> ;
6220 6220 <1> ; We enter protected mode, set up a flat 32-bit environment, run rep movsd
6221 6221 <1> ; and then exit. IMPORTANT: This code assumes cs == 0.
6222 6222 <1> ;
6223 6223 <1> ; This code is probably excessively anal-retentive in its handling of
6224 6224 <1> ; segments, but this stuff is painful enough as it is without having to rely
6225 6225 <1> ; on everything happening "as it ought to."
6226 6226 <1> ;
6227 6227 <1> ; NOTE: this code is relocated into low memory, just after the .earlybss
6228 6228 <1> ; segment, in order to support to "bcopy over self" operation.
6229 6229 <1> ;
6230 6230 <1>
6231 6231 <1> section .bcopy32
6232 6232 <1> align 8
6233 6233 <1> __bcopy_start:
6234 6234 <1>
6235 6235 <1> ; This is in the .text segment since it needs to be
6236 6236 <1> ; contiguous with the rest of the bcopy stuff
6237 6237 <1>
6238 6238 00000000 2F00 <1> bcopy_gdt: dw bcopy_gdt_size-1 ; Null descriptor - contains GDT
6239 6239 00000002 [00000000] <1> dd bcopy_gdt ; pointer for LGDT instruction
6240 6240 00000006 0000 <1> dw 0
6241 6241 00000008 FFFF0000 <1> dd 0000ffffh ; Code segment, use16, readable,
6242 6242 0000000C 009B0000 <1> dd 00009b00h ; present, dpl 0, cover 64K
6243 6243 00000010 FFFF0000 <1> dd 0000ffffh ; Data segment, use16, read/write,
6244 6244 00000014 00938F00 <1> dd 008f9300h ; present, dpl 0, cover all 4G
6245 6245 00000018 FFFF0000 <1> dd 0000ffffh ; Data segment, use16, read/write,
6246 6246 0000001C 00930000 <1> dd 00009300h ; present, dpl 0, cover 64K
6247 6247 <1> ; The rest are used for COM32 only
6248 6248 00000020 FFFF0000 <1> dd 0000ffffh ; Code segment, use32, readable,
6249 6249 00000024 009BCF00 <1> dd 00cf9b00h ; present, dpl 0, cover all 4G
6250 6250 00000028 FFFF0000 <1> dd 0000ffffh ; Data segment, use32, read/write,
6251 6251 0000002C 0093CF00 <1> dd 00cf9300h ; present, dpl 0, cover all 4G
6252 6252 <1> bcopy_gdt_size: equ $-bcopy_gdt
6253 6253 <1>
6254 6254 <1> ;
6255 6255 <1> ; bcopy:
6256 6256 <1> ; 32-bit copy, overlap safe
6257 6257 <1> ;
6258 6258 <1> ; Inputs:
6259 6259 <1> ; ESI - source pointer
6260 6260 <1> ; EDI - target pointer
6261 6261 <1> ; ECX - byte count
6262 6262 <1> ; DF - zero
6263 6263 <1> ;
6264 6264 <1> ; Outputs:
6265 6265 <1> ; ESI - first byte after source
6266 6266 <1> ; EDI - first byte after target
6267 6267 <1> ; ECX - zero
6268 6268 <1> ;
6269 6269 00000030 6650 <1> bcopy: push eax
6270 6270 00000032 6656 <1> push esi
6271 6271 00000034 6657 <1> push edi
6272 6272 00000036 6651 <1> push ecx
6273 6273 00000038 9C <1> pushf ; Saves, among others, the IF flag
6274 6274 00000039 1E <1> push ds
6275 6275 0000003A 06 <1> push es
6276 6276 <1>
6277 6277 0000003B FA <1> cli
6278 6278 0000003C E88D00 <1> call enable_a20
6279 6279 <1>
6280 6280 0000003F 662E0F0116[0000] <1> o32 lgdt [cs:bcopy_gdt]
6281 6281 00000046 0F20C0 <1> mov eax,cr0
6282 6282 00000049 0C01 <1> or al,1
6283 6283 0000004B 0F22C0 <1> mov cr0,eax ; Enter protected mode
6284 6284 0000004E EA[5300]0800 <1> jmp 08h:.in_pm
6285 6285 <1>
6286 6286 00000053 B81000 <1> .in_pm: mov ax,10h ; Data segment selector
6287 6287 00000056 8EC0 <1> mov es,ax
6288 6288 00000058 8ED8 <1> mov ds,ax
6289 6289 <1>
6290 6290 <1> ; Don't mess with ss, fs, and gs. They are never changed
6291 6291 <1> ; and should be able to make it back out of protected mode.
6292 6292 <1> ; This works because (and only because) we don't take
6293 6293 <1> ; interrupt in protected mode.
6294 6294 <1>
6295 6295 0000005A 6639FE <1> cmp esi,edi ; If source > destination, we might
6296 6296 0000005D 7713 <1> ja .reverse ; have to copy backwards
6297 6297 <1>
6298 6298 <1> .forward:
6299 6299 0000005F 88C8 <1> mov al,cl ; Save low bits
6300 6300 00000061 2403 <1> and al,3
6301 6301 00000063 66C1E902 <1> shr ecx,2 ; Convert to dwords
6302 6302 00000067 67F366A5 <1> a32 rep movsd ; Do our business
6303 6303 <1> ; At this point ecx == 0
6304 6304 <1>
6305 6305 0000006B 88C1 <1> mov cl,al ; Copy any fractional dword
6306 6306 0000006D 67F3A4 <1> a32 rep movsb
6307 6307 00000070 EB2B <1> jmp .exit
6308 6308 <1>
6309 6309 <1> .reverse:
6310 6310 00000072 FD <1> std ; Reverse copy
6311 6311 00000073 66678D740EFF <1> lea esi,[esi+ecx-1] ; Point to final byte
6312 6312 00000079 66678D7C0FFF <1> lea edi,[edi+ecx-1]
6313 6313 0000007F 6689C8 <1> mov eax,ecx
6314 6314 00000082 6683E103 <1> and ecx,3
6315 6315 00000086 66C1E802 <1> shr eax,2
6316 6316 0000008A 67F3A4 <1> a32 rep movsb
6317 6317 <1>
6318 6318 <1> ; Change ESI/EDI to point to the last dword, instead
6319 6319 <1> ; of the last byte.
6320 6320 0000008D 6683EE03 <1> sub esi,3
6321 6321 00000091 6683EF03 <1> sub edi,3
6322 6322 00000095 6689C1 <1> mov ecx,eax
6323 6323 00000098 67F366A5 <1> a32 rep movsd
6324 6324 <1>
6325 6325 0000009C FC <1> cld
6326 6326 <1>
6327 6327 <1> .exit:
6328 6328 0000009D B81800 <1> mov ax,18h ; "Real-mode-like" data segment
6329 6329 000000A0 8EC0 <1> mov es,ax
6330 6330 000000A2 8ED8 <1> mov ds,ax
6331 6331 <1>
6332 6332 000000A4 0F20C0 <1> mov eax,cr0
6333 6333 000000A7 24FE <1> and al,~1
6334 6334 000000A9 0F22C0 <1> mov cr0,eax ; Disable protected mode
6335 6335 000000AC EA[B100]0000 <1> jmp 0:.in_rm
6336 6336 <1>
6337 6337 <1> .in_rm: ; Back in real mode
6338 6338 000000B1 07 <1> pop es
6339 6339 000000B2 1F <1> pop ds
6340 6340 000000B3 E8B700 <1> call disable_a20
6341 6341 <1>
6342 6342 000000B6 9D <1> popf ; Re-enables interrupts
6343 6343 000000B7 6658 <1> pop eax
6344 6344 000000B9 665F <1> pop edi
6345 6345 000000BB 665E <1> pop esi
6346 6346 000000BD 6601C7 <1> add edi,eax
6347 6347 000000C0 6601C6 <1> add esi,eax
6348 6348 000000C3 6658 <1> pop eax
6349 6349 000000C5 C3 <1> ret
6350 6350 <1>
6351 6351 <1> ;
6352 6352 <1> ; Routines to enable and disable (yuck) A20. These routines are gathered
6353 6353 <1> ; from tips from a couple of sources, including the Linux kernel and
6354 6354 <1> ; http://www.x86.org/. The need for the delay to be as large as given here
6355 6355 <1> ; is indicated by Donnie Barnes of RedHat, the problematic system being an
6356 6356 <1> ; IBM ThinkPad 760EL.
6357 6357 <1> ;
6358 6358 <1> ; We typically toggle A20 twice for every 64K transferred.
6359 6359 <1> ;
6360 6360 <1> %define io_delay call _io_delay
6361 6361 <1> %define IO_DELAY_PORT 80h ; Invalid port (we hope!)
6362 6362 <1> %define disable_wait 32 ; How long to wait for a disable
6363 6363 <1>
6364 6364 <1> ; Note the skip of 2 here
6365 6365 <1> %define A20_DUNNO 0 ; A20 type unknown
6366 6366 <1> %define A20_NONE 2 ; A20 always on?
6367 6367 <1> %define A20_BIOS 4 ; A20 BIOS enable
6368 6368 <1> %define A20_KBC 6 ; A20 through KBC
6369 6369 <1> %define A20_FAST 8 ; A20 through port 92h
6370 6370 <1>
6371 6371 000000C6 EE <1> slow_out: out dx, al ; Fall through
6372 6372 <1>
6373 6373 000000C7 E680 <1> _io_delay: out IO_DELAY_PORT,al
6374 6374 000000C9 E680 <1> out IO_DELAY_PORT,al
6375 6375 000000CB C3 <1> ret
6376 6376 <1>
6377 6377 <1> enable_a20:
6378 6378 000000CC 6660 <1> pushad
6379 6379 000000CE 2EC606[0A40]FF <1> mov byte [cs:A20Tries],255 ; Times to try to make this work
6380 6380 <1>
6381 6381 <1> try_enable_a20:
6382 6382 <1> ;
6383 6383 <1> ; Flush the caches
6384 6384 <1> ;
6385 6385 <1> %if DO_WBINVD
6386 6386 <1> call try_wbinvd
6387 6387 <1> %endif
6388 6388 <1>
6389 6389 <1> ;
6390 6390 <1> ; If the A20 type is known, jump straight to type
6391 6391 <1> ;
6392 6392 000000D4 2E8B2E[0802] <1> mov bp,[cs:A20Type]
6393 6393 000000D9 2EFFA6[F401] <1> jmp word [cs:bp+A20List]
6394 6394 <1>
6395 6395 <1> ;
6396 6396 <1> ; First, see if we are on a system with no A20 gate
6397 6397 <1> ;
6398 6398 <1> a20_dunno:
6399 6399 <1> a20_none:
6400 6400 000000DE 2EC606[0802]02 <1> mov byte [cs:A20Type], A20_NONE
6401 6401 000000E4 E86400 <1> call a20_test
6402 6402 000000E7 755F <1> jnz a20_done
6403 6403 <1>
6404 6404 <1> ;
6405 6405 <1> ; Next, try the BIOS (INT 15h AX=2401h)
6406 6406 <1> ;
6407 6407 <1> a20_bios:
6408 6408 000000E9 2EC606[0802]04 <1> mov byte [cs:A20Type], A20_BIOS
6409 6409 000000EF B80124 <1> mov ax,2401h
6410 6410 000000F2 9C <1> pushf ; Some BIOSes muck with IF
6411 6411 000000F3 CD15 <1> int 15h
6412 6412 000000F5 9D <1> popf
6413 6413 <1>
6414 6414 000000F6 E85200 <1> call a20_test
6415 6415 000000F9 754D <1> jnz a20_done
6416 6416 <1>
6417 6417 <1> ;
6418 6418 <1> ; Enable the keyboard controller A20 gate
6419 6419 <1> ;
6420 6420 <1> a20_kbc:
6421 6421 000000FB B201 <1> mov dl, 1 ; Allow early exit
6422 6422 000000FD E8AC00 <1> call empty_8042
6423 6423 00000100 7546 <1> jnz a20_done ; A20 live, no need to use KBC
6424 6424 <1>
6425 6425 00000102 2EC606[0802]06 <1> mov byte [cs:A20Type], A20_KBC ; Starting KBC command sequence
6426 6426 <1>
6427 6427 00000108 B0D1 <1> mov al,0D1h ; Command write
6428 6428 0000010A E664 <1> out 064h, al
6429 6429 0000010C E89B00 <1> call empty_8042_uncond
6430 6430 <1>
6431 6431 0000010F B0DF <1> mov al,0DFh ; A20 on
6432 6432 00000111 E660 <1> out 060h, al
6433 6433 00000113 E89400 <1> call empty_8042_uncond
6434 6434 <1>
6435 6435 <1> ; Verify that A20 actually is enabled. Do that by
6436 6436 <1> ; observing a word in low memory and the same word in
6437 6437 <1> ; the HMA until they are no longer coherent. Note that
6438 6438 <1> ; we don't do the same check in the disable case, because
6439 6439 <1> ; we don't want to *require* A20 masking (SYSLINUX should
6440 6440 <1> ; work fine without it, if the BIOS does.)
6441 6441 00000116 51 <1> .kbc_wait: push cx
6442 6442 00000117 31C9 <1> xor cx,cx
6443 6443 <1> .kbc_wait_loop:
6444 6444 00000119 E82F00 <1> call a20_test
6445 6445 0000011C 7529 <1> jnz a20_done_pop
6446 6446 0000011E E2F9 <1> loop .kbc_wait_loop
6447 6447 <1>
6448 6448 00000120 59 <1> pop cx
6449 6449 <1> ;
6450 6450 <1> ; Running out of options here. Final attempt: enable the "fast A20 gate"
6451 6451 <1> ;
6452 6452 <1> a20_fast:
6453 6453 00000121 2EC606[0802]08 <1> mov byte [cs:A20Type], A20_FAST ; Haven't used the KBC yet
6454 6454 00000127 E492 <1> in al, 092h
6455 6455 00000129 0C02 <1> or al,02h
6456 6456 0000012B 24FE <1> and al,~01h ; Don't accidentally reset the machine!
6457 6457 0000012D E692 <1> out 092h, al
6458 6458 <1>
6459 6459 0000012F 51 <1> .fast_wait: push cx
6460 6460 00000130 31C9 <1> xor cx,cx
6461 6461 <1> .fast_wait_loop:
6462 6462 00000132 E81600 <1> call a20_test
6463 6463 00000135 7510 <1> jnz a20_done_pop
6464 6464 00000137 E2F9 <1> loop .fast_wait_loop
6465 6465 <1>
6466 6466 00000139 59 <1> pop cx
6467 6467 <1>
6468 6468 <1> ;
6469 6469 <1> ; Oh bugger. A20 is not responding. Try frobbing it again; eventually give up
6470 6470 <1> ; and report failure to the user.
6471 6471 <1> ;
6472 6472 <1>
6473 6473 <1>
6474 6474 0000013A 2EFE0E[0A40] <1> dec byte [cs:A20Tries]
6475 6475 0000013F 7593 <1> jnz try_enable_a20
6476 6476 <1>
6477 6477 00000141 BE[3103] <1> mov si, err_a20
6478 6478 00000144 E9(1915) <1> jmp abort_load
6479 6479 <1> ;
6480 6480 <1> ; A20 unmasked, proceed...
6481 6481 <1> ;
6482 6482 00000147 59 <1> a20_done_pop: pop cx
6483 6483 00000148 6661 <1> a20_done: popad
6484 6484 0000014A C3 <1> ret
6485 6485 <1>
6486 6486 <1> ;
6487 6487 <1> ; This routine tests if A20 is enabled (ZF = 0). This routine
6488 6488 <1> ; must not destroy any register contents.
6489 6489 <1> ;
6490 6490 <1> a20_test:
6491 6491 0000014B 06 <1> push es
6492 6492 0000014C 51 <1> push cx
6493 6493 0000014D 50 <1> push ax
6494 6494 0000014E B9FFFF <1> mov cx,0FFFFh ; HMA = segment 0FFFFh
6495 6495 00000151 8EC1 <1> mov es,cx
6496 6496 00000153 B92000 <1> mov cx,32 ; Loop count
6497 6497 00000156 2EA1[0840] <1> mov ax,[cs:A20Test]
6498 6498 0000015A 40 <1> .a20_wait: inc ax
6499 6499 0000015B 2EA3[0840] <1> mov [cs:A20Test],ax
6500 6500 0000015F E865FF <1> io_delay ; Serialize, and fix delay
6501 6501 00000162 263B06[1840] <1> cmp ax,[es:A20Test+10h]
6502 6502 00000167 E1F1 <1> loopz .a20_wait
6503 6503 00000169 58 <1> .a20_done: pop ax
6504 6504 0000016A 59 <1> pop cx
6505 6505 0000016B 07 <1> pop es
6506 6506 0000016C C3 <1> ret
6507 6507 <1>
6508 6508 <1> disable_a20:
6509 6509 0000016D 6660 <1> pushad
6510 6510 <1> ;
6511 6511 <1> ; Flush the caches
6512 6512 <1> ;
6513 6513 <1> %if DO_WBINVD
6514 6514 <1> call try_wbinvd
6515 6515 <1> %endif
6516 6516 <1>
6517 6517 0000016F 2E8B2E[0802] <1> mov bp,[cs:A20Type]
6518 6518 00000174 2EFFA6[FE01] <1> jmp word [cs:bp+A20DList]
6519 6519 <1>
6520 6520 <1> a20d_bios:
6521 6521 00000179 B80024 <1> mov ax,2400h
6522 6522 0000017C 9C <1> pushf ; Some BIOSes muck with IF
6523 6523 0000017D CD15 <1> int 15h
6524 6524 0000017F 9D <1> popf
6525 6525 00000180 EB19 <1> jmp short a20d_snooze
6526 6526 <1>
6527 6527 <1> ;
6528 6528 <1> ; Disable the "fast A20 gate"
6529 6529 <1> ;
6530 6530 <1> a20d_fast:
6531 6531 00000182 E492 <1> in al, 092h
6532 6532 00000184 24FC <1> and al,~03h
6533 6533 00000186 E692 <1> out 092h, al
6534 6534 00000188 EB11 <1> jmp short a20d_snooze
6535 6535 <1>
6536 6536 <1> ;
6537 6537 <1> ; Disable the keyboard controller A20 gate
6538 6538 <1> ;
6539 6539 <1> a20d_kbc:
6540 6540 0000018A E81D00 <1> call empty_8042_uncond
6541 6541 0000018D B0D1 <1> mov al,0D1h
6542 6542 0000018F E664 <1> out 064h, al ; Command write
6543 6543 00000191 E81600 <1> call empty_8042_uncond
6544 6544 00000194 B0DD <1> mov al,0DDh ; A20 off
6545 6545 00000196 E660 <1> out 060h, al
6546 6546 00000198 E80F00 <1> call empty_8042_uncond
6547 6547 <1> ; Wait a bit for it to take effect
6548 6548 <1> a20d_snooze:
6549 6549 0000019B 51 <1> push cx
6550 6550 0000019C B92000 <1> mov cx, disable_wait
6551 6551 0000019F E8A9FF <1> .delayloop: call a20_test
6552 6552 000001A2 7402 <1> jz .disabled
6553 6553 000001A4 E2F9 <1> loop .delayloop
6554 6554 000001A6 59 <1> .disabled: pop cx
6555 6555 <1> a20d_dunno:
6556 6556 <1> a20d_none:
6557 6557 000001A7 6661 <1> popad
6558 6558 000001A9 C3 <1> ret
6559 6559 <1>
6560 6560 <1> ;
6561 6561 <1> ; Routine to empty the 8042 KBC controller. If dl != 0
6562 6562 <1> ; then we will test A20 in the loop and exit if A20 is
6563 6563 <1> ; suddenly enabled.
6564 6564 <1> ;
6565 6565 <1> empty_8042_uncond:
6566 6566 000001AA 30D2 <1> xor dl,dl
6567 6567 <1> empty_8042:
6568 6568 000001AC E89CFF <1> call a20_test
6569 6569 000001AF 7404 <1> jz .a20_on
6570 6570 000001B1 20D2 <1> and dl,dl
6571 6571 000001B3 7517 <1> jnz .done
6572 6572 000001B5 E80FFF <1> .a20_on: io_delay
6573 6573 000001B8 E464 <1> in al, 064h ; Status port
6574 6574 000001BA A801 <1> test al,1
6575 6575 000001BC 7407 <1> jz .no_output
6576 6576 000001BE E806FF <1> io_delay
6577 6577 000001C1 E460 <1> in al, 060h ; Read input
6578 6578 000001C3 EBE7 <1> jmp short empty_8042
6579 6579 <1> .no_output:
6580 6580 000001C5 A802 <1> test al,2
6581 6581 000001C7 75E3 <1> jnz empty_8042
6582 6582 000001C9 E8FBFE <1> io_delay
6583 6583 000001CC C3 <1> .done: ret
6584 6584 <1>
6585 6585 <1> ;
6586 6586 <1> ; Execute a WBINVD instruction if possible on this CPU
6587 6587 <1> ;
6588 6588 <1> %if DO_WBINVD
6589 6589 <1> try_wbinvd:
6590 6590 <1> wbinvd
6591 6591 <1> ret
6592 6592 <1> %endif
6593 6593 <1>
6594 6594 <1> ;
6595 6595 <1> ; bcopy_over_self:
6596 6596 <1> ;
6597 6597 <1> ; This routine is used to shuffle memory around, followed by
6598 6598 <1> ; invoking an entry point somewhere in low memory. This routine
6599 6599 <1> ; can clobber any memory above 7C00h, we therefore have to move
6600 6600 <1> ; necessary code into the trackbuf area before doing the copy,
6601 6601 <1> ; and do adjustments to anything except BSS area references.
6602 6602 <1> ;
6603 6603 <1> ; NOTE: Since PXELINUX relocates itself, put all these
6604 6604 <1> ; references in the ".earlybss" segment.
6605 6605 <1> ;
6606 6606 <1> ; After performing the copy, this routine resets the stack and
6607 6607 <1> ; jumps to the specified entrypoint.
6608 6608 <1> ;
6609 6609 <1> ; IMPORTANT: This routine does not canonicalize the stack or the
6610 6610 <1> ; SS register. That is the responsibility of the caller.
6611 6611 <1> ;
6612 6612 <1> ; Inputs:
6613 6613 <1> ; DS:BX -> Pointer to list of (dst, src, len) pairs
6614 6614 <1> ; AX -> Number of list entries
6615 6615 <1> ; [CS:EntryPoint] -> CS:IP to jump to
6616 6616 <1> ; On stack - initial state (fd, ad, ds, es, fs, gs)
6617 6617 <1> ;
6618 6618 <1> shuffle_and_boot:
6619 6619 000001CD 21C0 <1> and ax,ax
6620 6620 000001CF 7414 <1> jz .done
6621 6621 <1> .loop:
6622 6622 000001D1 668B3F <1> mov edi,[bx]
6623 6623 000001D4 668B7704 <1> mov esi,[bx+4]
6624 6624 000001D8 668B4F08 <1> mov ecx,[bx+8]
6625 6625 000001DC E851FE <1> call bcopy
6626 6626 000001DF 83C30C <1> add bx,12
6627 6627 000001E2 48 <1> dec ax
6628 6628 000001E3 75EC <1> jnz .loop
6629 6629 <1>
6630 6630 <1> .done:
6631 6631 000001E5 0FA9 <1> pop gs
6632 6632 000001E7 0FA1 <1> pop fs
6633 6633 000001E9 07 <1> pop es
6634 6634 000001EA 1F <1> pop ds
6635 6635 000001EB 6661 <1> popad
6636 6636 000001ED 669D <1> popfd
6637 6637 000001EF 2EFF2E[0040] <1> jmp far [cs:EntryPoint]
6638 6638 <1>
6639 6639 <1> align 2
6640 6640 000001F4 [DE00][DE00][E900]- <1> A20List dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast
6641 6641 000001FA [FB00][2101] <1>
6642 6642 000001FE [A701][A701][7901]- <1> A20DList dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast
6643 6643 00000204 [8A01][8201] <1>
6644 6644 <1> a20_adjust_cnt equ ($-A20List)/2
6645 6645 <1>
6646 6646 00000208 0200 <1> A20Type dw A20_NONE ; A20 type
6647 6647 <1>
6648 6648 <1> ; Total size of .bcopy32 section
6649 6649 0000020A 00<rept> <1> alignb 4, db 0 ; Even number of dwords
6650 6650 <1> __bcopy_size equ $-__bcopy_start
6651 6651 <1>
6652 6652 <1> section .earlybss
6653 6653 <1> alignb 2
6654 6654 00004000 <res 00000004> <1> EntryPoint resd 1 ; CS:IP for shuffle_and_boot
6655 6655 00004004 <res 00000004> <1> SavedSSSP resd 1 ; Saved real mode SS:SP
6656 6656 00004008 <res 00000002> <1> A20Test resw 1 ; Counter for testing status of A20
6657 6657 0000400A <res 00000001> <1> A20Tries resb 1 ; Times until giving up on A20
6658 6658 %include "loadhigh.inc" ; Load a file into high memory
6659 6659 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
6660 6660 <1> ;; -----------------------------------------------------------------------
6661 6661 <1> ;;
6662 6662 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
6663 6663 <1> ;;
6664 6664 <1> ;; This program is free software; you can redistribute it and/or modify
6665 6665 <1> ;; it under the terms of the GNU General Public License as published by
6666 6666 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
6667 6667 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
6668 6668 <1> ;; (at your option) any later version; incorporated herein by reference.
6669 6669 <1> ;;
6670 6670 <1> ;; -----------------------------------------------------------------------
6671 6671 <1>
6672 6672 <1> ;;
6673 6673 <1> ;; loadhigh.inc
6674 6674 <1> ;;
6675 6675 <1> ;; Load a file into high memory
6676 6676 <1> ;;
6677 6677 <1>
6678 6678 <1> section .text
6679 6679 <1>
6680 6680 <1> ;
6681 6681 <1> ; load_high: loads (the remainder of) a file into high memory.
6682 6682 <1> ; This routine prints dots for each 64K transferred, and
6683 6683 <1> ; calls abort_check periodically.
6684 6684 <1> ;
6685 6685 <1> ; The xfer_buf_seg is used as a bounce buffer.
6686 6686 <1> ;
6687 6687 <1> ; The input address (EDI) should be dword aligned, and the final
6688 6688 <1> ; stretch is padded with zeroes if necessary.
6689 6689 <1> ;
6690 6690 <1> ; Inputs: SI = file handle/cluster pointer
6691 6691 <1> ; EDI = target address in high memory
6692 6692 <1> ; EAX = size of remaining file in bytes
6693 6693 <1> ; DX = zero-padding mask (e.g. 0003h for pad to dword)
6694 6694 <1> ;
6695 6695 <1> ; Outputs: SI = file handle/cluster pointer
6696 6696 <1> ; EDI = first untouched address (not including padding)
6697 6697 <1> ;
6698 6698 <1> load_high:
6699 6699 00001DE5 06 <1> push es
6700 6700 <1>
6701 6701 00001DE6 BB0010 <1> mov bx,xfer_buf_seg
6702 6702 00001DE9 8EC3 <1> mov es,bx
6703 6703 <1>
6704 6704 <1> .read_loop:
6705 6705 00001DEB 21F6 <1> and si,si ; If SI == 0 then we have end of file
6706 6706 00001DED 7460 <1> jz .eof
6707 6707 00001DEF 56 <1> push si
6708 6708 00001DF0 BE[AE03] <1> mov si,dot_msg
6709 6709 00001DF3 E834E5 <1> call cwritestr
6710 6710 00001DF6 5E <1> pop si
6711 6711 00001DF7 E809F7 <1> call abort_check
6712 6712 <1>
6713 6713 00001DFA 6650 <1> push eax ; <A> Total bytes to transfer
6714 6714 00001DFC 663D00000100 <1> cmp eax,(1 << 16) ; Max 64K in one transfer
6715 6715 00001E02 7606 <1> jna .size_ok
6716 6716 00001E04 66B800000100 <1> mov eax,(1 << 16)
6717 6717 <1> .size_ok:
6718 6718 00001E0A 6650 <1> push eax ; <B> Bytes transferred this chunk
6719 6719 00001E0C 6605FF070000 <1> add eax,SECTOR_SIZE-1
6720 6720 00001E12 66C1E80B <1> shr eax,SECTOR_SHIFT ; Convert to sectors
6721 6721 <1>
6722 6722 <1> ; Now (e)ax contains the number of sectors to get
6723 6723 00001E16 6657 <1> push edi ; <C> Target buffer
6724 6724 00001E18 89C1 <1> mov cx,ax
6725 6725 00001E1A 31DB <1> xor bx,bx ; ES:0
6726 6726 00001E1C E87FF8 <1> call getfssec ; Load the data into xfer_buf_seg
6727 6727 00001E1F 665F <1> pop edi ; <C> Target buffer
6728 6728 00001E21 6659 <1> pop ecx ; <B> Byte count this round
6729 6729 00001E23 6651 <1> push ecx ; <B> Byte count this round
6730 6730 00001E25 6657 <1> push edi ; <C> Target buffer
6731 6731 <1> .fix_slop:
6732 6732 00001E27 85D1 <1> test cx,dx
6733 6733 00001E29 7409 <1> jz .noslop
6734 6734 <1> ; The last dword fractional - pad with zeroes
6735 6735 <1> ; Zero-padding is critical for multi-file initramfs.
6736 6736 00001E2B 2667C60100 <1> mov byte [es:ecx],0
6737 6737 00001E30 6641 <1> inc ecx
6738 6738 00001E32 EBF3 <1> jmp short .fix_slop
6739 6739 <1> .noslop:
6740 6740 00001E34 6656 <1> push esi ; <D> File handle/cluster pointer
6741 6741 00001E36 66BE00000100 <1> mov esi,(xfer_buf_seg << 4) ; Source address
6742 6742 00001E3C E8(3000) <1> call bcopy ; Copy to high memory
6743 6743 00001E3F 665E <1> pop esi ; <D> File handle/cluster pointer
6744 6744 00001E41 665F <1> pop edi ; <C> Target buffer
6745 6745 00001E43 6659 <1> pop ecx ; <B> Byte count this round
6746 6746 00001E45 6658 <1> pop eax ; <A> Total bytes to transfer
6747 6747 00001E47 6601CF <1> add edi,ecx
6748 6748 00001E4A 6629C8 <1> sub eax,ecx
6749 6749 00001E4D 759C <1> jnz .read_loop ; More to read...
6750 6750 <1>
6751 6751 <1> .eof:
6752 6752 00001E4F 07 <1> pop es
6753 6753 00001E50 C3 <1> ret
6754 6754 <1>
6755 6755 %include "font.inc" ; VGA font stuff
6756 6756 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
6757 6757 <1> ;; -----------------------------------------------------------------------
6758 6758 <1> ;;
6759 6759 <1> ;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
6760 6760 <1> ;;
6761 6761 <1> ;; This program is free software; you can redistribute it and/or modify
6762 6762 <1> ;; it under the terms of the GNU General Public License as published by
6763 6763 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
6764 6764 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
6765 6765 <1> ;; (at your option) any later version; incorporated herein by reference.
6766 6766 <1> ;;
6767 6767 <1> ;; -----------------------------------------------------------------------
6768 6768 <1>
6769 6769 <1> ;;
6770 6770 <1> ;; font.inc
6771 6771 <1> ;;
6772 6772 <1> ;; VGA font handling code
6773 6773 <1> ;;
6774 6774 <1>
6775 6775 <1> section .text
6776 6776 <1>
6777 6777 <1> ;
6778 6778 <1> ; loadfont: Load a .psf font file and install it onto the VGA console
6779 6779 <1> ; (if we're not on a VGA screen then ignore.) It is called with
6780 6780 <1> ; SI and DX:AX set by routine searchdir
6781 6781 <1> ;
6782 6782 <1> loadfont:
6783 6783 00001E51 BB[0000] <1> mov bx,trackbuf ; The trackbuf is >= 16K; the part
6784 6784 00001E54 8B0E[4405] <1> mov cx,[BufSafe] ; of a PSF file we care about is no
6785 6785 00001E58 E843F8 <1> call getfssec ; more than 8K+4 bytes
6786 6786 <1>
6787 6787 00001E5B A1[0000] <1> mov ax,[trackbuf] ; Magic number
6788 6788 00001E5E 3D3604 <1> cmp ax,0436h
6789 6789 00001E61 755B <1> jne lf_ret
6790 6790 <1>
6791 6791 00001E63 A0[0200] <1> mov al,[trackbuf+2] ; File mode
6792 6792 00001E66 3C05 <1> cmp al,5 ; Font modes 0-5 supported
6793 6793 00001E68 7754 <1> ja lf_ret
6794 6794 <1>
6795 6795 00001E6A 8A3E[0300] <1> mov bh,byte [trackbuf+3] ; Height of font
6796 6796 00001E6E 80FF02 <1> cmp bh,2 ; VGA minimum
6797 6797 00001E71 724B <1> jb lf_ret
6798 6798 00001E73 80FF20 <1> cmp bh,32 ; VGA maximum
6799 6799 00001E76 7746 <1> ja lf_ret
6800 6800 <1>
6801 6801 <1> ; Copy to font buffer
6802 6802 00001E78 BE[0400] <1> mov si,trackbuf+4 ; Start of font data
6803 6803 00001E7B 883E[BA00] <1> mov [VGAFontSize],bh
6804 6804 00001E7F BF[0C1E] <1> mov di,vgafontbuf
6805 6805 00001E82 B90008 <1> mov cx,(32*256) >> 2 ; Maximum size
6806 6806 00001E85 F366A5 <1> rep movsd
6807 6807 <1>
6808 6808 00001E88 C606[BC00]01 <1> mov [UserFont], byte 1 ; Set font flag
6809 6809 <1>
6810 6810 <1> ; Fall through to use_font
6811 6811 <1>
6812 6812 <1> ;
6813 6813 <1> ; use_font:
6814 6814 <1> ; This routine activates whatever font happens to be in the
6815 6815 <1> ; vgafontbuf, and updates the adjust_screen data.
6816 6816 <1> ; Must be called with CS = DS = ES
6817 6817 <1> ;
6818 6818 <1> use_font:
6819 6819 00001E8D F606[BC00]01 <1> test [UserFont], byte 1 ; Are we using a user-specified font?
6820 6820 00001E92 743C <1> jz adjust_screen ; If not, just do the normal stuff
6821 6821 <1>
6822 6822 00001E94 BD[0C1E] <1> mov bp,vgafontbuf
6823 6823 00001E97 8A3E[BA00] <1> mov bh,[VGAFontSize]
6824 6824 <1>
6825 6825 00001E9B 30DB <1> xor bl,bl ; Needed by both INT 10h calls
6826 6826 00001E9D 803E[CE00]01 <1> cmp [UsingVGA], byte 1 ; Are we in graphics mode?
6827 6827 00001EA2 751B <1> jne .text
6828 6828 <1>
6829 6829 <1> .graphics:
6830 6830 00001EA4 31C9 <1> xor cx,cx
6831 6831 00001EA6 88F9 <1> mov cl,bh ; CX = bytes/character
6832 6832 00001EA8 B8E001 <1> mov ax,480
6833 6833 00001EAB F6F1 <1> div cl ; Compute char rows per screen
6834 6834 00001EAD 88C2 <1> mov dl,al
6835 6835 00001EAF FEC8 <1> dec al
6836 6836 00001EB1 A2[5103] <1> mov [VidRows],al
6837 6837 00001EB4 B82111 <1> mov ax,1121h ; Set user character table
6838 6838 00001EB7 CD10 <1> int 10h
6839 6839 00001EB9 C606[5003]4F <1> mov [VidCols], byte 79 ; Always 80 bytes/line
6840 6840 00001EBE C3 <1> .lf_ret: ret ; No need to call adjust_screen
6841 6841 <1>
6842 6842 <1> .text:
6843 6843 00001EBF B90001 <1> mov cx,256
6844 6844 00001EC2 31D2 <1> xor dx,dx
6845 6845 00001EC4 B81011 <1> mov ax,1110h
6846 6846 00001EC7 CD10 <1> int 10h ; Load into VGA RAM
6847 6847 <1>
6848 6848 00001EC9 30DB <1> xor bl,bl
6849 6849 00001ECB B80311 <1> mov ax,1103h ; Select page 0
6850 6850 00001ECE CD10 <1> int 10h
6851 6851 <1>
6852 6852 <1> ; Fall through to adjust_screen
6853 6853 <1>
6854 6854 <1> lf_ret equ use_font.lf_ret
6855 6855 <1>
6856 6856 <1> ;
6857 6857 <1> ; adjust_screen: Set the internal variables associated with the screen size.
6858 6858 <1> ; This is a subroutine in case we're loading a custom font.
6859 6859 <1> ;
6860 6860 <1> adjust_screen:
6861 6861 00001ED0 60 <1> pusha
6862 6862 00001ED1 A08404 <1> mov al,[BIOS_vidrows]
6863 6863 00001ED4 20C0 <1> and al,al
6864 6864 00001ED6 7502 <1> jnz vidrows_ok
6865 6865 00001ED8 B018 <1> mov al,24 ; No vidrows in BIOS, assume 25
6866 6866 <1> ; (Remember: vidrows == rows-1)
6867 6867 00001EDA A2[5103] <1> vidrows_ok: mov [VidRows],al
6868 6868 00001EDD B40F <1> mov ah,0fh
6869 6869 00001EDF CD10 <1> int 10h ; Read video state
6870 6870 00001EE1 FECC <1> dec ah ; Store count-1 (same as rows)
6871 6871 00001EE3 8826[5003] <1> mov [VidCols],ah
6872 6872 00001EE7 61 <1> popa
6873 6873 00001EE8 C3 <1> ret
6874 6874 <1>
6875 6875 <1>
6876 6876 <1> ; VGA font buffer at the end of memory (so loading a font works even
6877 6877 <1> ; in graphics mode, but don't put too much pressure on the .bss)
6878 6878 <1> section .latebss
6879 6879 00001E0C <res 00002000> <1> vgafontbuf resb 8192
6880 6880 <1>
6881 6881 <1> section .data
6882 6882 000000B9 00 <1> align 2, db 0
6883 6883 000000BA 1000 <1> VGAFontSize dw 16 ; Defaults to 16 byte font
6884 6884 000000BC 00 <1> UserFont db 0 ; Using a user-specified font
6885 6885 <1>
6886 6886 <1>
6887 6887 %include "graphics.inc" ; VGA graphics
6888 6888 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
6889 6889 <1> ;; -----------------------------------------------------------------------
6890 6890 <1> ;;
6891 6891 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
6892 6892 <1> ;;
6893 6893 <1> ;; This program is free software; you can redistribute it and/or modify
6894 6894 <1> ;; it under the terms of the GNU General Public License as published by
6895 6895 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
6896 6896 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
6897 6897 <1> ;; (at your option) any later version; incorporated herein by reference.
6898 6898 <1> ;;
6899 6899 <1> ;; -----------------------------------------------------------------------
6900 6900 <1>
6901 6901 <1> ; ----------------------------------------------------------------------------
6902 6902 <1> ; VGA splash screen code
6903 6903 <1> ; ----------------------------------------------------------------------------
6904 6904 <1>
6905 6905 <1> ;
6906 6906 <1> ; vgadisplayfile:
6907 6907 <1> ; Display a graphical splash screen.
6908 6908 <1> ;
6909 6909 <1> ; Input:
6910 6910 <1> ;
6911 6911 <1> ; SI = cluster/socket pointer
6912 6912 <1> ;
6913 6913 <1> section .text
6914 6914 <1>
6915 6915 <1> vgadisplayfile:
6916 6916 00001EE9 8936[103E] <1> mov [VGACluster],si
6917 6917 00001EED 06 <1> push es
6918 6918 <1>
6919 6919 <1> ; This is a cheap and easy way to make sure the screen is
6920 6920 <1> ; cleared in case we were in graphics mode already
6921 6921 00001EEE E87E01 <1> call vgaclearmode
6922 6922 00001EF1 E84D01 <1> call vgasetmode
6923 6923 00001EF4 7514 <1> jnz .error_nz
6924 6924 <1>
6925 6925 <1> .graphalready:
6926 6926 00001EF6 B80010 <1> mov ax,xfer_buf_seg ; Use as temporary storage
6927 6927 00001EF9 8EC0 <1> mov es,ax
6928 6928 00001EFB 8EE0 <1> mov fs,ax
6929 6929 <1>
6930 6930 00001EFD E8F300 <1> call vgagetchunk ; Get the first chunk
6931 6931 <1>
6932 6932 <1> ; The header WILL be in the first chunk.
6933 6933 00001F00 2666813E00203DF313- <1> cmp dword [es:xbs_vgabuf],0x1413f33d ; Magic number
6934 6934 00001F09 14 <1>
6935 6935 00001F0A 757D <1> .error_nz: jne .error
6936 6936 00001F0C 26A10420 <1> mov ax,[es:xbs_vgabuf+4]
6937 6937 00001F10 A3[0C3E] <1> mov [GraphXSize],ax
6938 6938 <1>
6939 6939 00001F13 BA0820 <1> mov dx,xbs_vgabuf+8 ; Color map offset
6940 6940 00001F16 B81210 <1> mov ax,1012h ; Set RGB registers
6941 6941 00001F19 31DB <1> xor bx,bx ; First register number
6942 6942 00001F1B B91000 <1> mov cx,16 ; 16 registers
6943 6943 00001F1E CD10 <1> int 10h
6944 6944 <1>
6945 6945 <1> .movecursor:
6946 6946 00001F20 26A10620 <1> mov ax,[es:xbs_vgabuf+6] ; Number of pixel rows
6947 6947 00001F24 8B16[BA00] <1> mov dx,[VGAFontSize]
6948 6948 00001F28 01D0 <1> add ax,dx
6949 6949 00001F2A 48 <1> dec ax
6950 6950 00001F2B F6F2 <1> div dl
6951 6951 00001F2D 31D2 <1> xor dx,dx ; Set column to 0
6952 6952 00001F2F 3A06[5103] <1> cmp al,[VidRows]
6953 6953 00001F33 7205 <1> jb .rowsok
6954 6954 00001F35 A0[5103] <1> mov al,[VidRows]
6955 6955 00001F38 FEC8 <1> dec al
6956 6956 <1> .rowsok:
6957 6957 00001F3A 88C6 <1> mov dh,al
6958 6958 00001F3C B402 <1> mov ah,2
6959 6959 00001F3E 31DB <1> xor bx,bx
6960 6960 00001F40 CD10 <1> int 10h ; Set cursor below image
6961 6961 <1>
6962 6962 00001F42 268B0E0620 <1> mov cx,[es:xbs_vgabuf+6] ; Number of graphics rows
6963 6963 <1>
6964 6964 00001F47 BE3820 <1> mov si,xbs_vgabuf+8+3*16 ; Beginning of pixel data
6965 6965 00001F4A C706[0E3E]0000 <1> mov word [VGAPos],0
6966 6966 <1>
6967 6967 <1> .drawpixelrow:
6968 6968 00001F50 51 <1> push cx
6969 6969 00001F51 8B0E[0C3E] <1> mov cx,[GraphXSize]
6970 6970 00001F55 BF0040 <1> mov di,xbs_vgatmpbuf ; Row buffer
6971 6971 00001F58 E83000 <1> call rledecode ; Decode one row
6972 6972 00001F5B 56 <1> push si
6973 6973 00001F5C BE0040 <1> mov si,xbs_vgatmpbuf
6974 6974 00001F5F 89F7 <1> mov di,si
6975 6975 00001F61 033E[0C3E] <1> add di,[GraphXSize]
6976 6976 00001F65 B9A000 <1> mov cx,640/4
6977 6977 00001F68 6631C0 <1> xor eax,eax
6978 6978 00001F6B F366AB <1> rep stosd ; Clear rest of row
6979 6979 00001F6E BF00A0 <1> mov di,0A000h ; VGA segment
6980 6980 00001F71 8EC7 <1> mov es,di
6981 6981 00001F73 8B3E[0E3E] <1> mov di,[VGAPos]
6982 6982 00001F77 BD8002 <1> mov bp,640
6983 6983 00001F7A E89500 <1> call packedpixel2vga
6984 6984 00001F7D 8306[0E3E]50 <1> add word [VGAPos],byte 80 ; Advance to next pixel row
6985 6985 00001F82 0FA0 <1> push fs
6986 6986 00001F84 07 <1> pop es
6987 6987 00001F85 5E <1> pop si
6988 6988 00001F86 59 <1> pop cx
6989 6989 00001F87 E2C7 <1> loop .drawpixelrow
6990 6990 <1>
6991 6991 <1> .error:
6992 6992 00001F89 07 <1> pop es
6993 6993 00001F8A C3 <1> ret
6994 6994 <1>
6995 6995 <1> ;
6996 6996 <1> ; rledecode:
6997 6997 <1> ; Decode a pixel row in RLE16 format.
6998 6998 <1> ;
6999 6999 <1> ; FS:SI -> input
7000 7000 <1> ; CX -> pixel count
7001 7001 <1> ; ES:DI -> output (packed pixel)
7002 7002 <1> ;
7003 7003 <1> rledecode:
7004 7004 00001F8B 66D1E6 <1> shl esi,1 ; Nybble pointer
7005 7005 00001F8E 30D2 <1> xor dl,dl ; Last pixel
7006 7006 <1> .loop:
7007 7007 00001F90 E83E00 <1> call .getnybble
7008 7008 00001F93 38D0 <1> cmp al,dl
7009 7009 00001F95 740D <1> je .run ; Start of run sequence
7010 7010 00001F97 AA <1> stosb
7011 7011 00001F98 88C2 <1> mov dl,al
7012 7012 00001F9A 49 <1> dec cx
7013 7013 00001F9B 75F3 <1> jnz .loop
7014 7014 <1> .done:
7015 7015 00001F9D 66D1EE <1> shr esi,1
7016 7016 00001FA0 83D600 <1> adc si,byte 0
7017 7017 00001FA3 C3 <1> ret
7018 7018 <1> .run:
7019 7019 00001FA4 31DB <1> xor bx,bx
7020 7020 00001FA6 E82800 <1> call .getnybble
7021 7021 00001FA9 20C0 <1> and al,al
7022 7022 00001FAB 7410 <1> jz .longrun
7023 7023 00001FAD 88C3 <1> mov bl,al
7024 7024 <1> .dorun:
7025 7025 00001FAF 51 <1> push cx
7026 7026 00001FB0 89D9 <1> mov cx,bx
7027 7027 00001FB2 88D0 <1> mov al,dl
7028 7028 00001FB4 F3AA <1> rep stosb
7029 7029 00001FB6 59 <1> pop cx
7030 7030 00001FB7 29D9 <1> sub cx,bx
7031 7031 00001FB9 77D5 <1> ja .loop
7032 7032 00001FBB EBE0 <1> jmp short .done
7033 7033 <1> .longrun:
7034 7034 00001FBD E81100 <1> call .getnybble
7035 7035 00001FC0 88C4 <1> mov ah,al
7036 7036 00001FC2 E80C00 <1> call .getnybble
7037 7037 00001FC5 C0E004 <1> shl al,4
7038 7038 00001FC8 08E0 <1> or al,ah
7039 7039 00001FCA 88C3 <1> mov bl,al
7040 7040 00001FCC 83C310 <1> add bx,16
7041 7041 00001FCF EBDE <1> jmp short .dorun
7042 7042 <1> .getnybble:
7043 7043 00001FD1 66D1EE <1> shr esi,1
7044 7044 00001FD4 64AC <1> fs lodsb
7045 7045 00001FD6 7208 <1> jc .high
7046 7046 00001FD8 4E <1> dec si
7047 7047 00001FD9 240F <1> and al,0Fh
7048 7048 00001FDB F9 <1> stc
7049 7049 00001FDC 66D1D6 <1> rcl esi,1
7050 7050 00001FDF C3 <1> ret
7051 7051 <1> .high:
7052 7052 00001FE0 C0E804 <1> shr al,4
7053 7053 00001FE3 81FE0040 <1> cmp si,xbs_vgabuf+trackbufsize ; Chunk overrun
7054 7054 00001FE7 7206 <1> jb .nonewchunk
7055 7055 00001FE9 E80700 <1> call vgagetchunk
7056 7056 00001FEC BE0020 <1> mov si,xbs_vgabuf ; Start at beginning of buffer
7057 7057 <1> .nonewchunk:
7058 7058 00001FEF 66D1E6 <1> shl esi,1
7059 7059 00001FF2 C3 <1> ret
7060 7060 <1>
7061 7061 <1> ;
7062 7062 <1> ; vgagetchunk:
7063 7063 <1> ; Get a new trackbufsize chunk of VGA image data
7064 7064 <1> ;
7065 7065 <1> ; On input, ES is assumed to point to the buffer segment.
7066 7066 <1> ;
7067 7067 <1> vgagetchunk:
7068 7068 00001FF3 6660 <1> pushad
7069 7069 00001FF5 8B36[103E] <1> mov si,[VGACluster]
7070 7070 00001FF9 21F6 <1> and si,si
7071 7071 00001FFB 7412 <1> jz .eof ; EOF overrun, not much to do...
7072 7072 <1>
7073 7073 00001FFD 8B0E[4405] <1> mov cx,[BufSafe] ; One trackbuf worth of data
7074 7074 00002001 BB0020 <1> mov bx,xbs_vgabuf
7075 7075 00002004 E897F6 <1> call getfssec
7076 7076 <1>
7077 7077 00002007 7302 <1> jnc .noteof
7078 7078 00002009 31F6 <1> xor si,si
7079 7079 0000200B 8936[103E] <1> .noteof: mov [VGACluster],si
7080 7080 <1>
7081 7081 0000200F 6661 <1> .eof: popad
7082 7082 00002011 C3 <1> ret
7083 7083 <1>
7084 7084 <1> ;
7085 7085 <1> ; packedpixel2vga:
7086 7086 <1> ; Convert packed-pixel to VGA bitplanes
7087 7087 <1> ;
7088 7088 <1> ; FS:SI -> packed pixel string
7089 7089 <1> ; BP -> pixel count (multiple of 8)
7090 7090 <1> ; ES:DI -> output
7091 7091 <1> ;
7092 7092 <1> packedpixel2vga:
7093 7093 00002012 BAC403 <1> mov dx,3C4h ; VGA Sequencer Register select port
7094 7094 00002015 B002 <1> mov al,2 ; Sequencer mask
7095 7095 00002017 EE <1> out dx,al ; Select the sequencer mask
7096 7096 00002018 42 <1> inc dx ; VGA Sequencer Register data port
7097 7097 00002019 B001 <1> mov al,1
7098 7098 0000201B 88C3 <1> mov bl,al
7099 7099 <1> .planeloop:
7100 7100 0000201D 60 <1> pusha
7101 7101 0000201E EE <1> out dx,al
7102 7102 <1> .loop1:
7103 7103 0000201F B90800 <1> mov cx,8
7104 7104 <1> .loop2:
7105 7105 00002022 87CB <1> xchg cx,bx
7106 7106 00002024 64AC <1> fs lodsb
7107 7107 00002026 D2E8 <1> shr al,cl
7108 7108 00002028 D0D5 <1> rcl ch,1 ; VGA is bigendian. Sigh.
7109 7109 0000202A 87CB <1> xchg cx,bx
7110 7110 0000202C E2F4 <1> loop .loop2
7111 7111 0000202E 88F8 <1> mov al,bh
7112 7112 00002030 AA <1> stosb
7113 7113 00002031 83ED08 <1> sub bp,byte 8
7114 7114 00002034 77E9 <1> ja .loop1
7115 7115 00002036 61 <1> popa
7116 7116 00002037 FEC3 <1> inc bl
7117 7117 00002039 D0E0 <1> shl al,1
7118 7118 0000203B 80FB04 <1> cmp bl,4
7119 7119 0000203E 76DD <1> jbe .planeloop
7120 7120 00002040 C3 <1> ret
7121 7121 <1>
7122 7122 <1> ;
7123 7123 <1> ; vgasetmode:
7124 7124 <1> ; Enable VGA graphics, if possible; return ZF=1 on success
7125 7125 <1> ; DS must be set to the base segment; ES is set to DS.
7126 7126 <1> ;
7127 7127 <1> vgasetmode:
7128 7128 00002041 1E <1> push ds
7129 7129 00002042 07 <1> pop es
7130 7130 00002043 B8001A <1> mov ax,1A00h ; Get video card and monitor
7131 7131 00002046 31DB <1> xor bx,bx
7132 7132 00002048 CD10 <1> int 10h
7133 7133 0000204A 80EB07 <1> sub bl, 7 ; BL=07h and BL=08h OK
7134 7134 0000204D 80FB01 <1> cmp bl, 1
7135 7135 00002050 771C <1> ja .error ; ZF=0
7136 7136 <1> ; mov bx,TextColorReg
7137 7137 <1> ; mov dx,1009h ; Read color registers
7138 7138 <1> ; int 10h
7139 7139 00002052 B81200 <1> mov ax,0012h ; Set mode = 640x480 VGA 16 colors
7140 7140 00002055 CD10 <1> int 10h
7141 7141 00002057 BA[BD00] <1> mov dx,linear_color
7142 7142 0000205A B80210 <1> mov ax,1002h ; Write color registers
7143 7143 0000205D CD10 <1> int 10h
7144 7144 0000205F C606[CE00]01 <1> mov [UsingVGA], byte 1
7145 7145 <1>
7146 7146 00002064 E826FE <1> call use_font ; Set graphics font/data
7147 7147 00002067 C606[7400]00 <1> mov byte [ScrollAttribute], 00h
7148 7148 <1>
7149 7149 0000206C 31C0 <1> xor ax,ax ; Set ZF
7150 7150 <1> .error:
7151 7151 0000206E C3 <1> ret
7152 7152 <1>
7153 7153 <1> ;
7154 7154 <1> ; vgaclearmode:
7155 7155 <1> ; Disable VGA graphics. It is not safe to assume any value
7156 7156 <1> ; for DS or ES.
7157 7157 <1> ;
7158 7158 <1> vgaclearmode:
7159 7159 0000206F 1E <1> push ds
7160 7160 00002070 06 <1> push es
7161 7161 00002071 6660 <1> pushad
7162 7162 00002073 8CC8 <1> mov ax,cs
7163 7163 00002075 8ED8 <1> mov ds,ax
7164 7164 00002077 8EC0 <1> mov es,ax
7165 7165 00002079 803E[CE00]01 <1> cmp [UsingVGA], byte 1
7166 7166 0000207E 7512 <1> jne .done
7167 7167 00002080 B80300 <1> mov ax,0003h ; Return to normal video mode
7168 7168 00002083 CD10 <1> int 10h
7169 7169 <1> ; mov dx,TextColorReg ; Restore color registers
7170 7170 <1> ; mov ax,1002h
7171 7171 <1> ; int 10h
7172 7172 00002085 C606[CE00]00 <1> mov [UsingVGA], byte 0
7173 7173 <1>
7174 7174 0000208A E800FE <1> call use_font ; Restore text font/data
7175 7175 0000208D C606[7400]07 <1> mov byte [ScrollAttribute], 07h
7176 7176 <1> .done:
7177 7177 00002092 6661 <1> popad
7178 7178 00002094 07 <1> pop es
7179 7179 00002095 1F <1> pop ds
7180 7180 00002096 C3 <1> ret
7181 7181 <1>
7182 7182 <1> ;
7183 7183 <1> ; vgashowcursor/vgahidecursor:
7184 7184 <1> ; If VGA graphics is enabled, draw a cursor/clear a cursor
7185 7185 <1> ;
7186 7186 <1> vgashowcursor:
7187 7187 00002097 6660 <1> pushad
7188 7188 00002099 B05F <1> mov al,'_'
7189 7189 0000209B EB04 <1> jmp short vgacursorcommon
7190 7190 <1> vgahidecursor:
7191 7191 0000209D 6660 <1> pushad
7192 7192 0000209F B020 <1> mov al,' '
7193 7193 <1> vgacursorcommon:
7194 7194 000020A1 803E[CE00]01 <1> cmp [UsingVGA], byte 1
7195 7195 000020A6 750A <1> jne .done
7196 7196 000020A8 B409 <1> mov ah,09h
7197 7197 000020AA BB0700 <1> mov bx,0007h
7198 7198 000020AD B90100 <1> mov cx,1
7199 7199 000020B0 CD10 <1> int 10h
7200 7200 <1> .done:
7201 7201 000020B2 6661 <1> popad
7202 7202 000020B4 C3 <1> ret
7203 7203 <1>
7204 7204 <1>
7205 7205 <1> section .data
7206 7206 <1> ; Map colors to consecutive DAC registers
7207 7207 000000BD 000102030405060708- <1> linear_color db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
7208 7208 000000C6 090A0B0C0D0E0F00 <1>
7209 7209 000000CE 00 <1> UsingVGA db 0
7210 7210 <1>
7211 7211 <1> section .latebss
7212 7212 <1> alignb 2
7213 7213 00003E0C <res 00000002> <1> GraphXSize resw 1 ; Width of splash screen file
7214 7214 00003E0E <res 00000002> <1> VGAPos resw 1 ; Pointer into VGA memory
7215 7215 00003E10 <res 00000002> <1> VGACluster resw 1 ; Cluster pointer for VGA image file
7216 7216 00003E12 <res 00000002> <1> VGAFilePtr resw 1 ; Pointer into VGAFileBuf
7217 7217 00003E14 <res 00000011> <1> TextColorReg resb 17 ; VGA color registers for text mode
7218 7218 <1> %if IS_SYSLINUX
7219 7219 <1> VGAFileBuf resb FILENAME_MAX+2 ; Unmangled VGA image name
7220 7220 <1> %else
7221 7221 00003E25 <res 00000100> <1> VGAFileBuf resb FILENAME_MAX ; Unmangled VGA image name
7222 7222 <1> %endif
7223 7223 <1> VGAFileBufEnd equ $
7224 7224 00003F25 <res 00000100> <1> VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name
7225 7225 <1>
7226 7226 %include "highmem.inc" ; High memory sizing
7227 7227 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
7228 7228 <1> ;; -----------------------------------------------------------------------
7229 7229 <1> ;;
7230 7230 <1> ;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
7231 7231 <1> ;;
7232 7232 <1> ;; This program is free software; you can redistribute it and/or modify
7233 7233 <1> ;; it under the terms of the GNU General Public License as published by
7234 7234 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
7235 7235 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
7236 7236 <1> ;; (at your option) any later version; incorporated herein by reference.
7237 7237 <1> ;;
7238 7238 <1> ;; -----------------------------------------------------------------------
7239 7239 <1>
7240 7240 <1> ;;
7241 7241 <1> ;; highmem.inc
7242 7242 <1> ;;
7243 7243 <1> ;; Probe for the size of high memory. This can be overridden by a
7244 7244 <1> ;; mem= command on the command line while booting a new kernel.
7245 7245 <1> ;;
7246 7246 <1>
7247 7247 <1> section .text
7248 7248 <1>
7249 7249 <1> ;
7250 7250 <1> ; This is set up as a subroutine; it will set up the global variable
7251 7251 <1> ; HighMemSize. All registers are preserved. Assumes DS == CS.
7252 7252 <1> ;
7253 7253 <1> highmemsize:
7254 7254 000020B5 06 <1> push es
7255 7255 000020B6 6660 <1> pushad
7256 7256 <1>
7257 7257 <1> ;
7258 7258 <1> ; First, try INT 15:E820 (get BIOS memory map)
7259 7259 <1> ;
7260 7260 <1> get_e820:
7261 7261 000020B8 6631DB <1> xor ebx,ebx ; Start with first record
7262 7262 000020BB 66C706[7403]0000F0- <1> mov dword [E820Max],-(1 << 20) ; Max amount of high memory
7263 7263 000020C3 FF <1>
7264 7264 000020C4 66891E[7003] <1> mov dword [E820Mem],ebx ; Detected amount of high memory
7265 7265 000020C9 8EC3 <1> mov es,bx ; Need ES = DS = 0 for now
7266 7266 000020CB EB05 <1> jmp short .do_e820 ; Skip "at end" check first time!
7267 7267 000020CD 6621DB <1> .int_loop: and ebx,ebx ; If we're back at beginning...
7268 7268 000020D0 7478 <1> jz .e820_done ; ... we're done
7269 7269 000020D2 66B820E80000 <1> .do_e820: mov eax,0000E820h
7270 7270 000020D8 66BA50414D53 <1> mov edx,534D4150h ; "SMAP" backwards
7271 7271 000020DE 6631C9 <1> xor ecx,ecx
7272 7272 000020E1 B114 <1> mov cl,20 ; ECX <- 20
7273 7273 000020E3 BF[5C03] <1> mov di,E820Buf
7274 7274 000020E6 CD15 <1> int 15h
7275 7275 000020E8 7307 <1> jnc .no_carry
7276 7276 <1> ; If carry, ebx == 0 means error, ebx != 0 means we're done
7277 7277 000020EA 6621DB <1> and ebx,ebx
7278 7278 000020ED 755B <1> jnz .e820_done
7279 7279 000020EF EB6F <1> jmp no_e820
7280 7280 <1> .no_carry:
7281 7281 000020F1 663D50414D53 <1> cmp eax,534D4150h
7282 7282 000020F7 7567 <1> jne no_e820
7283 7283 <1> ;
7284 7284 <1> ; Look for a memory block starting at <= 1 MB and continuing upward
7285 7285 <1> ;
7286 7286 000020F9 66833E[6003]00 <1> cmp dword [E820Buf+4], byte 0
7287 7287 000020FF 77CC <1> ja .int_loop ; Start >= 4 GB?
7288 7288 00002101 66BA00001000 <1> mov edx, (1 << 20)
7289 7289 00002107 662B16[5C03] <1> sub edx, [E820Buf]
7290 7290 0000210C 7319 <1> jnb .ram_range ; Start >= 1 MB?
7291 7291 <1> ; If we get here, it starts > 1 MB but < 4 GB; if this is a
7292 7292 <1> ; *non*-memory range, remember this as unusable; some BIOSes
7293 7293 <1> ; get the length of primary RAM wrong!
7294 7294 0000210E 66833E[6C03]01 <1> cmp dword [E820Buf+16], byte 1
7295 7295 00002114 74B7 <1> je .int_loop ; If it's memory, don't worry about it
7296 7296 00002116 66F7DA <1> neg edx ; This means what for memory limit?
7297 7297 00002119 663B16[7403] <1> cmp edx,[E820Max] ; Better or worse
7298 7298 0000211E 73AD <1> jnb .int_loop
7299 7299 00002120 668916[7403] <1> mov [E820Max],edx
7300 7300 00002125 EBA6 <1> jmp .int_loop
7301 7301 <1>
7302 7302 <1> .ram_range:
7303 7303 00002127 F9 <1> stc
7304 7304 00002128 6619C0 <1> sbb eax,eax ; eax <- 0xFFFFFFFF
7305 7305 0000212B 66833E[6803]00 <1> cmp dword [E820Buf+12], byte 0
7306 7306 00002131 7704 <1> ja .huge ; Size >= 4 GB
7307 7307 00002133 66A1[6403] <1> mov eax, [E820Buf+8]
7308 7308 00002137 6629D0 <1> .huge: sub eax, edx ; Adjust size to start at 1 MB
7309 7309 0000213A 7691 <1> jbe .int_loop ; Completely below 1 MB?
7310 7310 <1>
7311 7311 <1> ; Now EAX contains the size of memory 1 MB...up
7312 7312 0000213C 66833E[6C03]01 <1> cmp dword [E820Buf+16], byte 1
7313 7313 00002142 7589 <1> jne .int_loop ; High memory isn't usable memory!!!!
7314 7314 <1>
7315 7315 <1> ; We're good!
7316 7316 00002144 66A3[7003] <1> mov [E820Mem],eax
7317 7317 00002148 EB83 <1> jmp .int_loop ; Still need to add low 1 MB
7318 7318 <1>
7319 7319 <1> .e820_done:
7320 7320 0000214A 66A1[7003] <1> mov eax,[E820Mem]
7321 7321 0000214E 6621C0 <1> and eax,eax
7322 7322 00002151 740D <1> jz no_e820 ; Nothing found by E820?
7323 7323 00002153 663B06[7403] <1> cmp eax,[E820Max] ; Make sure we're not limited
7324 7324 00002158 7638 <1> jna got_highmem_add1mb
7325 7325 0000215A 66A1[7403] <1> mov eax,[E820Max]
7326 7326 0000215E EB32 <1> jmp got_highmem_add1mb
7327 7327 <1>
7328 7328 <1> ;
7329 7329 <1> ; INT 15:E820 failed. Try INT 15:E801.
7330 7330 <1> ;
7331 7331 <1> no_e820:
7332 7332 00002160 B801E8 <1> mov ax,0e801h ; Query high memory (semi-recent)
7333 7333 00002163 CD15 <1> int 15h
7334 7334 00002165 7215 <1> jc no_e801
7335 7335 00002167 3D003C <1> cmp ax,3c00h
7336 7336 0000216A 7710 <1> ja no_e801 ; > 3C00h something's wrong with this call
7337 7337 0000216C 721A <1> jb e801_hole ; If memory hole we can only use low part
7338 7338 <1>
7339 7339 0000216E 89D8 <1> mov ax,bx
7340 7340 00002170 66C1E010 <1> shl eax,16 ; 64K chunks
7341 7341 00002174 660500000001 <1> add eax,(16 << 20) ; Add first 16M
7342 7342 0000217A EB1C <1> jmp short got_highmem
7343 7343 <1>
7344 7344 <1> ;
7345 7345 <1> ; INT 15:E801 failed. Try INT 15:88.
7346 7346 <1> ;
7347 7347 <1> no_e801:
7348 7348 0000217C B488 <1> mov ah,88h ; Query high memory (oldest)
7349 7349 0000217E CD15 <1> int 15h
7350 7350 00002180 3D0038 <1> cmp ax,14*1024 ; Don't trust memory >15M
7351 7351 00002183 7603 <1> jna e801_hole
7352 7352 00002185 B80038 <1> mov ax,14*1024
7353 7353 <1> e801_hole:
7354 7354 00002188 6625FFFF0000 <1> and eax,0ffffh
7355 7355 0000218E 66C1E00A <1> shl eax,10 ; Convert from kilobytes
7356 7356 <1> got_highmem_add1mb:
7357 7357 00002192 660500001000 <1> add eax,(1 << 20) ; First megabyte
7358 7358 <1> got_highmem:
7359 7359 <1> %if HIGHMEM_SLOP != 0
7360 7360 00002198 662D00000200 <1> sub eax,HIGHMEM_SLOP
7361 7361 <1> %endif
7362 7362 0000219E 66A3[7803] <1> mov [HighMemSize],eax
7363 7363 000021A2 6661 <1> popad
7364 7364 000021A4 07 <1> pop es
7365 7365 000021A5 C3 <1> ret ; Done!
7366 7366 <1>
7367 7367 <1> section .bss
7368 7368 00000359 <res 00000001>- <1> alignb 4
7369 7369 00000359 <rept> <1>
7370 7370 0000035C <res 00000014> <1> E820Buf resd 5 ; INT 15:E820 data buffer
7371 7371 00000370 <res 00000004> <1> E820Mem resd 1 ; Memory detected by E820
7372 7372 00000374 <res 00000004> <1> E820Max resd 1 ; Is E820 memory capped?
7373 7373 00000378 <res 00000004> <1> HighMemSize resd 1 ; End of memory pointer (bytes)
7374 7374 %include "strcpy.inc" ; strcpy()
7375 7375 <1> ;
7376 7376 <1> ; strcpy: Copy DS:SI -> ES:DI up to and including a null byte;
7377 7377 <1> ; on exit SI and DI point to the byte *after* the null byte
7378 7378 <1> ;
7379 7379 <1> section .text
7380 7380 <1>
7381 7381 000021A6 50 <1> strcpy: push ax
7382 7382 000021A7 AC <1> .loop: lodsb
7383 7383 000021A8 AA <1> stosb
7384 7384 000021A9 20C0 <1> and al,al
7385 7385 000021AB 75FA <1> jnz .loop
7386 7386 000021AD 58 <1> pop ax
7387 7387 000021AE C3 <1> ret
7388 7388 <1>
7389 7389 %include "rawcon.inc" ; Console I/O w/o using the console functions
7390 7390 <1> ;
7391 7391 <1> ; writechr: Write a single character in AL to the console without
7392 7392 <1> ; mangling any registers. This does raw console writes,
7393 7393 <1> ; since some PXE BIOSes seem to interfere regular console I/O.
7394 7394 <1> ;
7395 7395 <1> %if IS_ISOLINUX
7396 7396 <1> writechr_full:
7397 7397 <1> %else
7398 7398 <1> writechr:
7399 7399 <1> %endif
7400 7400 000021AF 1E <1> push ds
7401 7401 000021B0 0E <1> push cs
7402 7402 000021B1 1F <1> pop ds
7403 7403 000021B2 E882F8 <1> call write_serial ; write to serial port if needed
7404 7404 000021B5 669C <1> pushfd
7405 7405 000021B7 F606[7200]01 <1> test byte [DisplayCon],01h ; Write to screen?
7406 7406 000021BC 7443 <1> jz .nothing
7407 7407 <1>
7408 7408 000021BE 6660 <1> pushad
7409 7409 000021C0 8A3E6204 <1> mov bh,[BIOS_page]
7410 7410 000021C4 50 <1> push ax
7411 7411 000021C5 B403 <1> mov ah,03h ; Read cursor position
7412 7412 000021C7 CD10 <1> int 10h
7413 7413 000021C9 58 <1> pop ax
7414 7414 000021CA 3C08 <1> cmp al,8
7415 7415 000021CC 7456 <1> je .bs
7416 7416 000021CE 3C0D <1> cmp al,13
7417 7417 000021D0 744E <1> je .cr
7418 7418 000021D2 3C0A <1> cmp al,10
7419 7419 000021D4 7419 <1> je .lf
7420 7420 000021D6 52 <1> push dx
7421 7421 000021D7 8A3E6204 <1> mov bh,[BIOS_page]
7422 7422 000021DB B307 <1> mov bl,07h ; White on black
7423 7423 000021DD B90100 <1> mov cx,1 ; One only
7424 7424 000021E0 B409 <1> mov ah,09h ; Write char and attribute
7425 7425 000021E2 CD10 <1> int 10h
7426 7426 000021E4 5A <1> pop dx
7427 7427 000021E5 FEC2 <1> inc dl
7428 7428 000021E7 3A16[5003] <1> cmp dl,[VidCols]
7429 7429 000021EB 760A <1> jna .curxyok
7430 7430 000021ED 30D2 <1> xor dl,dl
7431 7431 000021EF FEC6 <1> .lf: inc dh
7432 7432 000021F1 3A36[5103] <1> cmp dh,[VidRows]
7433 7433 000021F5 770E <1> ja .scroll
7434 7434 000021F7 8A3E6204 <1> .curxyok: mov bh,[BIOS_page]
7435 7435 000021FB B402 <1> mov ah,02h ; Set cursor position
7436 7436 000021FD CD10 <1> int 10h
7437 7437 000021FF 6661 <1> .ret: popad
7438 7438 <1> .nothing:
7439 7439 00002201 669D <1> popfd
7440 7440 00002203 1F <1> pop ds
7441 7441 00002204 C3 <1> ret
7442 7442 00002205 FECE <1> .scroll: dec dh
7443 7443 00002207 8A3E6204 <1> mov bh,[BIOS_page]
7444 7444 0000220B B402 <1> mov ah,02h
7445 7445 0000220D CD10 <1> int 10h
7446 7446 0000220F B80106 <1> mov ax,0601h ; Scroll up one line
7447 7447 00002212 8A3E[7400] <1> mov bh,[ScrollAttribute]
7448 7448 00002216 31C9 <1> xor cx,cx
7449 7449 00002218 8B16[5003] <1> mov dx,[ScreenSize] ; The whole screen
7450 7450 0000221C CD10 <1> int 10h
7451 7451 0000221E EBDF <1> jmp short .ret
7452 7452 00002220 30D2 <1> .cr: xor dl,dl
7453 7453 00002222 EBD3 <1> jmp short .curxyok
7454 7454 00002224 80EA01 <1> .bs: sub dl,1
7455 7455 00002227 73CE <1> jnc .curxyok
7456 7456 00002229 8A16[5003] <1> mov dl,[VidCols]
7457 7457 0000222D 80EE01 <1> sub dh,1
7458 7458 00002230 73C5 <1> jnc .curxyok
7459 7459 00002232 30F6 <1> xor dh,dh
7460 7460 00002234 EBC1 <1> jmp short .curxyok
7461 7461 <1>
7462 7462
7463 7463 ; -----------------------------------------------------------------------------
7464 7464 ; Begin data section
7465 7465 ; -----------------------------------------------------------------------------
7466 7466
7467 7467 section .data
7468 7468
7469 7469 000000CF 626F6F743A2000 boot_prompt db 'boot: ', 0
7470 7470 000000D6 08200800 wipe_char db BS, ' ', BS, 0
7471 7471 000000DA 436F756C64206E6F74- err_notfound db 'Could not find kernel image: ',0
7472 7472 000000E3 2066696E64206B6572-
7473 7473 000000EC 6E656C20696D616765-
7474 7474 000000F5 3A2000
7475 7475 000000F8 0D0A496E76616C6964- err_notkernel db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0
7476 7476 00000101 206F7220636F727275-
7477 7477 0000010A 7074206B65726E656C-
7478 7478 00000113 20696D6167652E0D0A-
7479 7479 0000011C 00
7480 7480 0000011D 497420617070656172- err_noram db 'It appears your computer has less than '
7481 7481 00000126 7320796F757220636F-
7482 7482 0000012F 6D7075746572206861-
7483 7483 00000138 73206C657373207468-
7484 7484 00000141 616E20
7485 7485 00000144 323536 asciidec dosram_k
7486 7486 00000147 4B206F66206C6F7720- db 'K of low ("DOS")'
7487 7487 00000150 2822444F532229
7488 7488 00000157 0D0A db CR, LF
7489 7489 00000159 52414D2E20204C696E- db 'RAM. Linux needs at least this amount to boot. If you get'
7490 7490 00000162 7578206E6565647320-
7491 7491 0000016B 6174206C6561737420-
7492 7492 00000174 7468697320616D6F75-
7493 7493 0000017D 6E7420746F20626F6F-
7494 7494 00000186 742E2020496620796F-
7495 7495 0000018F 7520676574
7496 7496 00000194 0D0A db CR, LF
7497 7497 00000196 74686973206D657373- db 'this message in error, hold down the Ctrl key while'
7498 7498 0000019F 61676520696E206572-
7499 7499 000001A8 726F722C20686F6C64-
7500 7500 000001B1 20646F776E20746865-
7501 7501 000001BA 204374726C206B6579-
7502 7502 000001C3 207768696C65
7503 7503 000001C9 0D0A db CR, LF
7504 7504 000001CB 626F6F74696E672C20- db 'booting, and I will take your word for it.', CR, LF, 0
7505 7505 000001D4 616E6420492077696C-
7506 7506 000001DD 6C2074616B6520796F-
7507 7507 000001E6 757220776F72642066-
7508 7508 000001EF 6F722069742E0D0A00
7509 7509 000001F8 556E6B6E6F776E206B- err_badcfg db 'Unknown keyword in config file.', CR, LF, 0
7510 7510 00000201 6579776F726420696E-
7511 7511 0000020A 20636F6E6669672066-
7512 7512 00000213 696C652E0D0A00
7513 7513 0000021A 4D697373696E672070- err_noparm db 'Missing parameter in config file.', CR, LF, 0
7514 7514 00000223 6172616D6574657220-
7515 7515 0000022C 696E20636F6E666967-
7516 7516 00000235 2066696C652E0D0A00
7517 7517 0000023E 0D0A436F756C64206E- err_noinitrd db CR, LF, 'Could not find ramdisk image: ', 0
7518 7518 00000247 6F742066696E642072-
7519 7519 00000250 616D6469736B20696D-
7520 7520 00000259 6167653A2000
7521 7521 0000025F 4E6F7420656E6F7567- err_nohighmem db 'Not enough memory to load specified kernel.', CR, LF, 0
7522 7522 00000268 68206D656D6F727920-
7523 7523 00000271 746F206C6F61642073-
7524 7524 0000027A 706563696669656420-
7525 7525 00000283 6B65726E656C2E0D0A-
7526 7526 0000028C 00
7527 7527 0000028D 0D0A4B65726E656C20- err_highload db CR, LF, 'Kernel transfer failure.', CR, LF, 0
7528 7528 00000296 7472616E7366657220-
7529 7529 0000029F 6661696C7572652E0D-
7530 7530 000002A8 0A00
7531 7531 000002AA 43616E6E6F74206C6F- err_oldkernel db 'Cannot load a ramdisk with an old kernel image.'
7532 7532 000002B3 616420612072616D64-
7533 7533 000002BC 69736B207769746820-
7534 7534 000002C5 616E206F6C64206B65-
7535 7535 000002CE 726E656C20696D6167-
7536 7536 000002D7 652E
7537 7537 000002D9 0D0A00 db CR, LF, 0
7538 7538 000002DC 3A20617474656D7074- err_notdos db ': attempted DOS system call', CR, LF, 0
7539 7539 000002E5 656420444F53207379-
7540 7540 000002EE 7374656D2063616C6C-
7541 7541 000002F7 0D0A00
7542 7542 000002FA 434F4D424F4F542069- err_comlarge db 'COMBOOT image too large.', CR, LF, 0
7543 7543 00000303 6D61676520746F6F20-
7544 7544 0000030C 6C617267652E0D0A00
7545 7545 00000315 42535320696D616765- err_bssimage db 'BSS images not supported.', CR, LF, 0
7546 7546 0000031E 73206E6F7420737570-
7547 7547 00000327 706F727465642E0D0A-
7548 7548 00000330 00
7549 7549 00000331 0D0A41323020676174- err_a20 db CR, LF, 'A20 gate not responding!', CR, LF, 0
7550 7550 0000033A 65206E6F7420726573-
7551 7551 00000343 706F6E64696E67210D-
7552 7552 0000034C 0A00
7553 7553 0000034E 6E6F7420666F756E64- notfound_msg db 'not found', CR, LF, 0
7554 7554 00000357 0D0A00
7555 7555 0000035A 426F6F74696E672066- localboot_msg db 'Booting from local disk...', CR, LF, 0
7556 7556 00000363 726F6D206C6F63616C-
7557 7557 0000036C 206469736B2E2E2E0D-
7558 7558 00000375 0A00
7559 7559 00000377 436F6D6D616E64206C- cmdline_msg db 'Command line: ', CR, LF, 0
7560 7560 00000380 696E653A200D0A00
7561 7561 00000388 52656164792E0D0A00 ready_msg db 'Ready.', CR, LF, 0
7562 7562 00000391 547279696E6720746F- trying_msg db 'Trying to load: ', 0
7563 7563 0000039A 206C6F61643A2000
7564 7564 000003A2 0D0A crlfloading_msg db CR, LF ; Fall through
7565 7565 000003A4 4C6F6164696E672000 loading_msg db 'Loading ', 0
7566 7566 000003AD 2E dotdot_msg db '.'
7567 7567 000003AE 2E00 dot_msg db '.', 0
7568 7568 000003B0 0808080800 fourbs_msg db BS, BS, BS, BS, 0
7569 7569 000003B5 2061626F727465642E- aborted_msg db ' aborted.', CR, LF, 0
7570 7570 000003BE 0D0A00
7571 7571 000003C1 0D0C00 crff_msg db CR, FF, 0
7572 7572 000003C4 64656661756C7400 default_str db 'default', 0
7573 7573 default_len equ ($-default_str)
7574 7574 000003CC 2F626F6F74 boot_dir db '/boot' ; /boot/isolinux
7575 7575 000003D1 2F69736F6C696E7578- isolinux_dir db '/isolinux', 0
7576 7576 000003DA 00
7577 7577 ConfigName equ $
7578 7578 000003DB 69736F6C696E75782E- isolinux_cfg db 'isolinux.cfg', 0
7579 7579 000003E4 63666700
7580 7580 000003E8 43616E6E6F74206C6F- err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0
7581 7581 000003F1 6164206469736B2069-
7582 7582 000003FA 6D6167652028696E76-
7583 7583 00000403 616C69642066696C65-
7584 7584 0000040C 293F0D0A00
7585 7585
7586 7586 %ifdef DEBUG_MESSAGES
7587 7587 dbg_rootdir_msg db 'Root directory at LBA = ', 0
7588 7588 dbg_isodir_msg db 'isolinux directory at LBA = ', 0
7589 7589 dbg_config_msg db 'About to load config file...', CR, LF, 0
7590 7590 dbg_configok_msg db 'Configuration file opened...', CR, LF, 0
7591 7591 %endif
7592 7592 ;
7593 7593 ; Command line options we'd like to take a look at
7594 7594 ;
7595 7595 ; mem= and vga= are handled as normal 32-bit integer values
7596 7596 00000411 696E697472643D initrd_cmd db 'initrd='
7597 7597 initrd_cmd_len equ 7
7598 7598
7599 7599 ;
7600 7600 ; Config file keyword table
7601 7601 ;
7602 7602 %include "keywords.inc"
7603 7603 <1> ;; $Id: isolinux.lst,v 1.1 2007-09-01 22:44:04 niro Exp $
7604 7604 <1> ;; -----------------------------------------------------------------------
7605 7605 <1> ;;
7606 7606 <1> ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
7607 7607 <1> ;;
7608 7608 <1> ;; This program is free software; you can redistribute it and/or modify
7609 7609 <1> ;; it under the terms of the GNU General Public License as published by
7610 7610 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
7611 7611 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or
7612 7612 <1> ;; (at your option) any later version; incorporated herein by reference.
7613 7613 <1> ;;
7614 7614 <1> ;; -----------------------------------------------------------------------
7615 7615 <1>
7616 7616 <1> ;;
7617 7617 <1> ;; keywords.inc
7618 7618 <1> ;;
7619 7619 <1> ;; Common header file for the handling of keyword hash and macros
7620 7620 <1> ;;
7621 7621 <1>
7622 7622 <1> %ifndef DEPEND ; Generated file
7623 7623 <1> %include "kwdhash.gen"
7624 7624 <2> hash_menu equ 0x003719b5
7625 7625 <2> hash_append equ 0xc53999a4
7626 7626 <2> hash_default equ 0xcc5159ed
7627 7627 <2> hash_display equ 0xd509bc40
7628 7628 <2> hash_font equ 0x0032b1b4
7629 7629 <2> hash_implicit equ 0xa6f50207
7630 7630 <2> hash_ipappend equ 0xc5399af0
7631 7631 <2> hash_kbdmap equ 0xd013b850
7632 7632 <2> hash_kernel equ 0xd068b4cc
7633 7633 <2> hash_label equ 0x06f104cc
7634 7634 <2> hash_localboot equ 0x04f0def4
7635 7635 <2> hash_prompt equ 0xe7163a74
7636 7636 <2> hash_say equ 0x0001c059
7637 7637 <2> hash_serial equ 0xe068a84c
7638 7638 <2> hash_console equ 0x18d831fd
7639 7639 <2> hash_timeout equ 0xd4e332c9
7640 7640 <2> hash_totaltimeout equ 0xef51d0a9
7641 7641 <2> hash_allowoptions equ 0x1648dd10
7642 7642 <2> hash_ontimeout equ 0xd4e35eb9
7643 7643 <2> hash_onerror equ 0x1a68c589
7644 7644 <2> hash_noescape equ 0x0d00090e
7645 7645 <2> hash_f0 equ 0x00000cf0
7646 7646 <2> hash_f1 equ 0x00000cf1
7647 7647 <2> hash_f2 equ 0x00000cf2
7648 7648 <2> hash_f3 equ 0x00000cf3
7649 7649 <2> hash_f4 equ 0x00000cf4
7650 7650 <2> hash_f5 equ 0x00000cf5
7651 7651 <2> hash_f6 equ 0x00000cf6
7652 7652 <2> hash_f7 equ 0x00000cf7
7653 7653 <2> hash_f8 equ 0x00000cf8
7654 7654 <2> hash_f9 equ 0x00000cf9
7655 7655 <2> hash_f10 equ 0x00019e10
7656 7656 <2> hash_f11 equ 0x00019e11
7657 7657 <2> hash_f12 equ 0x00019e12
7658 7658 <1> %endif
7659 7659 <1>
7660 7660 <1> %macro keyword 2
7661 7661 <1> dd hash_%1 ; Hash value
7662 7662 <1> dw 0 ; No argument
7663 7663 <1> dw %2 ; Entrypoint
7664 7664 <1> %endmacro
7665 7665 <1>
7666 7666 <1> %macro keyword 3
7667 7667 <1> dd hash_%1 ; Hash value
7668 7668 <1> dw %3 ; 16-bit argument
7669 7669 <1> dw %2 ; Entrypoint
7670 7670 <1> %endmacro
7671 7671 <1>
7672 7672 <1> %macro keyword 4
7673 7673 <1> dd hash_%1 ; Hash value
7674 7674 <1> db %3, %4 ; 2 8-bit arguments
7675 7675 <1> dw %2 ; Entrypoint
7676 7676 <1> %endmacro
7677 7677 <1>
7678 7678 <1> keywd_size equ 8 ; Bytes per keyword
7679 7679 <1>
7680 7680 <1> align 4, db 0
7681 7681 <1>
7682 7682 <1> keywd_table:
7683 7683 <1> keyword menu, pc_comment
7684 7684 00000418 B5193700 <2> dd hash_%1
7685 7685 0000041C 0000 <2> dw 0
7686 7686 0000041E [A11C] <2> dw %2
7687 7687 <1> keyword append, pc_append
7688 7688 00000420 A49939C5 <2> dd hash_%1
7689 7689 00000424 0000 <2> dw 0
7690 7690 00000426 [031B] <2> dw %2
7691 7691 <1> keyword default, pc_default
7692 7692 00000428 ED5951CC <2> dd hash_%1
7693 7693 0000042C 0000 <2> dw 0
7694 7694 0000042E [DA1A] <2> dw %2
7695 7695 <1> keyword display, pc_filecmd, get_msg_file
7696 7696 00000430 40BC09D5 <2> dd hash_%1
7697 7697 00000434 [8018] <2> dw %3
7698 7698 00000436 [811B] <2> dw %2
7699 7699 <1> keyword font, pc_filecmd, loadfont
7700 7700 00000438 B4B13200 <2> dd hash_%1
7701 7701 0000043C [511E] <2> dw %3
7702 7702 0000043E [811B] <2> dw %2
7703 7703 <1> keyword implicit, pc_setint16, AllowImplicit
7704 7704 00000440 0702F5A6 <2> dd hash_%1
7705 7705 00000444 [B000] <2> dw %3
7706 7706 00000446 [771B] <2> dw %2
7707 7707 <1> keyword kbdmap, pc_filecmd, loadkeys
7708 7708 00000448 50B813D0 <2> dd hash_%1
7709 7709 0000044C [6118] <2> dw %3
7710 7710 0000044E [811B] <2> dw %2
7711 7711 <1> keyword kernel, pc_kernel
7712 7712 00000450 CCB468D0 <2> dd hash_%1
7713 7713 00000454 0000 <2> dw 0
7714 7714 00000456 [4F1B] <2> dw %2
7715 7715 <1> keyword label, pc_label
7716 7716 00000458 CC04F106 <2> dd hash_%1
7717 7717 0000045C 0000 <2> dw 0
7718 7718 0000045E [611C] <2> dw %2
7719 7719 <1> keyword prompt, pc_setint16, ForcePrompt
7720 7720 00000460 743A16E7 <2> dd hash_%1
7721 7721 00000464 [AC00] <2> dw %3
7722 7722 00000466 [771B] <2> dw %2
7723 7723 <1> keyword say, pc_say
7724 7724 00000468 59C00100 <2> dd hash_%1
7725 7725 0000046C 0000 <2> dw 0
7726 7726 0000046E [981C] <2> dw %2
7727 7727 <1> keyword serial, pc_serial
7728 7728 00000470 4CA868E0 <2> dd hash_%1
7729 7729 00000474 0000 <2> dw 0
7730 7730 00000476 [941B] <2> dw %2
7731 7731 <1> keyword console, pc_setint16, DisplayCon
7732 7732 00000478 FD31D818 <2> dd hash_%1
7733 7733 0000047C [7200] <2> dw %3
7734 7734 0000047E [771B] <2> dw %2
7735 7735 <1> keyword timeout, pc_timeout, KbdTimeout
7736 7736 00000480 C932E3D4 <2> dd hash_%1
7737 7737 00000484 [9C00] <2> dw %3
7738 7738 00000486 [601B] <2> dw %2
7739 7739 <1> keyword totaltimeout, pc_timeout, TotalTimeout
7740 7740 00000488 A9D051EF <2> dd hash_%1
7741 7741 0000048C [A000] <2> dw %3
7742 7742 0000048E [601B] <2> dw %2
7743 7743 <1> keyword ontimeout, pc_ontimeout
7744 7744 00000490 B95EE3D4 <2> dd hash_%1
7745 7745 00000494 0000 <2> dw 0
7746 7746 00000496 [E51A] <2> dw %2
7747 7747 <1> keyword onerror, pc_onerror
7748 7748 00000498 89C5681A <2> dd hash_%1
7749 7749 0000049C 0000 <2> dw 0
7750 7750 0000049E [F41A] <2> dw %2
7751 7751 <1> keyword allowoptions, pc_setint16, AllowOptions
7752 7752 000004A0 10DD4816 <2> dd hash_%1
7753 7753 000004A4 [B200] <2> dw %3
7754 7754 000004A6 [771B] <2> dw %2
7755 7755 <1> keyword noescape, pc_setint16, NoEscape
7756 7756 000004A8 0E09000D <2> dd hash_%1
7757 7757 000004AC [AE00] <2> dw %3
7758 7758 000004AE [771B] <2> dw %2
7759 7759 <1> keyword f1, pc_fkey, FKeyName+(0<<FILENAME_MAX_LG2)
7760 7760 000004B0 F10C0000 <2> dd hash_%1
7761 7761 000004B4 [080F] <2> dw %3
7762 7762 000004B6 [581C] <2> dw %2
7763 7763 <1> keyword f2, pc_fkey, FKeyName+(1<<FILENAME_MAX_LG2)
7764 7764 000004B8 F20C0000 <2> dd hash_%1
7765 7765 000004BC [0810] <2> dw %3
7766 7766 000004BE [581C] <2> dw %2
7767 7767 <1> keyword f3, pc_fkey, FKeyName+(2<<FILENAME_MAX_LG2)
7768 7768 000004C0 F30C0000 <2> dd hash_%1
7769 7769 000004C4 [0811] <2> dw %3
7770 7770 000004C6 [581C] <2> dw %2
7771 7771 <1> keyword f4, pc_fkey, FKeyName+(3<<FILENAME_MAX_LG2)
7772 7772 000004C8 F40C0000 <2> dd hash_%1
7773 7773 000004CC [0812] <2> dw %3
7774 7774 000004CE [581C] <2> dw %2
7775 7775 <1> keyword f5, pc_fkey, FKeyName+(4<<FILENAME_MAX_LG2)
7776 7776 000004D0 F50C0000 <2> dd hash_%1
7777 7777 000004D4 [0813] <2> dw %3
7778 7778 000004D6 [581C] <2> dw %2
7779 7779 <1> keyword f6, pc_fkey, FKeyName+(5<<FILENAME_MAX_LG2)
7780 7780 000004D8 F60C0000 <2> dd hash_%1
7781 7781 000004DC [0814] <2> dw %3
7782 7782 000004DE [581C] <2> dw %2
7783 7783 <1> keyword f7, pc_fkey, FKeyName+(6<<FILENAME_MAX_LG2)
7784 7784 000004E0 F70C0000 <2> dd hash_%1
7785 7785 000004E4 [0815] <2> dw %3
7786 7786 000004E6 [581C] <2> dw %2
7787 7787 <1> keyword f8, pc_fkey, FKeyName+(7<<FILENAME_MAX_LG2)
7788 7788 000004E8 F80C0000 <2> dd hash_%1
7789 7789 000004EC [0816] <2> dw %3
7790 7790 000004EE [581C] <2> dw %2
7791 7791 <1> keyword f9, pc_fkey, FKeyName+(8<<FILENAME_MAX_LG2)
7792 7792 000004F0 F90C0000 <2> dd hash_%1
7793 7793 000004F4 [0817] <2> dw %3
7794 7794 000004F6 [581C] <2> dw %2
7795 7795 <1> keyword f10, pc_fkey, FKeyName+(9<<FILENAME_MAX_LG2)
7796 7796 000004F8 109E0100 <2> dd hash_%1
7797 7797 000004FC [0818] <2> dw %3
7798 7798 000004FE [581C] <2> dw %2
7799 7799 <1> keyword f0, pc_fkey, FKeyName+(9<<FILENAME_MAX_LG2)
7800 7800 00000500 F00C0000 <2> dd hash_%1
7801 7801 00000504 [0818] <2> dw %3
7802 7802 00000506 [581C] <2> dw %2
7803 7803 <1> %if IS_PXELINUX
7804 7804 <1> keyword ipappend, pc_ipappend
7805 7805 <1> %endif
7806 7806 <1> %if IS_PXELINUX || IS_ISOLINUX
7807 7807 <1> keyword localboot, pc_localboot
7808 7808 00000508 F4DEF004 <2> dd hash_%1
7809 7809 0000050C 0000 <2> dw 0
7810 7810 0000050E [361B] <2> dw %2
7811 7811 <1> %endif
7812 7812 <1>
7813 7813 <1> keywd_count equ ($-keywd_table)/keywd_size
7814 7814 <1>
7815 7815
7816 7816 ;
7817 7817 ; Extensions to search for (in *forward* order).
7818 7818 ;
7819 7819 align 4, db 0
7820 7820 00000510 2E636274 exten_table: db '.cbt' ; COMBOOT (specific)
7821 7821 00000514 2E696D67 db '.img' ; Disk image
7822 7822 00000518 2E62696E db '.bin' ; CD boot sector
7823 7823 0000051C 2E636F6D db '.com' ; COMBOOT (same as DOS)
7824 7824 00000520 2E633332 db '.c32' ; COM32
7825 7825 exten_table_end:
7826 7826 00000524 0000000000000000 dd 0, 0 ; Need 8 null bytes here
7827 7827
7828 7828 ;
7829 7829 ; Floppy image table
7830 7830 ;
7831 7831 align 4, db 0
7832 7832 img_table_count equ 3
7833 7833 img_table:
7834 7834 0000052C 00C01200 dd 1200*1024 ; 1200K floppy
7835 7835 00000530 01 db 1 ; Emulation type
7836 7836 00000531 4F db 80-1 ; Max cylinder
7837 7837 00000532 0F db 15 ; Max sector
7838 7838 00000533 01 db 2-1 ; Max head
7839 7839
7840 7840 00000534 00801600 dd 1440*1024 ; 1440K floppy
7841 7841 00000538 02 db 2 ; Emulation type
7842 7842 00000539 4F db 80-1 ; Max cylinder
7843 7843 0000053A 12 db 18 ; Max sector
7844 7844 0000053B 01 db 2-1 ; Max head
7845 7845
7846 7846 0000053C 00002D00 dd 2880*1024 ; 2880K floppy
7847 7847 00000540 03 db 3 ; Emulation type
7848 7848 00000541 4F db 80-1 ; Max cylinder
7849 7849 00000542 24 db 36 ; Max sector
7850 7850 00000543 01 db 2-1 ; Max head
7851 7851
7852 7852 ;
7853 7853 ; Misc initialized (data) variables
7854 7854 ;
7855 7855
7856 7856 ;
7857 7857 ; Variables that are uninitialized in SYSLINUX but initialized here
7858 7858 ;
7859 7859 ; **** ISOLINUX:: We may have to make this flexible, based on what the
7860 7860 ; **** BIOS expects our "sector size" to be.
7861 7861 ;
7862 7862 alignb 4, db 0
7863 7863 00000544 0400 BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf
7864 7864 00000546 0400 BufSafeSec dw trackbufsize/SECTOR_SIZE ; = how many sectors?
7865 7865 00000548 0020 BufSafeBytes dw trackbufsize ; = how many bytes?
7866 7866 0000054A [0040] EndOfGetCBuf dw getcbuf+trackbufsize ; = getcbuf+BufSafeBytes
7867 7867 %ifndef DEPEND
7868 7868 %if ( trackbufsize % SECTOR_SIZE ) != 0
7869 7869 %error trackbufsize must be a multiple of SECTOR_SIZE
7870 7870 %endif
7871 7871 %endif