Adding upstream version 3.53.
[syslinux-debian/hramrach.git] / isolinux.asm
blobba7a6a6619d93b669c44be62fca2e573717c6b6f
1 ; -*- fundamental -*- (asm-mode sucks)
2 ; ****************************************************************************
4 ; isolinux.asm
6 ; A program to boot Linux kernels off a CD-ROM using the El Torito
7 ; boot standard in "no emulation" mode, making the entire filesystem
8 ; available. It is based on the SYSLINUX boot loader for MS-DOS
9 ; floppies.
11 ; Copyright (C) 1994-2006 H. Peter Anvin
13 ; This program is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
16 ; Boston MA 02111-1307, USA; either version 2 of the License, or
17 ; (at your option) any later version; incorporated herein by reference.
19 ; ****************************************************************************
21 %define IS_ISOLINUX 1
22 %include "head.inc"
25 ; Some semi-configurable constants... change on your own risk.
27 my_id equ isolinux_id
28 FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null)
29 FILENAME_MAX equ (1 << FILENAME_MAX_LG2)
30 NULLFILE equ 0 ; Zero byte == null file name
31 NULLOFFSET equ 0 ; Position in which to look
32 retry_count equ 6 ; How patient are we with the BIOS?
33 %assign HIGHMEM_SLOP 128*1024 ; Avoid this much memory near the top
34 MAX_OPEN_LG2 equ 6 ; log2(Max number of open files)
35 MAX_OPEN equ (1 << MAX_OPEN_LG2)
36 SECTOR_SHIFT equ 11 ; 2048 bytes/sector (El Torito requirement)
37 SECTOR_SIZE equ (1 << SECTOR_SHIFT)
40 ; This is what we need to do when idle
42 %macro RESET_IDLE 0
43 ; Nothing
44 %endmacro
45 %macro DO_IDLE 0
46 ; Nothing
47 %endmacro
50 ; The following structure is used for "virtual kernels"; i.e. LILO-style
51 ; option labels. The options we permit here are `kernel' and `append
52 ; Since there is no room in the bottom 64K for all of these, we
53 ; stick them at vk_seg:0000 and copy them down before we need them.
55 struc vkernel
56 vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
57 vk_rname: resb FILENAME_MAX ; Real name
58 vk_appendlen: resw 1
59 vk_type: resb 1 ; Type of file
60 alignb 4
61 vk_append: resb max_cmd_len+1 ; Command line
62 alignb 4
63 vk_end: equ $ ; Should be <= vk_size
64 endstruc
67 ; Segment assignments in the bottom 640K
68 ; 0000h - main code/data segment (and BIOS segment)
70 real_mode_seg equ 3000h
71 vk_seg equ 2000h ; Virtual kernels
72 xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
73 comboot_seg equ real_mode_seg ; COMBOOT image loading zone
76 ; File structure. This holds the information for each currently open file.
78 struc open_file_t
79 file_sector resd 1 ; Sector pointer (0 = structure free)
80 file_left resd 1 ; Number of sectors left
81 endstruc
83 %ifndef DEPEND
84 %if (open_file_t_size & (open_file_t_size-1))
85 %error "open_file_t is not a power of 2"
86 %endif
87 %endif
89 struc dir_t
90 dir_lba resd 1 ; Directory start (LBA)
91 dir_len resd 1 ; Length in bytes
92 dir_clust resd 1 ; Length in clusters
93 endstruc
95 ; ---------------------------------------------------------------------------
96 ; BEGIN CODE
97 ; ---------------------------------------------------------------------------
100 ; Memory below this point is reserved for the BIOS and the MBR
102 section .earlybss
103 trackbufsize equ 8192
104 trackbuf resb trackbufsize ; Track buffer goes here
105 getcbuf resb trackbufsize
106 ; ends at 4800h
108 ; Some of these are touched before the whole image
109 ; is loaded. DO NOT move this to .uibss.
110 section .bss1
111 alignb 4
112 ISOFileName resb 64 ; ISO filename canonicalization buffer
113 ISOFileNameEnd equ $
114 CurDir resb dir_t_size ; Current directory
115 RootDir resb dir_t_size ; Root directory
116 FirstSecSum resd 1 ; Checksum of bytes 64-2048
117 ImageDwords resd 1 ; isolinux.bin size, dwords
118 InitStack resd 1 ; Initial stack pointer (SS:SP)
119 DiskSys resw 1 ; Last INT 13h call
120 ImageSectors resw 1 ; isolinux.bin size, sectors
121 DiskError resb 1 ; Error code for disk I/O
122 DriveNumber resb 1 ; CD-ROM BIOS drive number
123 ISOFlags resb 1 ; Flags for ISO directory search
124 RetryCount resb 1 ; Used for disk access retries
126 _spec_start equ $
129 ; El Torito spec packet
132 alignb 8
133 spec_packet: resb 1 ; Size of packet
134 sp_media: resb 1 ; Media type
135 sp_drive: resb 1 ; Drive number
136 sp_controller: resb 1 ; Controller index
137 sp_lba: resd 1 ; LBA for emulated disk image
138 sp_devspec: resw 1 ; IDE/SCSI information
139 sp_buffer: resw 1 ; User-provided buffer
140 sp_loadseg: resw 1 ; Load segment
141 sp_sectors: resw 1 ; Sector count
142 sp_chs: resb 3 ; Simulated CHS geometry
143 sp_dummy: resb 1 ; Scratch, safe to overwrite
146 ; EBIOS drive parameter packet
148 alignb 8
149 drive_params: resw 1 ; Buffer size
150 dp_flags: resw 1 ; Information flags
151 dp_cyl: resd 1 ; Physical cylinders
152 dp_head: resd 1 ; Physical heads
153 dp_sec: resd 1 ; Physical sectors/track
154 dp_totalsec: resd 2 ; Total sectors
155 dp_secsize: resw 1 ; Bytes per sector
156 dp_dpte: resd 1 ; Device Parameter Table
157 dp_dpi_key: resw 1 ; 0BEDDh if rest valid
158 dp_dpi_len: resb 1 ; DPI len
159 resb 1
160 resw 1
161 dp_bus: resb 4 ; Host bus type
162 dp_interface: resb 8 ; Interface type
163 db_i_path: resd 2 ; Interface path
164 db_d_path: resd 2 ; Device path
165 resb 1
166 db_dpi_csum: resb 1 ; Checksum for DPI info
169 ; EBIOS disk address packet
171 alignb 8
172 dapa: resw 1 ; Packet size
173 .count: resw 1 ; Block count
174 .off: resw 1 ; Offset of buffer
175 .seg: resw 1 ; Segment of buffer
176 .lba: resd 2 ; LBA (LSW, MSW)
179 ; Spec packet for disk image emulation
181 alignb 8
182 dspec_packet: resb 1 ; Size of packet
183 dsp_media: resb 1 ; Media type
184 dsp_drive: resb 1 ; Drive number
185 dsp_controller: resb 1 ; Controller index
186 dsp_lba: resd 1 ; LBA for emulated disk image
187 dsp_devspec: resw 1 ; IDE/SCSI information
188 dsp_buffer: resw 1 ; User-provided buffer
189 dsp_loadseg: resw 1 ; Load segment
190 dsp_sectors: resw 1 ; Sector count
191 dsp_chs: resb 3 ; Simulated CHS geometry
192 dsp_dummy: resb 1 ; Scratch, safe to overwrite
194 alignb 4
195 _spec_end equ $
196 _spec_len equ _spec_end - _spec_start
198 alignb open_file_t_size
199 Files resb MAX_OPEN*open_file_t_size
202 ; Constants for the xfer_buf_seg
204 ; The xfer_buf_seg is also used to store message file buffers. We
205 ; need two trackbuffers (text and graphics), plus a work buffer
206 ; for the graphics decompressor.
208 xbs_textbuf equ 0 ; Also hard-coded, do not change
209 xbs_vgabuf equ trackbufsize
210 xbs_vgatmpbuf equ 2*trackbufsize
212 section .text
214 ;; Primary entry point. Because BIOSes are buggy, we only load the first
215 ;; CD-ROM sector (2K) of the file, so the number one priority is actually
216 ;; loading the rest.
218 StackBuf equ $-44 ; 44 bytes needed for
219 ; the bootsector chainloading
220 ; code!
221 OrigESDI equ StackBuf-4 ; The high dword on the stack
223 bootsec equ $
225 _start: ; Far jump makes sure we canonicalize the address
227 jmp 0:_start1
228 times 8-($-$$) nop ; Pad to file offset 8
230 ; This table hopefully gets filled in by mkisofs using the
231 ; -boot-info-table option. If not, the values in this
232 ; table are default values that we can use to get us what
233 ; we need, at least under a certain set of assumptions.
234 bi_pvd: dd 16 ; LBA of primary volume descriptor
235 bi_file: dd 0 ; LBA of boot file
236 bi_length: dd 0xdeadbeef ; Length of boot file
237 bi_csum: dd 0xdeadbeef ; Checksum of boot file
238 bi_reserved: times 10 dd 0xdeadbeef ; Reserved
240 _start1: mov [cs:InitStack],sp ; Save initial stack pointer
241 mov [cs:InitStack+2],ss
242 xor ax,ax
243 mov ss,ax
244 mov sp,StackBuf ; Set up stack
245 push es ; Save initial ES:DI -> $PnP pointer
246 push di
247 mov ds,ax
248 mov es,ax
249 mov fs,ax
250 mov gs,ax
254 ; Show signs of life
255 mov si,syslinux_banner
256 call writestr
257 %ifdef DEBUG_MESSAGES
258 mov si,copyright_str
259 call writestr
260 %endif
263 ; Before modifying any memory, get the checksum of bytes
264 ; 64-2048
266 initial_csum: xor edi,edi
267 mov si,_start1
268 mov cx,(SECTOR_SIZE-64) >> 2
269 .loop: lodsd
270 add edi,eax
271 loop .loop
272 mov [FirstSecSum],edi
274 mov [DriveNumber],dl
275 %ifdef DEBUG_MESSAGES
276 mov si,startup_msg
277 call writemsg
278 mov al,dl
279 call writehex2
280 call crlf
281 %endif
283 ; Initialize spec packet buffers
285 mov di,_spec_start
286 mov cx,_spec_len >> 2
287 xor eax,eax
288 rep stosd
290 ; Initialize length field of the various packets
291 mov byte [spec_packet],13h
292 mov byte [drive_params],30
293 mov byte [dapa],16
294 mov byte [dspec_packet],13h
296 ; Other nonzero fields
297 inc word [dsp_sectors]
299 ; Now figure out what we're actually doing
300 ; Note: use passed-in DL value rather than 7Fh because
301 ; at least some BIOSes will get the wrong value otherwise
302 mov ax,4B01h ; Get disk emulation status
303 mov dl,[DriveNumber]
304 mov si,spec_packet
305 call int13
306 jc award_hack ; changed for BrokenAwardHack
307 mov dl,[DriveNumber]
308 cmp [sp_drive],dl ; Should contain the drive number
309 jne spec_query_failed
311 %ifdef DEBUG_MESSAGES
312 mov si,spec_ok_msg
313 call writemsg
314 mov al,byte [sp_drive]
315 call writehex2
316 call crlf
317 %endif
319 found_drive:
320 ; Alright, we have found the drive. Now, try to find the
321 ; boot file itself. If we have a boot info table, life is
322 ; good; if not, we have to make some assumptions, and try
323 ; to figure things out ourselves. In particular, the
324 ; assumptions we have to make are:
325 ; - single session only
326 ; - only one boot entry (no menu or other alternatives)
328 cmp dword [bi_file],0 ; Address of code to load
329 jne found_file ; Boot info table present :)
331 %ifdef DEBUG_MESSAGES
332 mov si,noinfotable_msg
333 call writemsg
334 %endif
336 ; No such luck. See if the the spec packet contained one.
337 mov eax,[sp_lba]
338 and eax,eax
339 jz set_file ; Good enough
341 %ifdef DEBUG_MESSAGES
342 mov si,noinfoinspec_msg
343 call writemsg
344 %endif
346 ; No such luck. Get the Boot Record Volume, assuming single
347 ; session disk, and that we're the first entry in the chain
348 mov eax,17 ; Assumed address of BRV
349 mov bx,trackbuf
350 call getonesec
352 mov eax,[trackbuf+47h] ; Get boot catalog address
353 mov bx,trackbuf
354 call getonesec ; Get boot catalog
356 mov eax,[trackbuf+28h] ; First boot entry
357 ; And hope and pray this is us...
359 ; Some BIOSes apparently have limitations on the size
360 ; that may be loaded (despite the El Torito spec being very
361 ; clear on the fact that it must all be loaded.) Therefore,
362 ; we load it ourselves, and *bleep* the BIOS.
364 set_file:
365 mov [bi_file],eax
367 found_file:
368 ; Set up boot file sizes
369 mov eax,[bi_length]
370 sub eax,SECTOR_SIZE-3
371 shr eax,2 ; bytes->dwords
372 mov [ImageDwords],eax ; boot file dwords
373 add eax,(2047 >> 2)
374 shr eax,9 ; dwords->sectors
375 mov [ImageSectors],ax ; boot file sectors
377 mov eax,[bi_file] ; Address of code to load
378 inc eax ; Don't reload bootstrap code
379 %ifdef DEBUG_MESSAGES
380 mov si,offset_msg
381 call writemsg
382 call writehex8
383 call crlf
384 %endif
386 ; Just in case some BIOSes have problems with
387 ; segment wraparound, use the normalized address
388 mov bx,((7C00h+2048) >> 4)
389 mov es,bx
390 xor bx,bx
391 mov bp,[ImageSectors]
392 %ifdef DEBUG_MESSAGES
393 push ax
394 mov si,size_msg
395 call writemsg
396 mov ax,bp
397 call writehex4
398 call crlf
399 pop ax
400 %endif
401 call getlinsec
403 push ds
404 pop es
406 %ifdef DEBUG_MESSAGES
407 mov si,loaded_msg
408 call writemsg
409 %endif
411 ; Verify the checksum on the loaded image.
412 verify_image:
413 mov si,7C00h+2048
414 mov bx,es
415 mov ecx,[ImageDwords]
416 mov edi,[FirstSecSum] ; First sector checksum
417 .loop es lodsd
418 add edi,eax
419 dec ecx
420 jz .done
421 and si,si
422 jnz .loop
423 ; SI wrapped around, advance ES
424 add bx,1000h
425 mov es,bx
426 jmp short .loop
427 .done: mov ax,ds
428 mov es,ax
429 cmp [bi_csum],edi
430 je integrity_ok
432 mov si,checkerr_msg
433 call writemsg
434 jmp kaboom
436 integrity_ok:
437 %ifdef DEBUG_MESSAGES
438 mov si,allread_msg
439 call writemsg
440 %endif
441 jmp all_read ; Jump to main code
443 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444 ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
445 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
447 ;; There is a problem with certain versions of the AWARD BIOS ...
448 ;; the boot sector will be loaded and executed correctly, but, because the
449 ;; int 13 vector points to the wrong code in the BIOS, every attempt to
450 ;; load the spec packet will fail. We scan for the equivalent of
452 ;; mov ax,0201h
453 ;; mov bx,7c00h
454 ;; mov cx,0006h
455 ;; mov dx,0180h
456 ;; pushf
457 ;; call <direct far>
459 ;; and use <direct far> as the new vector for int 13. The code above is
460 ;; used to load the boot code into ram, and there should be no reason
461 ;; for anybody to change it now or in the future. There are no opcodes
462 ;; that use encodings relativ to IP, so scanning is easy. If we find the
463 ;; code above in the BIOS code we can be pretty sure to run on a machine
464 ;; with an broken AWARD BIOS ...
466 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
468 %ifdef DEBUG_MESSAGES ;;
470 award_notice db "Trying BrokenAwardHack first ...",CR,LF,0 ;;
471 award_not_orig db "BAH: Original Int 13 vector : ",0 ;;
472 award_not_new db "BAH: Int 13 vector changed to : ",0 ;;
473 award_not_succ db "BAH: SUCCESS",CR,LF,0 ;;
474 award_not_fail db "BAH: FAILURE" ;;
475 award_not_crlf db CR,LF,0 ;;
477 %endif ;;
479 award_oldint13 dd 0 ;;
480 award_string db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah ;;
482 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
483 award_hack: mov si,spec_err_msg ; Moved to this place from
484 call writemsg ; spec_query_faild
486 %ifdef DEBUG_MESSAGES ;
488 mov si,award_notice ; display our plan
489 call writemsg ;
490 mov si,award_not_orig ; display original int 13
491 call writemsg ; vector
492 %endif ;
493 mov eax,[13h*4] ;
494 mov [award_oldint13],eax ;
496 %ifdef DEBUG_MESSAGES ;
498 call writehex8 ;
499 mov si,award_not_crlf ;
500 call writestr ;
501 %endif ;
502 push es ; save ES
503 mov ax,0f000h ; ES = BIOS Seg
504 mov es,ax ;
505 cld ;
506 xor di,di ; start at ES:DI = f000:0
507 award_loop: push di ; save DI
508 mov si,award_string ; scan for award_string
509 mov cx,7 ; length of award_string = 7dw
510 repz cmpsw ; compare
511 pop di ; restore DI
512 jcxz award_found ; jmp if found
513 inc di ; not found, inc di
514 jno award_loop ;
516 award_failed: pop es ; No, not this way :-((
517 award_fail2: ;
519 %ifdef DEBUG_MESSAGES ;
521 mov si,award_not_fail ; display failure ...
522 call writemsg ;
523 %endif ;
524 mov eax,[award_oldint13] ; restore the original int
525 or eax,eax ; 13 vector if there is one
526 jz spec_query_failed ; and try other workarounds
527 mov [13h*4],eax ;
528 jmp spec_query_failed ;
530 award_found: mov eax,[es:di+0eh] ; load possible int 13 addr
531 pop es ; restore ES
533 cmp eax,[award_oldint13] ; give up if this is the
534 jz award_failed ; active int 13 vector,
535 mov [13h*4],eax ; otherwise change 0:13h*4
538 %ifdef DEBUG_MESSAGES ;
540 push eax ; display message and
541 mov si,award_not_new ; new vector address
542 call writemsg ;
543 pop eax ;
544 call writehex8 ;
545 mov si,award_not_crlf ;
546 call writestr ;
547 %endif ;
548 mov ax,4B01h ; try to read the spec packet
549 mov dl,[DriveNumber] ; now ... it should not fail
550 mov si,spec_packet ; any longer
551 int 13h ;
552 jc award_fail2 ;
554 %ifdef DEBUG_MESSAGES ;
556 mov si,award_not_succ ; display our SUCCESS
557 call writemsg ;
558 %endif ;
559 jmp found_drive ; and leave error recovery code
561 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
562 ;; End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de
563 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
566 ; INT 13h, AX=4B01h, DL=<passed in value> failed.
567 ; Try to scan the entire 80h-FFh from the end.
569 spec_query_failed:
571 ; some code moved to BrokenAwardHack
573 mov dl,0FFh
574 .test_loop: pusha
575 mov ax,4B01h
576 mov si,spec_packet
577 mov byte [si],13 ; Size of buffer
578 call int13
579 popa
580 jc .still_broken
582 mov si,maybe_msg
583 call writemsg
584 mov al,dl
585 call writehex2
586 call crlf
588 cmp byte [sp_drive],dl
589 jne .maybe_broken
591 ; Okay, good enough...
592 mov si,alright_msg
593 call writemsg
594 mov [DriveNumber],dl
595 .found_drive: jmp found_drive
597 ; Award BIOS 4.51 apparently passes garbage in sp_drive,
598 ; but if this was the drive number originally passed in
599 ; DL then consider it "good enough"
600 .maybe_broken:
601 cmp byte [DriveNumber],dl
602 je .found_drive
604 .still_broken: dec dx
605 cmp dl, 80h
606 jnb .test_loop
608 ; No spec packet anywhere. Some particularly pathetic
609 ; BIOSes apparently don't even implement function
610 ; 4B01h, so we can't query a spec packet no matter
611 ; what. If we got a drive number in DL, then try to
612 ; use it, and if it works, then well...
613 mov dl,[DriveNumber]
614 cmp dl,81h ; Should be 81-FF at least
615 jb fatal_error ; If not, it's hopeless
617 ; Write a warning to indicate we're on *very* thin ice now
618 mov si,nospec_msg
619 call writemsg
620 mov al,dl
621 call writehex2
622 call crlf
623 mov si,trysbm_msg
624 call writemsg
625 jmp .found_drive ; Pray that this works...
627 fatal_error:
628 mov si,nothing_msg
629 call writemsg
631 .norge: jmp short .norge
633 ; Information message (DS:SI) output
634 ; Prefix with "isolinux: "
636 writemsg: push ax
637 push si
638 mov si,isolinux_str
639 call writestr
640 pop si
641 call writestr
642 pop ax
646 ; Write a character to the screen. There is a more "sophisticated"
647 ; version of this in the subsequent code, so we patch the pointer
648 ; when appropriate.
651 writechr:
652 jmp near writechr_simple ; 3-byte jump
654 writechr_simple:
655 pushfd
656 pushad
657 mov ah,0Eh
658 xor bx,bx
659 int 10h
660 popad
661 popfd
665 ; int13: save all the segment registers and call INT 13h
666 ; Some CD-ROM BIOSes have been found to corrupt segment registers.
668 int13:
670 push ds
671 push es
672 push fs
673 push gs
674 int 13h
675 pop gs
676 pop fs
677 pop es
678 pop ds
682 ; Get one sector. Convenience entry point.
684 getonesec:
685 mov bp,1
686 ; Fall through to getlinsec
689 ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
691 ; Note that we can't always do this as a single request, because at least
692 ; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick
693 ; to 32 sectors (64K) per request.
695 ; Input:
696 ; EAX - Linear sector number
697 ; ES:BX - Target buffer
698 ; BP - Sector count
700 getlinsec:
701 mov si,dapa ; Load up the DAPA
702 mov [si+4],bx
703 mov bx,es
704 mov [si+6],bx
705 mov [si+8],eax
706 .loop:
707 push bp ; Sectors left
708 cmp bp,[MaxTransfer]
709 jbe .bp_ok
710 mov bp,[MaxTransfer]
711 .bp_ok:
712 mov [si+2],bp
713 push si
714 mov dl,[DriveNumber]
715 mov ah,42h ; Extended Read
716 call xint13
717 pop si
718 pop bp
719 movzx eax,word [si+2] ; Sectors we read
720 add [si+8],eax ; Advance sector pointer
721 sub bp,ax ; Sectors left
722 shl ax,SECTOR_SHIFT-4 ; 2048-byte sectors -> segment
723 add [si+6],ax ; Advance buffer pointer
724 and bp,bp
725 jnz .loop
726 mov eax,[si+8] ; Next sector
729 ; INT 13h with retry
730 xint13: mov byte [RetryCount],retry_count
731 .try: pushad
732 call int13
733 jc .error
734 add sp,byte 8*4 ; Clean up stack
736 .error:
737 mov [DiskError],ah ; Save error code
738 popad
739 mov [DiskSys],ax ; Save system call number
740 dec byte [RetryCount]
741 jz .real_error
742 push ax
743 mov al,[RetryCount]
744 mov ah,[dapa+2] ; Sector transfer count
745 cmp al,2 ; Only 2 attempts left
746 ja .nodanger
747 mov ah,1 ; Drop transfer size to 1
748 jmp short .setsize
749 .nodanger:
750 cmp al,retry_count-2
751 ja .again ; First time, just try again
752 shr ah,1 ; Otherwise, try to reduce
753 adc ah,0 ; the max transfer size, but not to 0
754 .setsize:
755 mov [MaxTransfer],ah
756 mov [dapa+2],ah
757 .again:
758 pop ax
759 jmp .try
761 .real_error: mov si,diskerr_msg
762 call writemsg
763 mov al,[DiskError]
764 call writehex2
765 mov si,oncall_str
766 call writestr
767 mov ax,[DiskSys]
768 call writehex4
769 mov si,ondrive_str
770 call writestr
771 mov al,dl
772 call writehex2
773 call crlf
774 ; Fall through to kaboom
777 ; kaboom: write a message and bail out. Wait for a user keypress,
778 ; then do a hard reboot.
780 kaboom:
781 RESET_STACK_AND_SEGS AX
782 mov si,err_bootfailed
783 call cwritestr
784 call getchar
786 mov word [BIOS_magic],0 ; Cold reboot
787 jmp 0F000h:0FFF0h ; Reset vector address
789 ; -----------------------------------------------------------------------------
790 ; Common modules needed in the first sector
791 ; -----------------------------------------------------------------------------
793 %include "writestr.inc" ; String output
794 writestr equ cwritestr
795 %include "writehex.inc" ; Hexadecimal output
797 ; -----------------------------------------------------------------------------
798 ; Data that needs to be in the first sector
799 ; -----------------------------------------------------------------------------
801 syslinux_banner db CR, LF, 'ISOLINUX ', version_str, ' ', date, ' ', 0
802 copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin'
803 db CR, LF, 0
804 isolinux_str db 'isolinux: ', 0
805 %ifdef DEBUG_MESSAGES
806 startup_msg: db 'Starting up, DL = ', 0
807 spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
808 secsize_msg: db 'Sector size appears to be ', 0
809 offset_msg: db 'Loading main image from LBA = ', 0
810 size_msg: db 'Sectors to load = ', 0
811 loaded_msg: db 'Loaded boot image, verifying...', CR, LF, 0
812 verify_msg: db 'Image checksum verified.', CR, LF, 0
813 allread_msg db 'Main image read, jumping to main code...', CR, LF, 0
814 %endif
815 noinfotable_msg db 'No boot info table, assuming single session disk...', CR, LF, 0
816 noinfoinspec_msg db 'Spec packet missing LBA information, trying to wing it...', CR, LF, 0
817 spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0
818 maybe_msg: db 'Found something at drive = ', 0
819 alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0
820 nospec_msg db 'Extremely broken BIOS detected, last ditch attempt with drive = ', 0
821 nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF
822 trysbm_msg db 'See http://syslinux.zytor.com/sbm for more information.', CR, LF, 0
823 diskerr_msg: db 'Disk error ', 0
824 oncall_str: db ', AX = ',0
825 ondrive_str: db ', drive ', 0
826 checkerr_msg: db 'Image checksum error, sorry...', CR, LF, 0
828 err_bootfailed db CR, LF, 'Boot failed: press a key to retry...'
829 bailmsg equ err_bootfailed
830 crlf_msg db CR, LF
831 null_msg db 0
833 alignb 4, db 0
834 MaxTransfer dw 32 ; Max sectors per transfer
836 rl_checkpt equ $ ; Must be <= 800h
838 rl_checkpt_off equ ($-$$)
839 ;%ifndef DEPEND
840 ;%if rl_checkpt_off > 0x800
841 ;%error "Sector 0 overflow"
842 ;%endif
843 ;%endif
845 ; ----------------------------------------------------------------------------
846 ; End of code and data that have to be in the first sector
847 ; ----------------------------------------------------------------------------
849 all_read:
851 ; Test tracers
852 TRACER 'T'
853 TRACER '>'
856 ; Common initialization code
858 %include "init.inc"
859 %include "cpuinit.inc"
861 ; Patch the writechr routine to point to the full code
862 mov word [writechr+1], writechr_full-(writechr+3)
864 ; Tell the user we got this far...
865 %ifndef DEBUG_MESSAGES ; Gets messy with debugging on
866 mov si,copyright_str
867 call writestr
868 %endif
871 ; Now we're all set to start with our *real* business. First load the
872 ; configuration file (if any) and parse it.
874 ; In previous versions I avoided using 32-bit registers because of a
875 ; rumour some BIOSes clobbered the upper half of 32-bit registers at
876 ; random. I figure, though, that if there are any of those still left
877 ; they probably won't be trying to install Linux on them...
879 ; The code is still ripe with 16-bitisms, though. Not worth the hassle
880 ; to take'm out. In fact, we may want to put them back if we're going
881 ; to boot ELKS at some point.
885 ; Now, we need to sniff out the actual filesystem data structures.
886 ; mkisofs gave us a pointer to the primary volume descriptor
887 ; (which will be at 16 only for a single-session disk!); from the PVD
888 ; we should be able to find the rest of what we need to know.
890 get_fs_structures:
891 mov eax,[bi_pvd]
892 mov bx,trackbuf
893 call getonesec
895 mov eax,[trackbuf+156+2]
896 mov [RootDir+dir_lba],eax
897 mov [CurDir+dir_lba],eax
898 %ifdef DEBUG_MESSAGES
899 mov si,dbg_rootdir_msg
900 call writemsg
901 call writehex8
902 call crlf
903 %endif
904 mov eax,[trackbuf+156+10]
905 mov [RootDir+dir_len],eax
906 mov [CurDir+dir_len],eax
907 add eax,SECTOR_SIZE-1
908 shr eax,SECTOR_SHIFT
909 mov [RootDir+dir_clust],eax
910 mov [CurDir+dir_clust],eax
912 ; Look for an isolinux directory, and if found,
913 ; make it the current directory instead of the root
914 ; directory.
915 mov di,boot_dir ; Search for /boot/isolinux
916 mov al,02h
917 call searchdir_iso
918 jnz .found_dir
919 mov di,isolinux_dir
920 mov al,02h ; Search for /isolinux
921 call searchdir_iso
922 jz .no_isolinux_dir
923 .found_dir:
924 mov [CurDir+dir_len],eax
925 mov eax,[si+file_left]
926 mov [CurDir+dir_clust],eax
927 xor eax,eax ; Free this file pointer entry
928 xchg eax,[si+file_sector]
929 mov [CurDir+dir_lba],eax
930 %ifdef DEBUG_MESSAGES
931 push si
932 mov si,dbg_isodir_msg
933 call writemsg
934 pop si
935 call writehex8
936 call crlf
937 %endif
938 .no_isolinux_dir:
941 ; Locate the configuration file
943 load_config:
944 %ifdef DEBUG_MESSAGES
945 mov si,dbg_config_msg
946 call writemsg
947 %endif
949 mov si,config_name
950 mov di,ConfigName
951 call strcpy
953 mov di,ConfigName
954 call open
955 jz no_config_file ; Not found or empty
957 %ifdef DEBUG_MESSAGES
958 mov si,dbg_configok_msg
959 call writemsg
960 %endif
963 ; Now we have the config file open. Parse the config file and
964 ; run the user interface.
966 %include "ui.inc"
969 ; Enable disk emulation. The kind of disk we emulate is dependent on the size of
970 ; the file: 1200K, 1440K or 2880K floppy, otherwise harddisk.
972 is_disk_image:
973 TRACER CR
974 TRACER LF
975 TRACER 'D'
976 TRACER ':'
978 shl edx,16
979 mov dx,ax ; Set EDX <- file size
980 mov di,img_table
981 mov cx,img_table_count
982 mov eax,[si+file_sector] ; Starting LBA of file
983 mov [dsp_lba],eax ; Location of file
984 mov byte [dsp_drive], 0 ; 00h floppy, 80h hard disk
985 .search_table:
986 TRACER 't'
987 mov eax,[di+4]
988 cmp edx,[di]
989 je .type_found
990 add di,8
991 loop .search_table
993 ; Hard disk image. Need to examine the partition table
994 ; in order to deduce the C/H/S geometry. Sigh.
995 .hard_disk_image:
996 TRACER 'h'
997 cmp edx,512
998 jb .bad_image
1000 mov bx,trackbuf
1001 mov cx,1 ; Load 1 sector
1002 call getfssec
1004 cmp word [trackbuf+510],0aa55h ; Boot signature
1005 jne .bad_image ; Image not bootable
1007 mov cx,4 ; 4 partition entries
1008 mov di,trackbuf+446 ; Start of partition table
1010 xor ax,ax ; Highest sector(al) head(ah)
1012 .part_scan:
1013 cmp byte [di+4], 0
1014 jz .part_loop
1015 lea si,[di+1]
1016 call .hs_check
1017 add si,byte 4
1018 call .hs_check
1019 .part_loop:
1020 add di,byte 16
1021 loop .part_scan
1023 push eax ; H/S
1024 push edx ; File size
1025 mov bl,ah
1026 xor bh,bh
1027 inc bx ; # of heads in BX
1028 xor ah,ah ; # of sectors in AX
1029 cwde ; EAX[31:16] <- 0
1030 mul bx
1031 shl eax,9 ; Convert to bytes
1032 ; Now eax contains the number of bytes per cylinder
1033 pop ebx ; File size
1034 xor edx,edx
1035 div ebx
1036 and edx,edx
1037 jz .no_remainder
1038 inc eax ; Fractional cylinder...
1039 ; Now (e)ax contains the number of cylinders
1040 .no_remainder: cmp eax,1024
1041 jna .ok_cyl
1042 mov ax,1024 ; Max possible #
1043 .ok_cyl: dec ax ; Convert to max cylinder no
1044 pop ebx ; S(bl) H(bh)
1045 shl ah,6
1046 or bl,ah
1047 xchg ax,bx
1048 shl eax,16
1049 mov ah,bl
1050 mov al,4 ; Hard disk boot
1051 mov byte [dsp_drive], 80h ; Drive 80h = hard disk
1053 .type_found:
1054 TRACER 'T'
1055 mov bl,[sp_media]
1056 and bl,0F0h ; Copy controller info bits
1057 or al,bl
1058 mov [dsp_media],al ; Emulation type
1059 shr eax,8
1060 mov [dsp_chs],eax ; C/H/S geometry
1061 mov ax,[sp_devspec] ; Copy device spec
1062 mov [dsp_devspec],ax
1063 mov al,[sp_controller] ; Copy controller index
1064 mov [dsp_controller],al
1066 TRACER 'V'
1067 call vgaclearmode ; Reset video
1069 mov ax,4C00h ; Enable emulation and boot
1070 mov si,dspec_packet
1071 mov dl,[DriveNumber]
1072 lss sp,[InitStack]
1073 TRACER 'X'
1075 call int13
1077 ; If this returns, we have problems
1078 .bad_image:
1079 mov si,err_disk_image
1080 call cwritestr
1081 jmp enter_command
1084 ; Look for the highest seen H/S geometry
1085 ; We compute cylinders separately
1087 .hs_check:
1088 mov bl,[si] ; Head #
1089 cmp bl,ah
1090 jna .done_track
1091 mov ah,bl ; New highest head #
1092 .done_track: mov bl,[si+1]
1093 and bl,3Fh ; Sector #
1094 cmp bl,al
1095 jna .done_sector
1096 mov al,bl
1097 .done_sector: ret
1100 ; Boot a specified local disk. AX specifies the BIOS disk number; or
1101 ; 0xFFFF in case we should execute INT 18h ("next device.")
1103 local_boot:
1104 call vgaclearmode
1105 lss sp,[cs:Stack] ; Restore stack pointer
1106 xor dx,dx
1107 mov ds,dx
1108 mov es,dx
1109 mov fs,dx
1110 mov gs,dx
1111 mov si,localboot_msg
1112 call writestr
1113 cmp ax,-1
1114 je .int18
1116 ; Load boot sector from the specified BIOS device and jump to it.
1117 mov dl,al
1118 xor dh,dh
1119 push dx
1120 xor ax,ax ; Reset drive
1121 call xint13
1122 mov ax,0201h ; Read one sector
1123 mov cx,0001h ; C/H/S = 0/0/1 (first sector)
1124 mov bx,trackbuf
1125 call xint13
1126 pop dx
1127 cli ; Abandon hope, ye who enter here
1128 mov si,trackbuf
1129 mov di,07C00h
1130 mov cx,512 ; Probably overkill, but should be safe
1131 rep movsd
1132 lss sp,[cs:InitStack]
1133 jmp 0:07C00h ; Jump to new boot sector
1135 .int18:
1136 int 18h ; Hope this does the right thing...
1137 jmp kaboom ; If we returned, oh boy...
1140 ; close_file:
1141 ; Deallocates a file structure (pointer in SI)
1142 ; Assumes CS == DS.
1144 close_file:
1145 and si,si
1146 jz .closed
1147 mov dword [si],0 ; First dword == file_left
1148 .closed: ret
1151 ; searchdir:
1153 ; Open a file
1155 ; On entry:
1156 ; DS:DI = filename
1157 ; If successful:
1158 ; ZF clear
1159 ; SI = file pointer
1160 ; DX:AX or EAX = file length in bytes
1161 ; If unsuccessful
1162 ; ZF set
1164 ; Assumes CS == DS == ES, and trashes BX and CX.
1166 ; searchdir_iso is a special entry point for ISOLINUX only. In addition
1167 ; to the above, searchdir_iso passes a file flag mask in AL. This is useful
1168 ; for searching for directories.
1170 alloc_failure:
1171 xor ax,ax ; ZF <- 1
1174 searchdir:
1175 xor al,al
1176 searchdir_iso:
1177 mov [ISOFlags],al
1178 TRACER 'S'
1179 call allocate_file ; Temporary file structure for directory
1180 jnz alloc_failure
1181 push es
1182 push ds
1183 pop es ; ES = DS
1184 mov si,CurDir
1185 cmp byte [di],'/' ; If filename begins with slash
1186 jne .not_rooted
1187 inc di ; Skip leading slash
1188 mov si,RootDir ; Reference root directory instead
1189 .not_rooted:
1190 mov eax,[si+dir_clust]
1191 mov [bx+file_left],eax
1192 mov eax,[si+dir_lba]
1193 mov [bx+file_sector],eax
1194 mov edx,[si+dir_len]
1196 .look_for_slash:
1197 mov ax,di
1198 .scan:
1199 mov cl,[di]
1200 inc di
1201 and cl,cl
1202 jz .isfile
1203 cmp cl,'/'
1204 jne .scan
1205 mov [di-1],byte 0 ; Terminate at directory name
1206 mov cl,02h ; Search for directory
1207 xchg cl,[ISOFlags]
1209 push di ; Save these...
1210 push cx
1212 ; Create recursion stack frame...
1213 push word .resume ; Where to "return" to
1214 push es
1215 .isfile: xchg ax,di
1217 .getsome:
1218 ; Get a chunk of the directory
1219 ; This relies on the fact that ISOLINUX doesn't change SI
1220 mov si,trackbuf
1221 TRACER 'g'
1222 pushad
1223 xchg bx,si
1224 mov cx,[BufSafe]
1225 call getfssec
1226 popad
1228 .compare:
1229 movzx eax,byte [si] ; Length of directory entry
1230 cmp al,33
1231 jb .next_sector
1232 TRACER 'c'
1233 mov cl,[si+25]
1234 xor cl,[ISOFlags]
1235 test cl, byte 8Eh ; Unwanted file attributes!
1236 jnz .not_file
1237 pusha
1238 movzx cx,byte [si+32] ; File identifier length
1239 add si,byte 33 ; File identifier offset
1240 TRACER 'i'
1241 call iso_compare_names
1242 popa
1243 je .success
1244 .not_file:
1245 sub edx,eax ; Decrease bytes left
1246 jbe .failure
1247 add si,ax ; Advance pointer
1249 .check_overrun:
1250 ; Did we finish the buffer?
1251 cmp si,trackbuf+trackbufsize
1252 jb .compare ; No, keep going
1254 jmp short .getsome ; Get some more directory
1256 .next_sector:
1257 ; Advance to the beginning of next sector
1258 lea ax,[si+SECTOR_SIZE-1]
1259 and ax,~(SECTOR_SIZE-1)
1260 sub ax,si
1261 jmp short .not_file ; We still need to do length checks
1263 .failure: xor eax,eax ; ZF = 1
1264 mov [bx+file_sector],eax
1265 pop es
1268 .success:
1269 mov eax,[si+2] ; Location of extent
1270 mov [bx+file_sector],eax
1271 mov eax,[si+10] ; Data length
1272 push eax
1273 add eax,SECTOR_SIZE-1
1274 shr eax,SECTOR_SHIFT
1275 mov [bx+file_left],eax
1276 pop eax
1277 mov edx,eax
1278 shr edx,16
1279 and bx,bx ; ZF = 0
1280 mov si,bx
1281 pop es
1284 .resume: ; We get here if we were only doing part of a lookup
1285 ; This relies on the fact that .success returns bx == si
1286 xchg edx,eax ; Directory length in edx
1287 pop cx ; Old ISOFlags
1288 pop di ; Next filename pointer
1289 mov byte [di-1], '/' ; Restore slash
1290 mov [ISOFlags],cl ; Restore the flags
1291 jz .failure ; Did we fail? If so fail for real!
1292 jmp .look_for_slash ; Otherwise, next level
1295 ; allocate_file: Allocate a file structure
1297 ; If successful:
1298 ; ZF set
1299 ; BX = file pointer
1300 ; In unsuccessful:
1301 ; ZF clear
1303 allocate_file:
1304 TRACER 'a'
1305 push cx
1306 mov bx,Files
1307 mov cx,MAX_OPEN
1308 .check: cmp dword [bx], byte 0
1309 je .found
1310 add bx,open_file_t_size ; ZF = 0
1311 loop .check
1312 ; ZF = 0 if we fell out of the loop
1313 .found: pop cx
1317 ; iso_compare_names:
1318 ; Compare the names DS:SI and DS:DI and report if they are
1319 ; equal from an ISO 9660 perspective. SI is the name from
1320 ; the filesystem; CX indicates its length, and ';' terminates.
1321 ; DI is expected to end with a null.
1323 ; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment
1326 iso_compare_names:
1327 ; First, terminate and canonicalize input filename
1328 push di
1329 mov di,ISOFileName
1330 .canon_loop: jcxz .canon_end
1331 lodsb
1332 dec cx
1333 cmp al,';'
1334 je .canon_end
1335 and al,al
1336 je .canon_end
1337 stosb
1338 cmp di,ISOFileNameEnd-1 ; Guard against buffer overrun
1339 jb .canon_loop
1340 .canon_end:
1341 cmp di,ISOFileName
1342 jbe .canon_done
1343 cmp byte [di-1],'.' ; Remove terminal dots
1344 jne .canon_done
1345 dec di
1346 jmp short .canon_end
1347 .canon_done:
1348 mov [di],byte 0 ; Null-terminate string
1349 pop di
1350 mov si,ISOFileName
1351 .compare:
1352 lodsb
1353 mov ah,[di]
1354 inc di
1355 and ax,ax
1356 jz .success ; End of string for both
1357 and al,al ; Is either one end of string?
1358 jz .failure ; If so, failure
1359 and ah,ah
1360 jz .failure
1361 or ax,2020h ; Convert to lower case
1362 cmp al,ah
1363 je .compare
1364 .failure: and ax,ax ; ZF = 0 (at least one will be nonzero)
1365 .success: ret
1368 ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed
1369 ; to by ES:DI; ends on encountering any whitespace.
1370 ; DI is preserved.
1372 ; This verifies that a filename is < FILENAME_MAX characters,
1373 ; doesn't contain whitespace, zero-pads the output buffer,
1374 ; and removes trailing dots and redundant slashes,
1375 ; so "repe cmpsb" can do a compare, and the
1376 ; path-searching routine gets a bit of an easier job.
1378 mangle_name:
1379 push di
1380 push bx
1381 xor ax,ax
1382 mov cx,FILENAME_MAX-1
1383 mov bx,di
1385 .mn_loop:
1386 lodsb
1387 cmp al,' ' ; If control or space, end
1388 jna .mn_end
1389 cmp al,ah ; Repeated slash?
1390 je .mn_skip
1391 xor ah,ah
1392 cmp al,'/'
1393 jne .mn_ok
1394 mov ah,al
1395 .mn_ok stosb
1396 .mn_skip: loop .mn_loop
1397 .mn_end:
1398 cmp bx,di ; At the beginning of the buffer?
1399 jbe .mn_zero
1400 cmp byte [es:di-1],'.' ; Terminal dot?
1401 je .mn_kill
1402 cmp byte [es:di-1],'/' ; Terminal slash?
1403 jne .mn_zero
1404 .mn_kill: dec di ; If so, remove it
1405 inc cx
1406 jmp short .mn_end
1407 .mn_zero:
1408 inc cx ; At least one null byte
1409 xor ax,ax ; Zero-fill name
1410 rep stosb
1411 pop bx
1412 pop di
1413 ret ; Done
1416 ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled
1417 ; filename to the conventional representation. This is needed
1418 ; for the BOOT_IMAGE= parameter for the kernel.
1419 ; NOTE: A 13-byte buffer is mandatory, even if the string is
1420 ; known to be shorter.
1422 ; DS:SI -> input mangled file name
1423 ; ES:DI -> output buffer
1425 ; On return, DI points to the first byte after the output name,
1426 ; which is set to a null byte.
1428 unmangle_name: call strcpy
1429 dec di ; Point to final null byte
1433 ; getfssec: Get multiple clusters from a file, given the file pointer.
1435 ; On entry:
1436 ; ES:BX -> Buffer
1437 ; SI -> File pointer
1438 ; CX -> Cluster count
1439 ; On exit:
1440 ; SI -> File pointer (or 0 on EOF)
1441 ; CF = 1 -> Hit EOF
1443 getfssec:
1444 TRACER 'F'
1446 push ds
1447 push cs
1448 pop ds ; DS <- CS
1450 movzx ecx,cx
1451 cmp ecx,[si+file_left]
1452 jna .ok_size
1453 mov ecx,[si+file_left]
1454 .ok_size:
1456 mov bp,cx
1457 push cx
1458 push si
1459 mov eax,[si+file_sector]
1460 TRACER 'l'
1461 call getlinsec
1462 xor ecx,ecx
1463 pop si
1464 pop cx
1466 add [si+file_sector],ecx
1467 sub [si+file_left],ecx
1468 ja .not_eof ; CF = 0
1470 xor ecx,ecx
1471 mov [si+file_sector],ecx ; Mark as unused
1472 xor si,si
1475 .not_eof:
1476 pop ds
1477 TRACER 'f'
1480 ; -----------------------------------------------------------------------------
1481 ; Common modules
1482 ; -----------------------------------------------------------------------------
1484 %include "getc.inc" ; getc et al
1485 %include "conio.inc" ; Console I/O
1486 %include "configinit.inc" ; Initialize configuration
1487 %include "parseconfig.inc" ; High-level config file handling
1488 %include "parsecmd.inc" ; Low-level config file handling
1489 %include "bcopy32.inc" ; 32-bit bcopy
1490 %include "loadhigh.inc" ; Load a file into high memory
1491 %include "font.inc" ; VGA font stuff
1492 %include "graphics.inc" ; VGA graphics
1493 %include "highmem.inc" ; High memory sizing
1494 %include "strcpy.inc" ; strcpy()
1495 %include "rawcon.inc" ; Console I/O w/o using the console functions
1497 ; -----------------------------------------------------------------------------
1498 ; Begin data section
1499 ; -----------------------------------------------------------------------------
1501 section .data
1503 localboot_msg db 'Booting from local disk...', CR, LF, 0
1504 default_str db 'default', 0
1505 default_len equ ($-default_str)
1506 boot_dir db '/boot' ; /boot/isolinux
1507 isolinux_dir db '/isolinux', 0
1508 config_name db 'isolinux.cfg', 0
1509 err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0
1511 %ifdef DEBUG_MESSAGES
1512 dbg_rootdir_msg db 'Root directory at LBA = ', 0
1513 dbg_isodir_msg db 'isolinux directory at LBA = ', 0
1514 dbg_config_msg db 'About to load config file...', CR, LF, 0
1515 dbg_configok_msg db 'Configuration file opened...', CR, LF, 0
1516 %endif
1518 ; Command line options we'd like to take a look at
1520 ; mem= and vga= are handled as normal 32-bit integer values
1521 initrd_cmd db 'initrd='
1522 initrd_cmd_len equ 7
1525 ; Config file keyword table
1527 %include "keywords.inc"
1530 ; Extensions to search for (in *forward* order).
1532 align 4, db 0
1533 exten_table: db '.cbt' ; COMBOOT (specific)
1534 db '.img' ; Disk image
1535 db '.bin' ; CD boot sector
1536 db '.com' ; COMBOOT (same as DOS)
1537 db '.c32' ; COM32
1538 exten_table_end:
1539 dd 0, 0 ; Need 8 null bytes here
1542 ; Floppy image table
1544 align 4, db 0
1545 img_table_count equ 3
1546 img_table:
1547 dd 1200*1024 ; 1200K floppy
1548 db 1 ; Emulation type
1549 db 80-1 ; Max cylinder
1550 db 15 ; Max sector
1551 db 2-1 ; Max head
1553 dd 1440*1024 ; 1440K floppy
1554 db 2 ; Emulation type
1555 db 80-1 ; Max cylinder
1556 db 18 ; Max sector
1557 db 2-1 ; Max head
1559 dd 2880*1024 ; 2880K floppy
1560 db 3 ; Emulation type
1561 db 80-1 ; Max cylinder
1562 db 36 ; Max sector
1563 db 2-1 ; Max head
1566 ; Misc initialized (data) variables
1570 ; Variables that are uninitialized in SYSLINUX but initialized here
1572 ; **** ISOLINUX:: We may have to make this flexible, based on what the
1573 ; **** BIOS expects our "sector size" to be.
1575 alignb 4, db 0
1576 BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf
1577 BufSafeBytes dw trackbufsize ; = how many bytes?
1578 %ifndef DEPEND
1579 %if ( trackbufsize % SECTOR_SIZE ) != 0
1580 %error trackbufsize must be a multiple of SECTOR_SIZE
1581 %endif
1582 %endif