Set the window size to 2 GB for linear framebuffer
[syslinux.git] / isolinux.asm
blob81caf76619eba034bb1f981e9effdf3f752fc2e7
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 1994-2008 H. Peter Anvin - All Rights Reserved
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 ; ends at 2800h
107 ; Some of these are touched before the whole image
108 ; is loaded. DO NOT move this to .uibss.
109 section .bss1
110 alignb 4
111 ISOFileName resb 64 ; ISO filename canonicalization buffer
112 ISOFileNameEnd equ $
113 CurDir resb dir_t_size ; Current directory
114 RootDir resb dir_t_size ; Root directory
115 FirstSecSum resd 1 ; Checksum of bytes 64-2048
116 ImageDwords resd 1 ; isolinux.bin size, dwords
117 InitStack resd 1 ; Initial stack pointer (SS:SP)
118 DiskSys resw 1 ; Last INT 13h call
119 ImageSectors resw 1 ; isolinux.bin size, sectors
120 DiskError resb 1 ; Error code for disk I/O
121 DriveNumber resb 1 ; CD-ROM BIOS drive number
122 ISOFlags resb 1 ; Flags for ISO directory search
123 RetryCount resb 1 ; Used for disk access retries
125 _spec_start equ $
128 ; El Torito spec packet
131 alignb 8
132 spec_packet: resb 1 ; Size of packet
133 sp_media: resb 1 ; Media type
134 sp_drive: resb 1 ; Drive number
135 sp_controller: resb 1 ; Controller index
136 sp_lba: resd 1 ; LBA for emulated disk image
137 sp_devspec: resw 1 ; IDE/SCSI information
138 sp_buffer: resw 1 ; User-provided buffer
139 sp_loadseg: resw 1 ; Load segment
140 sp_sectors: resw 1 ; Sector count
141 sp_chs: resb 3 ; Simulated CHS geometry
142 sp_dummy: resb 1 ; Scratch, safe to overwrite
145 ; EBIOS drive parameter packet
147 alignb 8
148 drive_params: resw 1 ; Buffer size
149 dp_flags: resw 1 ; Information flags
150 dp_cyl: resd 1 ; Physical cylinders
151 dp_head: resd 1 ; Physical heads
152 dp_sec: resd 1 ; Physical sectors/track
153 dp_totalsec: resd 2 ; Total sectors
154 dp_secsize: resw 1 ; Bytes per sector
155 dp_dpte: resd 1 ; Device Parameter Table
156 dp_dpi_key: resw 1 ; 0BEDDh if rest valid
157 dp_dpi_len: resb 1 ; DPI len
158 resb 1
159 resw 1
160 dp_bus: resb 4 ; Host bus type
161 dp_interface: resb 8 ; Interface type
162 db_i_path: resd 2 ; Interface path
163 db_d_path: resd 2 ; Device path
164 resb 1
165 db_dpi_csum: resb 1 ; Checksum for DPI info
168 ; EBIOS disk address packet
170 alignb 8
171 dapa: resw 1 ; Packet size
172 .count: resw 1 ; Block count
173 .off: resw 1 ; Offset of buffer
174 .seg: resw 1 ; Segment of buffer
175 .lba: resd 2 ; LBA (LSW, MSW)
178 ; Spec packet for disk image emulation
180 alignb 8
181 dspec_packet: resb 1 ; Size of packet
182 dsp_media: resb 1 ; Media type
183 dsp_drive: resb 1 ; Drive number
184 dsp_controller: resb 1 ; Controller index
185 dsp_lba: resd 1 ; LBA for emulated disk image
186 dsp_devspec: resw 1 ; IDE/SCSI information
187 dsp_buffer: resw 1 ; User-provided buffer
188 dsp_loadseg: resw 1 ; Load segment
189 dsp_sectors: resw 1 ; Sector count
190 dsp_chs: resb 3 ; Simulated CHS geometry
191 dsp_dummy: resb 1 ; Scratch, safe to overwrite
193 alignb 4
194 _spec_end equ $
195 _spec_len equ _spec_end - _spec_start
197 alignb open_file_t_size
198 Files resb MAX_OPEN*open_file_t_size
200 section .text
202 ;; Primary entry point. Because BIOSes are buggy, we only load the first
203 ;; CD-ROM sector (2K) of the file, so the number one priority is actually
204 ;; loading the rest.
206 StackBuf equ $-44 ; 44 bytes needed for
207 ; the bootsector chainloading
208 ; code!
209 OrigESDI equ StackBuf-4 ; The high dword on the stack
211 bootsec equ $
213 _start: ; Far jump makes sure we canonicalize the address
215 jmp 0:_start1
216 times 8-($-$$) nop ; Pad to file offset 8
218 ; This table hopefully gets filled in by mkisofs using the
219 ; -boot-info-table option. If not, the values in this
220 ; table are default values that we can use to get us what
221 ; we need, at least under a certain set of assumptions.
222 bi_pvd: dd 16 ; LBA of primary volume descriptor
223 bi_file: dd 0 ; LBA of boot file
224 bi_length: dd 0xdeadbeef ; Length of boot file
225 bi_csum: dd 0xdeadbeef ; Checksum of boot file
226 bi_reserved: times 10 dd 0xdeadbeef ; Reserved
228 _start1: mov [cs:InitStack],sp ; Save initial stack pointer
229 mov [cs:InitStack+2],ss
230 xor ax,ax
231 mov ss,ax
232 mov sp,StackBuf ; Set up stack
233 push es ; Save initial ES:DI -> $PnP pointer
234 push di
235 mov ds,ax
236 mov es,ax
237 mov fs,ax
238 mov gs,ax
242 ; Show signs of life
243 mov si,syslinux_banner
244 call writestr
245 %ifdef DEBUG_MESSAGES
246 mov si,copyright_str
247 call writestr
248 %endif
251 ; Before modifying any memory, get the checksum of bytes
252 ; 64-2048
254 initial_csum: xor edi,edi
255 mov si,_start1
256 mov cx,(SECTOR_SIZE-64) >> 2
257 .loop: lodsd
258 add edi,eax
259 loop .loop
260 mov [FirstSecSum],edi
262 mov [DriveNumber],dl
263 %ifdef DEBUG_MESSAGES
264 mov si,startup_msg
265 call writemsg
266 mov al,dl
267 call writehex2
268 call crlf
269 %endif
271 ; Initialize spec packet buffers
273 mov di,_spec_start
274 mov cx,_spec_len >> 2
275 xor eax,eax
276 rep stosd
278 ; Initialize length field of the various packets
279 mov byte [spec_packet],13h
280 mov byte [drive_params],30
281 mov byte [dapa],16
282 mov byte [dspec_packet],13h
284 ; Other nonzero fields
285 inc word [dsp_sectors]
287 ; Now figure out what we're actually doing
288 ; Note: use passed-in DL value rather than 7Fh because
289 ; at least some BIOSes will get the wrong value otherwise
290 mov ax,4B01h ; Get disk emulation status
291 mov dl,[DriveNumber]
292 mov si,spec_packet
293 call int13
294 jc award_hack ; changed for BrokenAwardHack
295 mov dl,[DriveNumber]
296 cmp [sp_drive],dl ; Should contain the drive number
297 jne spec_query_failed
299 %ifdef DEBUG_MESSAGES
300 mov si,spec_ok_msg
301 call writemsg
302 mov al,byte [sp_drive]
303 call writehex2
304 call crlf
305 %endif
307 found_drive:
308 ; Alright, we have found the drive. Now, try to find the
309 ; boot file itself. If we have a boot info table, life is
310 ; good; if not, we have to make some assumptions, and try
311 ; to figure things out ourselves. In particular, the
312 ; assumptions we have to make are:
313 ; - single session only
314 ; - only one boot entry (no menu or other alternatives)
316 cmp dword [bi_file],0 ; Address of code to load
317 jne found_file ; Boot info table present :)
319 %ifdef DEBUG_MESSAGES
320 mov si,noinfotable_msg
321 call writemsg
322 %endif
324 ; No such luck. See if the the spec packet contained one.
325 mov eax,[sp_lba]
326 and eax,eax
327 jz set_file ; Good enough
329 %ifdef DEBUG_MESSAGES
330 mov si,noinfoinspec_msg
331 call writemsg
332 %endif
334 ; No such luck. Get the Boot Record Volume, assuming single
335 ; session disk, and that we're the first entry in the chain
336 mov eax,17 ; Assumed address of BRV
337 mov bx,trackbuf
338 call getonesec
340 mov eax,[trackbuf+47h] ; Get boot catalog address
341 mov bx,trackbuf
342 call getonesec ; Get boot catalog
344 mov eax,[trackbuf+28h] ; First boot entry
345 ; And hope and pray this is us...
347 ; Some BIOSes apparently have limitations on the size
348 ; that may be loaded (despite the El Torito spec being very
349 ; clear on the fact that it must all be loaded.) Therefore,
350 ; we load it ourselves, and *bleep* the BIOS.
352 set_file:
353 mov [bi_file],eax
355 found_file:
356 ; Set up boot file sizes
357 mov eax,[bi_length]
358 sub eax,SECTOR_SIZE-3
359 shr eax,2 ; bytes->dwords
360 mov [ImageDwords],eax ; boot file dwords
361 add eax,(2047 >> 2)
362 shr eax,9 ; dwords->sectors
363 mov [ImageSectors],ax ; boot file sectors
365 mov eax,[bi_file] ; Address of code to load
366 inc eax ; Don't reload bootstrap code
367 %ifdef DEBUG_MESSAGES
368 mov si,offset_msg
369 call writemsg
370 call writehex8
371 call crlf
372 %endif
374 ; Just in case some BIOSes have problems with
375 ; segment wraparound, use the normalized address
376 mov bx,((7C00h+2048) >> 4)
377 mov es,bx
378 xor bx,bx
379 mov bp,[ImageSectors]
380 %ifdef DEBUG_MESSAGES
381 push ax
382 mov si,size_msg
383 call writemsg
384 mov ax,bp
385 call writehex4
386 call crlf
387 pop ax
388 %endif
389 call getlinsec
391 push ds
392 pop es
394 %ifdef DEBUG_MESSAGES
395 mov si,loaded_msg
396 call writemsg
397 %endif
399 ; Verify the checksum on the loaded image.
400 verify_image:
401 mov si,7C00h+2048
402 mov bx,es
403 mov ecx,[ImageDwords]
404 mov edi,[FirstSecSum] ; First sector checksum
405 .loop es lodsd
406 add edi,eax
407 dec ecx
408 jz .done
409 and si,si
410 jnz .loop
411 ; SI wrapped around, advance ES
412 add bx,1000h
413 mov es,bx
414 jmp short .loop
415 .done: mov ax,ds
416 mov es,ax
417 cmp [bi_csum],edi
418 je integrity_ok
420 mov si,checkerr_msg
421 call writemsg
422 jmp kaboom
424 integrity_ok:
425 %ifdef DEBUG_MESSAGES
426 mov si,allread_msg
427 call writemsg
428 %endif
429 jmp all_read ; Jump to main code
431 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
432 ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
435 ;; There is a problem with certain versions of the AWARD BIOS ...
436 ;; the boot sector will be loaded and executed correctly, but, because the
437 ;; int 13 vector points to the wrong code in the BIOS, every attempt to
438 ;; load the spec packet will fail. We scan for the equivalent of
440 ;; mov ax,0201h
441 ;; mov bx,7c00h
442 ;; mov cx,0006h
443 ;; mov dx,0180h
444 ;; pushf
445 ;; call <direct far>
447 ;; and use <direct far> as the new vector for int 13. The code above is
448 ;; used to load the boot code into ram, and there should be no reason
449 ;; for anybody to change it now or in the future. There are no opcodes
450 ;; that use encodings relativ to IP, so scanning is easy. If we find the
451 ;; code above in the BIOS code we can be pretty sure to run on a machine
452 ;; with an broken AWARD BIOS ...
454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
456 %ifdef DEBUG_MESSAGES ;;
458 award_notice db "Trying BrokenAwardHack first ...",CR,LF,0 ;;
459 award_not_orig db "BAH: Original Int 13 vector : ",0 ;;
460 award_not_new db "BAH: Int 13 vector changed to : ",0 ;;
461 award_not_succ db "BAH: SUCCESS",CR,LF,0 ;;
462 award_not_fail db "BAH: FAILURE" ;;
463 award_not_crlf db CR,LF,0 ;;
465 %endif ;;
467 award_oldint13 dd 0 ;;
468 award_string db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah ;;
470 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
471 award_hack: mov si,spec_err_msg ; Moved to this place from
472 call writemsg ; spec_query_faild
474 %ifdef DEBUG_MESSAGES ;
476 mov si,award_notice ; display our plan
477 call writemsg ;
478 mov si,award_not_orig ; display original int 13
479 call writemsg ; vector
480 %endif ;
481 mov eax,[13h*4] ;
482 mov [award_oldint13],eax ;
484 %ifdef DEBUG_MESSAGES ;
486 call writehex8 ;
487 mov si,award_not_crlf ;
488 call writestr ;
489 %endif ;
490 push es ; save ES
491 mov ax,0f000h ; ES = BIOS Seg
492 mov es,ax ;
493 cld ;
494 xor di,di ; start at ES:DI = f000:0
495 award_loop: push di ; save DI
496 mov si,award_string ; scan for award_string
497 mov cx,7 ; length of award_string = 7dw
498 repz cmpsw ; compare
499 pop di ; restore DI
500 jcxz award_found ; jmp if found
501 inc di ; not found, inc di
502 jno award_loop ;
504 award_failed: pop es ; No, not this way :-((
505 award_fail2: ;
507 %ifdef DEBUG_MESSAGES ;
509 mov si,award_not_fail ; display failure ...
510 call writemsg ;
511 %endif ;
512 mov eax,[award_oldint13] ; restore the original int
513 or eax,eax ; 13 vector if there is one
514 jz spec_query_failed ; and try other workarounds
515 mov [13h*4],eax ;
516 jmp spec_query_failed ;
518 award_found: mov eax,[es:di+0eh] ; load possible int 13 addr
519 pop es ; restore ES
521 cmp eax,[award_oldint13] ; give up if this is the
522 jz award_failed ; active int 13 vector,
523 mov [13h*4],eax ; otherwise change 0:13h*4
526 %ifdef DEBUG_MESSAGES ;
528 push eax ; display message and
529 mov si,award_not_new ; new vector address
530 call writemsg ;
531 pop eax ;
532 call writehex8 ;
533 mov si,award_not_crlf ;
534 call writestr ;
535 %endif ;
536 mov ax,4B01h ; try to read the spec packet
537 mov dl,[DriveNumber] ; now ... it should not fail
538 mov si,spec_packet ; any longer
539 int 13h ;
540 jc award_fail2 ;
542 %ifdef DEBUG_MESSAGES ;
544 mov si,award_not_succ ; display our SUCCESS
545 call writemsg ;
546 %endif ;
547 jmp found_drive ; and leave error recovery code
549 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
550 ;; End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de
551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
554 ; INT 13h, AX=4B01h, DL=<passed in value> failed.
555 ; Try to scan the entire 80h-FFh from the end.
557 spec_query_failed:
559 ; some code moved to BrokenAwardHack
561 mov dl,0FFh
562 .test_loop: pusha
563 mov ax,4B01h
564 mov si,spec_packet
565 mov byte [si],13h ; Size of buffer
566 call int13
567 popa
568 jc .still_broken
570 mov si,maybe_msg
571 call writemsg
572 mov al,dl
573 call writehex2
574 call crlf
576 cmp byte [sp_drive],dl
577 jne .maybe_broken
579 ; Okay, good enough...
580 mov si,alright_msg
581 call writemsg
582 mov [DriveNumber],dl
583 .found_drive: jmp found_drive
585 ; Award BIOS 4.51 apparently passes garbage in sp_drive,
586 ; but if this was the drive number originally passed in
587 ; DL then consider it "good enough"
588 .maybe_broken:
589 cmp byte [DriveNumber],dl
590 je .found_drive
592 .still_broken: dec dx
593 cmp dl, 80h
594 jnb .test_loop
596 ; No spec packet anywhere. Some particularly pathetic
597 ; BIOSes apparently don't even implement function
598 ; 4B01h, so we can't query a spec packet no matter
599 ; what. If we got a drive number in DL, then try to
600 ; use it, and if it works, then well...
601 mov dl,[DriveNumber]
602 cmp dl,81h ; Should be 81-FF at least
603 jb fatal_error ; If not, it's hopeless
605 ; Write a warning to indicate we're on *very* thin ice now
606 mov si,nospec_msg
607 call writemsg
608 mov al,dl
609 call writehex2
610 call crlf
611 mov si,trysbm_msg
612 call writemsg
613 jmp .found_drive ; Pray that this works...
615 fatal_error:
616 mov si,nothing_msg
617 call writemsg
619 .norge: jmp short .norge
621 ; Information message (DS:SI) output
622 ; Prefix with "isolinux: "
624 writemsg: push ax
625 push si
626 mov si,isolinux_str
627 call writestr
628 pop si
629 call writestr
630 pop ax
634 ; Write a character to the screen. There is a more "sophisticated"
635 ; version of this in the subsequent code, so we patch the pointer
636 ; when appropriate.
639 writechr:
640 jmp near writechr_simple ; 3-byte jump
642 writechr_simple:
643 pushfd
644 pushad
645 mov ah,0Eh
646 xor bx,bx
647 int 10h
648 popad
649 popfd
653 ; int13: save all the segment registers and call INT 13h
654 ; Some CD-ROM BIOSes have been found to corrupt segment registers.
656 int13:
658 push ds
659 push es
660 push fs
661 push gs
662 int 13h
663 pop gs
664 pop fs
665 pop es
666 pop ds
670 ; Get one sector. Convenience entry point.
672 getonesec:
673 mov bp,1
674 ; Fall through to getlinsec
677 ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
679 ; Note that we can't always do this as a single request, because at least
680 ; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick
681 ; to 32 sectors (64K) per request.
683 ; Input:
684 ; EAX - Linear sector number
685 ; ES:BX - Target buffer
686 ; BP - Sector count
688 getlinsec:
689 mov si,dapa ; Load up the DAPA
690 mov [si+4],bx
691 mov bx,es
692 mov [si+6],bx
693 mov [si+8],eax
694 .loop:
695 push bp ; Sectors left
696 cmp bp,[MaxTransfer]
697 jbe .bp_ok
698 mov bp,[MaxTransfer]
699 .bp_ok:
700 mov [si+2],bp
701 push si
702 mov dl,[DriveNumber]
703 mov ah,42h ; Extended Read
704 call xint13
705 pop si
706 pop bp
707 movzx eax,word [si+2] ; Sectors we read
708 add [si+8],eax ; Advance sector pointer
709 sub bp,ax ; Sectors left
710 shl ax,SECTOR_SHIFT-4 ; 2048-byte sectors -> segment
711 add [si+6],ax ; Advance buffer pointer
712 and bp,bp
713 jnz .loop
714 mov eax,[si+8] ; Next sector
717 ; INT 13h with retry
718 xint13: mov byte [RetryCount],retry_count
719 .try: pushad
720 call int13
721 jc .error
722 add sp,byte 8*4 ; Clean up stack
724 .error:
725 mov [DiskError],ah ; Save error code
726 popad
727 mov [DiskSys],ax ; Save system call number
728 dec byte [RetryCount]
729 jz .real_error
730 push ax
731 mov al,[RetryCount]
732 mov ah,[dapa+2] ; Sector transfer count
733 cmp al,2 ; Only 2 attempts left
734 ja .nodanger
735 mov ah,1 ; Drop transfer size to 1
736 jmp short .setsize
737 .nodanger:
738 cmp al,retry_count-2
739 ja .again ; First time, just try again
740 shr ah,1 ; Otherwise, try to reduce
741 adc ah,0 ; the max transfer size, but not to 0
742 .setsize:
743 mov [MaxTransfer],ah
744 mov [dapa+2],ah
745 .again:
746 pop ax
747 jmp .try
749 .real_error: mov si,diskerr_msg
750 call writemsg
751 mov al,[DiskError]
752 call writehex2
753 mov si,oncall_str
754 call writestr
755 mov ax,[DiskSys]
756 call writehex4
757 mov si,ondrive_str
758 call writestr
759 mov al,dl
760 call writehex2
761 call crlf
762 ; Fall through to kaboom
765 ; kaboom: write a message and bail out. Wait for a user keypress,
766 ; then do a hard reboot.
768 kaboom:
769 RESET_STACK_AND_SEGS AX
770 mov si,err_bootfailed
771 call cwritestr
772 call getchar
774 mov word [BIOS_magic],0 ; Cold reboot
775 jmp 0F000h:0FFF0h ; Reset vector address
777 ; -----------------------------------------------------------------------------
778 ; Common modules needed in the first sector
779 ; -----------------------------------------------------------------------------
781 %include "writestr.inc" ; String output
782 writestr equ cwritestr
783 %include "writehex.inc" ; Hexadecimal output
785 ; -----------------------------------------------------------------------------
786 ; Data that needs to be in the first sector
787 ; -----------------------------------------------------------------------------
789 syslinux_banner db CR, LF, 'ISOLINUX ', version_str, ' ', date, ' ', 0
790 copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin'
791 db CR, LF, 0
792 isolinux_str db 'isolinux: ', 0
793 %ifdef DEBUG_MESSAGES
794 startup_msg: db 'Starting up, DL = ', 0
795 spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
796 secsize_msg: db 'Sector size appears to be ', 0
797 offset_msg: db 'Loading main image from LBA = ', 0
798 size_msg: db 'Sectors to load = ', 0
799 loaded_msg: db 'Loaded boot image, verifying...', CR, LF, 0
800 verify_msg: db 'Image checksum verified.', CR, LF, 0
801 allread_msg db 'Main image read, jumping to main code...', CR, LF, 0
802 %endif
803 noinfotable_msg db 'No boot info table, assuming single session disk...', CR, LF, 0
804 noinfoinspec_msg db 'Spec packet missing LBA information, trying to wing it...', CR, LF, 0
805 spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0
806 maybe_msg: db 'Found something at drive = ', 0
807 alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0
808 nospec_msg db 'Extremely broken BIOS detected, last ditch attempt with drive = ', 0
809 nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF
810 trysbm_msg db 'See http://syslinux.zytor.com/sbm for more information.', CR, LF, 0
811 diskerr_msg: db 'Disk error ', 0
812 oncall_str: db ', AX = ',0
813 ondrive_str: db ', drive ', 0
814 checkerr_msg: db 'Image checksum error, sorry...', CR, LF, 0
816 err_bootfailed db CR, LF, 'Boot failed: press a key to retry...'
817 bailmsg equ err_bootfailed
818 crlf_msg db CR, LF
819 null_msg db 0
821 alignb 4, db 0
822 MaxTransfer dw 32 ; Max sectors per transfer
824 rl_checkpt equ $ ; Must be <= 800h
826 rl_checkpt_off equ ($-$$)
827 ;%ifndef DEPEND
828 ;%if rl_checkpt_off > 0x800
829 ;%error "Sector 0 overflow"
830 ;%endif
831 ;%endif
833 ; ----------------------------------------------------------------------------
834 ; End of code and data that have to be in the first sector
835 ; ----------------------------------------------------------------------------
837 all_read:
839 ; Test tracers
840 TRACER 'T'
841 TRACER '>'
844 ; Common initialization code
846 %include "init.inc"
847 %include "cpuinit.inc"
849 ; Patch the writechr routine to point to the full code
850 mov word [writechr+1], writechr_full-(writechr+3)
852 ; Tell the user we got this far...
853 %ifndef DEBUG_MESSAGES ; Gets messy with debugging on
854 mov si,copyright_str
855 call writestr
856 %endif
859 ; Now we're all set to start with our *real* business. First load the
860 ; configuration file (if any) and parse it.
862 ; In previous versions I avoided using 32-bit registers because of a
863 ; rumour some BIOSes clobbered the upper half of 32-bit registers at
864 ; random. I figure, though, that if there are any of those still left
865 ; they probably won't be trying to install Linux on them...
867 ; The code is still ripe with 16-bitisms, though. Not worth the hassle
868 ; to take'm out. In fact, we may want to put them back if we're going
869 ; to boot ELKS at some point.
873 ; Now, we need to sniff out the actual filesystem data structures.
874 ; mkisofs gave us a pointer to the primary volume descriptor
875 ; (which will be at 16 only for a single-session disk!); from the PVD
876 ; we should be able to find the rest of what we need to know.
878 get_fs_structures:
879 mov eax,[bi_pvd]
880 mov bx,trackbuf
881 call getonesec
883 mov eax,[trackbuf+156+2]
884 mov [RootDir+dir_lba],eax
885 mov [CurDir+dir_lba],eax
886 %ifdef DEBUG_MESSAGES
887 mov si,dbg_rootdir_msg
888 call writemsg
889 call writehex8
890 call crlf
891 %endif
892 mov eax,[trackbuf+156+10]
893 mov [RootDir+dir_len],eax
894 mov [CurDir+dir_len],eax
895 add eax,SECTOR_SIZE-1
896 shr eax,SECTOR_SHIFT
897 mov [RootDir+dir_clust],eax
898 mov [CurDir+dir_clust],eax
900 ; Look for an isolinux directory, and if found,
901 ; make it the current directory instead of the root
902 ; directory.
903 mov di,boot_dir ; Search for /boot/isolinux
904 mov al,02h
905 call searchdir_iso
906 jnz .found_dir
907 mov di,isolinux_dir
908 mov al,02h ; Search for /isolinux
909 call searchdir_iso
910 jz .no_isolinux_dir
911 .found_dir:
912 mov [CurDir+dir_len],eax
913 mov eax,[si+file_left]
914 mov [CurDir+dir_clust],eax
915 xor eax,eax ; Free this file pointer entry
916 xchg eax,[si+file_sector]
917 mov [CurDir+dir_lba],eax
918 %ifdef DEBUG_MESSAGES
919 push si
920 mov si,dbg_isodir_msg
921 call writemsg
922 pop si
923 call writehex8
924 call crlf
925 %endif
926 .no_isolinux_dir:
929 ; Locate the configuration file
931 load_config:
932 %ifdef DEBUG_MESSAGES
933 mov si,dbg_config_msg
934 call writemsg
935 %endif
937 mov si,config_name
938 mov di,ConfigName
939 call strcpy
941 mov di,ConfigName
942 call open
943 jz no_config_file ; Not found or empty
945 %ifdef DEBUG_MESSAGES
946 mov si,dbg_configok_msg
947 call writemsg
948 %endif
951 ; Now we have the config file open. Parse the config file and
952 ; run the user interface.
954 %include "ui.inc"
957 ; Enable disk emulation. The kind of disk we emulate is dependent on the size of
958 ; the file: 1200K, 1440K or 2880K floppy, otherwise harddisk.
960 is_disk_image:
961 TRACER CR
962 TRACER LF
963 TRACER 'D'
964 TRACER ':'
966 shl edx,16
967 mov dx,ax ; Set EDX <- file size
968 mov di,img_table
969 mov cx,img_table_count
970 mov eax,[si+file_sector] ; Starting LBA of file
971 mov [dsp_lba],eax ; Location of file
972 mov byte [dsp_drive], 0 ; 00h floppy, 80h hard disk
973 .search_table:
974 TRACER 't'
975 mov eax,[di+4]
976 cmp edx,[di]
977 je .type_found
978 add di,8
979 loop .search_table
981 ; Hard disk image. Need to examine the partition table
982 ; in order to deduce the C/H/S geometry. Sigh.
983 .hard_disk_image:
984 TRACER 'h'
985 cmp edx,512
986 jb .bad_image
988 mov bx,trackbuf
989 mov cx,1 ; Load 1 sector
990 call getfssec
992 cmp word [trackbuf+510],0aa55h ; Boot signature
993 jne .bad_image ; Image not bootable
995 mov cx,4 ; 4 partition entries
996 mov di,trackbuf+446 ; Start of partition table
998 xor ax,ax ; Highest sector(al) head(ah)
1000 .part_scan:
1001 cmp byte [di+4], 0
1002 jz .part_loop
1003 lea si,[di+1]
1004 call .hs_check
1005 add si,byte 4
1006 call .hs_check
1007 .part_loop:
1008 add di,byte 16
1009 loop .part_scan
1011 push eax ; H/S
1012 push edx ; File size
1013 mov bl,ah
1014 xor bh,bh
1015 inc bx ; # of heads in BX
1016 xor ah,ah ; # of sectors in AX
1017 cwde ; EAX[31:16] <- 0
1018 mul bx
1019 shl eax,9 ; Convert to bytes
1020 ; Now eax contains the number of bytes per cylinder
1021 pop ebx ; File size
1022 xor edx,edx
1023 div ebx
1024 and edx,edx
1025 jz .no_remainder
1026 inc eax ; Fractional cylinder...
1027 ; Now (e)ax contains the number of cylinders
1028 .no_remainder: cmp eax,1024
1029 jna .ok_cyl
1030 mov ax,1024 ; Max possible #
1031 .ok_cyl: dec ax ; Convert to max cylinder no
1032 pop ebx ; S(bl) H(bh)
1033 shl ah,6
1034 or bl,ah
1035 xchg ax,bx
1036 shl eax,16
1037 mov ah,bl
1038 mov al,4 ; Hard disk boot
1039 mov byte [dsp_drive], 80h ; Drive 80h = hard disk
1041 .type_found:
1042 TRACER 'T'
1043 mov bl,[sp_media]
1044 and bl,0F0h ; Copy controller info bits
1045 or al,bl
1046 mov [dsp_media],al ; Emulation type
1047 shr eax,8
1048 mov [dsp_chs],eax ; C/H/S geometry
1049 mov ax,[sp_devspec] ; Copy device spec
1050 mov [dsp_devspec],ax
1051 mov al,[sp_controller] ; Copy controller index
1052 mov [dsp_controller],al
1054 TRACER 'V'
1055 call vgaclearmode ; Reset video
1057 mov ax,4C00h ; Enable emulation and boot
1058 mov si,dspec_packet
1059 mov dl,[DriveNumber]
1060 lss sp,[InitStack]
1061 TRACER 'X'
1063 call int13
1065 ; If this returns, we have problems
1066 .bad_image:
1067 mov si,err_disk_image
1068 call cwritestr
1069 jmp enter_command
1072 ; Look for the highest seen H/S geometry
1073 ; We compute cylinders separately
1075 .hs_check:
1076 mov bl,[si] ; Head #
1077 cmp bl,ah
1078 jna .done_track
1079 mov ah,bl ; New highest head #
1080 .done_track: mov bl,[si+1]
1081 and bl,3Fh ; Sector #
1082 cmp bl,al
1083 jna .done_sector
1084 mov al,bl
1085 .done_sector: ret
1088 ; Boot a specified local disk. AX specifies the BIOS disk number; or
1089 ; 0xFFFF in case we should execute INT 18h ("next device.")
1091 local_boot:
1092 call vgaclearmode
1093 lss sp,[cs:Stack] ; Restore stack pointer
1094 xor dx,dx
1095 mov ds,dx
1096 mov es,dx
1097 mov fs,dx
1098 mov gs,dx
1099 mov si,localboot_msg
1100 call writestr
1101 cmp ax,-1
1102 je .int18
1104 ; Load boot sector from the specified BIOS device and jump to it.
1105 mov dl,al
1106 xor dh,dh
1107 push dx
1108 xor ax,ax ; Reset drive
1109 call xint13
1110 mov ax,0201h ; Read one sector
1111 mov cx,0001h ; C/H/S = 0/0/1 (first sector)
1112 mov bx,trackbuf
1113 call xint13
1114 pop dx
1115 cli ; Abandon hope, ye who enter here
1116 mov si,trackbuf
1117 mov di,07C00h
1118 mov cx,512 ; Probably overkill, but should be safe
1119 rep movsd
1120 lss sp,[cs:InitStack]
1121 jmp 0:07C00h ; Jump to new boot sector
1123 .int18:
1124 int 18h ; Hope this does the right thing...
1125 jmp kaboom ; If we returned, oh boy...
1128 ; close_file:
1129 ; Deallocates a file structure (pointer in SI)
1130 ; Assumes CS == DS.
1132 close_file:
1133 and si,si
1134 jz .closed
1135 mov dword [si],0 ; First dword == file_left
1136 .closed: ret
1139 ; searchdir:
1141 ; Open a file
1143 ; On entry:
1144 ; DS:DI = filename
1145 ; If successful:
1146 ; ZF clear
1147 ; SI = file pointer
1148 ; DX:AX or EAX = file length in bytes
1149 ; If unsuccessful
1150 ; ZF set
1152 ; Assumes CS == DS == ES, and trashes BX and CX.
1154 ; searchdir_iso is a special entry point for ISOLINUX only. In addition
1155 ; to the above, searchdir_iso passes a file flag mask in AL. This is useful
1156 ; for searching for directories.
1158 alloc_failure:
1159 xor ax,ax ; ZF <- 1
1162 searchdir:
1163 xor al,al
1164 searchdir_iso:
1165 mov [ISOFlags],al
1166 TRACER 'S'
1167 call allocate_file ; Temporary file structure for directory
1168 jnz alloc_failure
1169 push es
1170 push ds
1171 pop es ; ES = DS
1172 mov si,CurDir
1173 cmp byte [di],'/' ; If filename begins with slash
1174 jne .not_rooted
1175 inc di ; Skip leading slash
1176 mov si,RootDir ; Reference root directory instead
1177 .not_rooted:
1178 mov eax,[si+dir_clust]
1179 mov [bx+file_left],eax
1180 mov eax,[si+dir_lba]
1181 mov [bx+file_sector],eax
1182 mov edx,[si+dir_len]
1184 .look_for_slash:
1185 mov ax,di
1186 .scan:
1187 mov cl,[di]
1188 inc di
1189 and cl,cl
1190 jz .isfile
1191 cmp cl,'/'
1192 jne .scan
1193 mov [di-1],byte 0 ; Terminate at directory name
1194 mov cl,02h ; Search for directory
1195 xchg cl,[ISOFlags]
1197 push di ; Save these...
1198 push cx
1200 ; Create recursion stack frame...
1201 push word .resume ; Where to "return" to
1202 push es
1203 .isfile: xchg ax,di
1205 .getsome:
1206 ; Get a chunk of the directory
1207 ; This relies on the fact that ISOLINUX doesn't change SI
1208 mov si,trackbuf
1209 TRACER 'g'
1210 pushad
1211 xchg bx,si
1212 mov cx,[BufSafe]
1213 call getfssec
1214 popad
1216 .compare:
1217 movzx eax,byte [si] ; Length of directory entry
1218 cmp al,33
1219 jb .next_sector
1220 TRACER 'c'
1221 mov cl,[si+25]
1222 xor cl,[ISOFlags]
1223 test cl, byte 8Eh ; Unwanted file attributes!
1224 jnz .not_file
1225 pusha
1226 movzx cx,byte [si+32] ; File identifier length
1227 add si,byte 33 ; File identifier offset
1228 TRACER 'i'
1229 call iso_compare_names
1230 popa
1231 je .success
1232 .not_file:
1233 sub edx,eax ; Decrease bytes left
1234 jbe .failure
1235 add si,ax ; Advance pointer
1237 .check_overrun:
1238 ; Did we finish the buffer?
1239 cmp si,trackbuf+trackbufsize
1240 jb .compare ; No, keep going
1242 jmp short .getsome ; Get some more directory
1244 .next_sector:
1245 ; Advance to the beginning of next sector
1246 lea ax,[si+SECTOR_SIZE-1]
1247 and ax,~(SECTOR_SIZE-1)
1248 sub ax,si
1249 jmp short .not_file ; We still need to do length checks
1251 .failure: xor eax,eax ; ZF = 1
1252 mov [bx+file_sector],eax
1253 pop es
1256 .success:
1257 mov eax,[si+2] ; Location of extent
1258 mov [bx+file_sector],eax
1259 mov eax,[si+10] ; Data length
1260 push eax
1261 add eax,SECTOR_SIZE-1
1262 shr eax,SECTOR_SHIFT
1263 mov [bx+file_left],eax
1264 pop eax
1265 mov edx,eax
1266 shr edx,16
1267 and bx,bx ; ZF = 0
1268 mov si,bx
1269 pop es
1272 .resume: ; We get here if we were only doing part of a lookup
1273 ; This relies on the fact that .success returns bx == si
1274 xchg edx,eax ; Directory length in edx
1275 pop cx ; Old ISOFlags
1276 pop di ; Next filename pointer
1277 mov byte [di-1], '/' ; Restore slash
1278 mov [ISOFlags],cl ; Restore the flags
1279 jz .failure ; Did we fail? If so fail for real!
1280 jmp .look_for_slash ; Otherwise, next level
1283 ; allocate_file: Allocate a file structure
1285 ; If successful:
1286 ; ZF set
1287 ; BX = file pointer
1288 ; In unsuccessful:
1289 ; ZF clear
1291 allocate_file:
1292 TRACER 'a'
1293 push cx
1294 mov bx,Files
1295 mov cx,MAX_OPEN
1296 .check: cmp dword [bx], byte 0
1297 je .found
1298 add bx,open_file_t_size ; ZF = 0
1299 loop .check
1300 ; ZF = 0 if we fell out of the loop
1301 .found: pop cx
1305 ; iso_compare_names:
1306 ; Compare the names DS:SI and DS:DI and report if they are
1307 ; equal from an ISO 9660 perspective. SI is the name from
1308 ; the filesystem; CX indicates its length, and ';' terminates.
1309 ; DI is expected to end with a null.
1311 ; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment
1314 iso_compare_names:
1315 ; First, terminate and canonicalize input filename
1316 push di
1317 mov di,ISOFileName
1318 .canon_loop: jcxz .canon_end
1319 lodsb
1320 dec cx
1321 cmp al,';'
1322 je .canon_end
1323 and al,al
1324 je .canon_end
1325 stosb
1326 cmp di,ISOFileNameEnd-1 ; Guard against buffer overrun
1327 jb .canon_loop
1328 .canon_end:
1329 cmp di,ISOFileName
1330 jbe .canon_done
1331 cmp byte [di-1],'.' ; Remove terminal dots
1332 jne .canon_done
1333 dec di
1334 jmp short .canon_end
1335 .canon_done:
1336 mov [di],byte 0 ; Null-terminate string
1337 pop di
1338 mov si,ISOFileName
1339 .compare:
1340 lodsb
1341 mov ah,[di]
1342 inc di
1343 and ax,ax
1344 jz .success ; End of string for both
1345 and al,al ; Is either one end of string?
1346 jz .failure ; If so, failure
1347 and ah,ah
1348 jz .failure
1349 or ax,2020h ; Convert to lower case
1350 cmp al,ah
1351 je .compare
1352 .failure: and ax,ax ; ZF = 0 (at least one will be nonzero)
1353 .success: ret
1356 ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed
1357 ; to by ES:DI; ends on encountering any whitespace.
1358 ; DI is preserved.
1360 ; This verifies that a filename is < FILENAME_MAX characters,
1361 ; doesn't contain whitespace, zero-pads the output buffer,
1362 ; and removes trailing dots and redundant slashes,
1363 ; so "repe cmpsb" can do a compare, and the
1364 ; path-searching routine gets a bit of an easier job.
1366 mangle_name:
1367 push di
1368 push bx
1369 xor ax,ax
1370 mov cx,FILENAME_MAX-1
1371 mov bx,di
1373 .mn_loop:
1374 lodsb
1375 cmp al,' ' ; If control or space, end
1376 jna .mn_end
1377 cmp al,ah ; Repeated slash?
1378 je .mn_skip
1379 xor ah,ah
1380 cmp al,'/'
1381 jne .mn_ok
1382 mov ah,al
1383 .mn_ok stosb
1384 .mn_skip: loop .mn_loop
1385 .mn_end:
1386 cmp bx,di ; At the beginning of the buffer?
1387 jbe .mn_zero
1388 cmp byte [es:di-1],'.' ; Terminal dot?
1389 je .mn_kill
1390 cmp byte [es:di-1],'/' ; Terminal slash?
1391 jne .mn_zero
1392 .mn_kill: dec di ; If so, remove it
1393 inc cx
1394 jmp short .mn_end
1395 .mn_zero:
1396 inc cx ; At least one null byte
1397 xor ax,ax ; Zero-fill name
1398 rep stosb
1399 pop bx
1400 pop di
1401 ret ; Done
1404 ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled
1405 ; filename to the conventional representation. This is needed
1406 ; for the BOOT_IMAGE= parameter for the kernel.
1408 ; DS:SI -> input mangled file name
1409 ; ES:DI -> output buffer
1411 ; On return, DI points to the first byte after the output name,
1412 ; which is set to a null byte.
1414 unmangle_name: call strcpy
1415 dec di ; Point to final null byte
1419 ; getfssec: Get multiple clusters from a file, given the file pointer.
1421 ; On entry:
1422 ; ES:BX -> Buffer
1423 ; SI -> File pointer
1424 ; CX -> Cluster count
1425 ; On exit:
1426 ; SI -> File pointer (or 0 on EOF)
1427 ; CF = 1 -> Hit EOF
1429 getfssec:
1430 TRACER 'F'
1432 push ds
1433 push cs
1434 pop ds ; DS <- CS
1436 movzx ecx,cx
1437 cmp ecx,[si+file_left]
1438 jna .ok_size
1439 mov ecx,[si+file_left]
1440 .ok_size:
1442 mov bp,cx
1443 push cx
1444 push si
1445 mov eax,[si+file_sector]
1446 TRACER 'l'
1447 call getlinsec
1448 xor ecx,ecx
1449 pop si
1450 pop cx
1452 add [si+file_sector],ecx
1453 sub [si+file_left],ecx
1454 ja .not_eof ; CF = 0
1456 xor ecx,ecx
1457 mov [si+file_sector],ecx ; Mark as unused
1458 xor si,si
1461 .not_eof:
1462 pop ds
1463 TRACER 'f'
1466 ; -----------------------------------------------------------------------------
1467 ; Common modules
1468 ; -----------------------------------------------------------------------------
1470 %include "getc.inc" ; getc et al
1471 %include "conio.inc" ; Console I/O
1472 %include "configinit.inc" ; Initialize configuration
1473 %include "parseconfig.inc" ; High-level config file handling
1474 %include "parsecmd.inc" ; Low-level config file handling
1475 %include "bcopy32.inc" ; 32-bit bcopy
1476 %include "loadhigh.inc" ; Load a file into high memory
1477 %include "font.inc" ; VGA font stuff
1478 %include "graphics.inc" ; VGA graphics
1479 %include "highmem.inc" ; High memory sizing
1480 %include "strcpy.inc" ; strcpy()
1481 %include "rawcon.inc" ; Console I/O w/o using the console functions
1482 %include "adv.inc" ; Auxillary Data Vector
1484 ; -----------------------------------------------------------------------------
1485 ; Begin data section
1486 ; -----------------------------------------------------------------------------
1488 section .data
1490 localboot_msg db 'Booting from local disk...', CR, LF, 0
1491 default_str db 'default', 0
1492 default_len equ ($-default_str)
1493 boot_dir db '/boot' ; /boot/isolinux
1494 isolinux_dir db '/isolinux', 0
1495 config_name db 'isolinux.cfg', 0
1496 err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0
1498 %ifdef DEBUG_MESSAGES
1499 dbg_rootdir_msg db 'Root directory at LBA = ', 0
1500 dbg_isodir_msg db 'isolinux directory at LBA = ', 0
1501 dbg_config_msg db 'About to load config file...', CR, LF, 0
1502 dbg_configok_msg db 'Configuration file opened...', CR, LF, 0
1503 %endif
1505 ; Command line options we'd like to take a look at
1507 ; mem= and vga= are handled as normal 32-bit integer values
1508 initrd_cmd db 'initrd='
1509 initrd_cmd_len equ 7
1512 ; Config file keyword table
1514 %include "keywords.inc"
1517 ; Extensions to search for (in *forward* order).
1519 align 4, db 0
1520 exten_table: db '.cbt' ; COMBOOT (specific)
1521 db '.img' ; Disk image
1522 db '.bin' ; CD boot sector
1523 db '.com' ; COMBOOT (same as DOS)
1524 db '.c32' ; COM32
1525 exten_table_end:
1526 dd 0, 0 ; Need 8 null bytes here
1529 ; Floppy image table
1531 align 4, db 0
1532 img_table_count equ 3
1533 img_table:
1534 dd 1200*1024 ; 1200K floppy
1535 db 1 ; Emulation type
1536 db 80-1 ; Max cylinder
1537 db 15 ; Max sector
1538 db 2-1 ; Max head
1540 dd 1440*1024 ; 1440K floppy
1541 db 2 ; Emulation type
1542 db 80-1 ; Max cylinder
1543 db 18 ; Max sector
1544 db 2-1 ; Max head
1546 dd 2880*1024 ; 2880K floppy
1547 db 3 ; Emulation type
1548 db 80-1 ; Max cylinder
1549 db 36 ; Max sector
1550 db 2-1 ; Max head
1553 ; Misc initialized (data) variables
1557 ; Variables that are uninitialized in SYSLINUX but initialized here
1559 ; **** ISOLINUX:: We may have to make this flexible, based on what the
1560 ; **** BIOS expects our "sector size" to be.
1562 alignb 4, db 0
1563 BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf
1564 BufSafeBytes dw trackbufsize ; = how many bytes?
1565 %ifndef DEPEND
1566 %if ( trackbufsize % SECTOR_SIZE ) != 0
1567 %error trackbufsize must be a multiple of SECTOR_SIZE
1568 %endif
1569 %endif