Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 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 niro 532 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