Magellan Linux

Diff of /trunk/mkinitrd-magellan/isolinux/isolinux.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1132 by niro, Sat Sep 1 22:45:15 2007 UTC revision 1133 by niro, Thu Aug 19 09:50:43 2010 UTC
# Line 1  Line 1 
1  ; -*- fundamental -*- (asm-mode sucks)  ; -*- fundamental -*- (asm-mode sucks)
 ; $Id: isolinux.asm,v 1.1 2007-09-01 22:44:04 niro Exp $  
2  ; ****************************************************************************  ; ****************************************************************************
3  ;  ;
4  ;  isolinux.asm  ;  isolinux.asm
# Line 9  Line 8 
8  ;  available.  It is based on the SYSLINUX boot loader for MS-DOS  ;  available.  It is based on the SYSLINUX boot loader for MS-DOS
9  ;  floppies.  ;  floppies.
10  ;  ;
11  ;   Copyright (C) 1994-2005  H. Peter Anvin  ;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
12    ;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
13  ;  ;
14  ;  This program is free software; you can redistribute it and/or modify  ;  This program is free software; you can redistribute it and/or modify
15  ;  it under the terms of the GNU General Public License as published by  ;  it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20  ; ****************************************************************************  ; ****************************************************************************
21    
22  %define IS_ISOLINUX 1  %define IS_ISOLINUX 1
23  %include "macros.inc"  %include "head.inc"
 %include "config.inc"  
 %include "kernel.inc"  
 %include "bios.inc"  
 %include "tracers.inc"  
 %include "layout.inc"  
24    
25  ;  ;
26  ; Some semi-configurable constants... change on your own risk.  ; Some semi-configurable constants... change on your own risk.
# Line 42  MAX_OPEN equ (1 << MAX_OPEN_LG2) Line 37  MAX_OPEN equ (1 << MAX_OPEN_LG2)
37  SECTOR_SHIFT equ 11 ; 2048 bytes/sector (El Torito requirement)  SECTOR_SHIFT equ 11 ; 2048 bytes/sector (El Torito requirement)
38  SECTOR_SIZE equ (1 << SECTOR_SHIFT)  SECTOR_SIZE equ (1 << SECTOR_SHIFT)
39    
40  ;  ROOT_DIR_WORD equ 0x002F
 ; This is what we need to do when idle  
 ;  
 %macro RESET_IDLE 0  
  ; Nothing  
 %endmacro  
 %macro DO_IDLE 0  
  ; Nothing  
 %endmacro  
41    
42  ;  ;
43  ; The following structure is used for "virtual kernels"; i.e. LILO-style  ; The following structure is used for "virtual kernels"; i.e. LILO-style
44  ; option labels.  The options we permit here are `kernel' and `append  ; option labels.  The options we permit here are `kernel' and `append
45  ; Since there is no room in the bottom 64K for all of these, we  ; Since there is no room in the bottom 64K for all of these, we
46  ; stick them at vk_seg:0000 and copy them down before we need them.  ; stick them in high memory and copy them down before we need them.
47  ;  ;
48   struc vkernel   struc vkernel
49  vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**  vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
50  vk_rname: resb FILENAME_MAX ; Real name  vk_rname: resb FILENAME_MAX ; Real name
51  vk_appendlen: resw 1  vk_appendlen: resw 1
52    vk_type: resb 1 ; Type of file
53   alignb 4   alignb 4
54  vk_append: resb max_cmd_len+1 ; Command line  vk_append: resb max_cmd_len+1 ; Command line
55   alignb 4   alignb 4
# Line 69  vk_end: equ $ ; Should be <= vk_size Line 57  vk_end: equ $ ; Should be <= vk_size
57   endstruc   endstruc
58    
59  ;  ;
 ; Segment assignments in the bottom 640K  
 ; 0000h - main code/data segment (and BIOS segment)  
 ;  
 real_mode_seg equ 3000h  
 vk_seg          equ 2000h ; Virtual kernels  
 xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem  
 comboot_seg equ real_mode_seg ; COMBOOT image loading zone  
   
 ;  
60  ; File structure.  This holds the information for each currently open file.  ; File structure.  This holds the information for each currently open file.
61  ;  ;
62   struc open_file_t   struc open_file_t
63  file_sector resd 1 ; Sector pointer (0 = structure free)  file_sector resd 1 ; Sector pointer (0 = structure free)
64    file_bytesleft resd 1 ; Number of bytes left
65  file_left resd 1 ; Number of sectors left  file_left resd 1 ; Number of sectors left
66     resd 1 ; Unused
67   endstruc   endstruc
68    
69  %ifndef DEPEND  %ifndef DEPEND
# Line 107  dir_clust resd 1 ; Length in clusters Line 88  dir_clust resd 1 ; Length in clusters
88   section .earlybss   section .earlybss
89  trackbufsize equ 8192  trackbufsize equ 8192
90  trackbuf resb trackbufsize ; Track buffer goes here  trackbuf resb trackbufsize ; Track buffer goes here
91  getcbuf resb trackbufsize  ; ends at 2800h
 ; ends at 4800h  
92    
93   section .bss   ; Some of these are touched before the whole image
94     ; is loaded.  DO NOT move this to .uibss.
95     section .bss2
96   alignb 4   alignb 4
97  ISOFileName resb 64 ; ISO filename canonicalization buffer  ISOFileName resb 64 ; ISO filename canonicalization buffer
98  ISOFileNameEnd equ $  ISOFileNameEnd equ $
99  CurDir resb dir_t_size ; Current directory  CurrentDir resb dir_t_size ; Current directory
100  RootDir resb dir_t_size ; Root directory  RootDir resb dir_t_size ; Root directory
101  FirstSecSum resd 1 ; Checksum of bytes 64-2048  FirstSecSum resd 1 ; Checksum of bytes 64-2048
102  ImageDwords resd 1 ; isolinux.bin size, dwords  ImageDwords resd 1 ; isolinux.bin size, dwords
103  InitStack resd 1 ; Initial stack pointer (SS:SP)  InitStack resd 1 ; Initial stack pointer (SS:SP)
104  DiskSys resw 1 ; Last INT 13h call  DiskSys resw 1 ; Last INT 13h call
105  ImageSectors resw 1 ; isolinux.bin size, sectors  ImageSectors resw 1 ; isolinux.bin size, sectors
106    ; These following two are accessed as a single dword...
107    GetlinsecPtr resw 1 ; The sector-read pointer
108    BIOSName resw 1 ; Display string for BIOS type
109    %define HAVE_BIOSNAME 1
110    BIOSType resw 1
111  DiskError resb 1 ; Error code for disk I/O  DiskError resb 1 ; Error code for disk I/O
112  DriveNo resb 1 ; CD-ROM BIOS drive number  DriveNumber resb 1 ; CD-ROM BIOS drive number
113  ISOFlags resb 1 ; Flags for ISO directory search  ISOFlags resb 1 ; Flags for ISO directory search
114  RetryCount      resb 1 ; Used for disk access retries  RetryCount      resb 1 ; Used for disk access retries
115    
116  _spec_start equ $   alignb 8
117    bsHidden resq 1 ; Used in hybrid mode
118    bsSecPerTrack resw 1 ; Used in hybrid mode
119    bsHeads resw 1 ; Used in hybrid mode
120    
121    
122  ;  ;
123  ; El Torito spec packet  ; El Torito spec packet
124  ;  ;
125    
126   alignb 8   alignb 8
127    _spec_start equ $
128  spec_packet: resb 1 ; Size of packet  spec_packet: resb 1 ; Size of packet
129  sp_media: resb 1 ; Media type  sp_media: resb 1 ; Media type
130  sp_drive: resb 1 ; Drive number  sp_drive: resb 1 ; Drive number
# Line 142  sp_devspec: resw 1 ; IDE/SCSI informa Line 134  sp_devspec: resw 1 ; IDE/SCSI informa
134  sp_buffer: resw 1 ; User-provided buffer  sp_buffer: resw 1 ; User-provided buffer
135  sp_loadseg: resw 1 ; Load segment  sp_loadseg: resw 1 ; Load segment
136  sp_sectors: resw 1 ; Sector count  sp_sectors: resw 1 ; Sector count
137  sp_chs: resb 3   ; Simulated CHS geometry  sp_chs: resb 3 ; Simulated CHS geometry
138  sp_dummy: resb 1 ; Scratch, safe to overwrite  sp_dummy: resb 1 ; Scratch, safe to overwrite
139    
140  ;  ;
# Line 201  _spec_len equ _spec_end - _spec_start Line 193  _spec_len equ _spec_end - _spec_start
193   alignb open_file_t_size   alignb open_file_t_size
194  Files resb MAX_OPEN*open_file_t_size  Files resb MAX_OPEN*open_file_t_size
195    
 ;  
 ; Constants for the xfer_buf_seg  
 ;  
 ; The xfer_buf_seg is also used to store message file buffers.  We  
 ; need two trackbuffers (text and graphics), plus a work buffer  
 ; for the graphics decompressor.  
 ;  
 xbs_textbuf equ 0 ; Also hard-coded, do not change  
 xbs_vgabuf equ trackbufsize  
 xbs_vgatmpbuf equ 2*trackbufsize  
   
196   section .text   section .text
197  ;;  ;;
198  ;; Primary entry point.  Because BIOSes are buggy, we only load the first  ;; Primary entry point.  Because BIOSes are buggy, we only load the first
199  ;; CD-ROM sector (2K) of the file, so the number one priority is actually  ;; CD-ROM sector (2K) of the file, so the number one priority is actually
200  ;; loading the rest.  ;; loading the rest.
201  ;;  ;;
202  StackBuf equ $  StackBuf equ STACK_TOP-44 ; 44 bytes needed for
203     ; the bootsector chainloading
204     ; code!
205    OrigESDI equ StackBuf-4          ; The high dword on the stack
206    
207  bootsec equ $  bootsec equ $
208    
# Line 236  bi_file: dd 0 ; LBA of boot file Line 220  bi_file: dd 0 ; LBA of boot file
220  bi_length: dd 0xdeadbeef ; Length of boot file  bi_length: dd 0xdeadbeef ; Length of boot file
221  bi_csum: dd 0xdeadbeef ; Checksum of boot file  bi_csum: dd 0xdeadbeef ; Checksum of boot file
222  bi_reserved: times 10 dd 0xdeadbeef ; Reserved  bi_reserved: times 10 dd 0xdeadbeef ; Reserved
223    bi_end:
224    
225  _start1: mov [cs:InitStack],sp ; Save initial stack pointer   ; Custom entry point for the hybrid-mode disk.
226     ; The following values will have been pushed onto the
227     ; entry stack:
228     ; - partition offset (qword)
229     ; - ES
230     ; - DI
231     ; - DX (including drive number)
232     ; - CBIOS Heads
233     ; - CBIOS Sectors
234     ; - EBIOS flag
235     ;       (top of stack)
236     ;
237     ; If we had an old isohybrid, the partition offset will
238     ; be missing; we can check for that with sp >= 0x7c00.
239     ; Serious hack alert.
240    %ifndef DEBUG_MESSAGES
241    _hybrid_signature:
242           dd 0x7078c0fb ; An arbitrary number...
243    
244    _start_hybrid:
245     pop cx ; EBIOS flag
246     pop word [cs:bsSecPerTrack]
247     pop word [cs:bsHeads]
248     pop dx
249     pop di
250     pop es
251     xor eax,eax
252     xor ebx,ebx
253     cmp sp,7C00h
254     jae .nooffset
255     pop eax
256     pop ebx
257    .nooffset:
258     mov [cs:bsHidden],eax
259     mov [cs:bsHidden+4],ebx
260    
261     mov si,bios_cbios
262     jcxz _start_common
263     mov si,bios_ebios
264     jmp _start_common
265    %endif
266    
267    _start1:
268     mov si,bios_cdrom
269    _start_common:
270     mov [cs:InitStack],sp ; Save initial stack pointer
271   mov [cs:InitStack+2],ss   mov [cs:InitStack+2],ss
272   xor ax,ax   xor ax,ax
273   mov ss,ax   mov ss,ax
274   mov sp,StackBuf ; Set up stack   mov sp,StackBuf ; Set up stack
275     push es ; Save initial ES:DI -> $PnP pointer
276     push di
277   mov ds,ax   mov ds,ax
278   mov es,ax   mov es,ax
279   mov fs,ax   mov fs,ax
280   mov gs,ax   mov gs,ax
281   sti   sti
   
282   cld   cld
283    
284     mov [BIOSType],si
285     mov eax,[si]
286     mov [GetlinsecPtr],eax
287    
288   ; Show signs of life   ; Show signs of life
289   mov si,syslinux_banner   mov si,syslinux_banner
290   call writestr   call writestr_early
291  %ifdef DEBUG_MESSAGES  %ifdef DEBUG_MESSAGES
292   mov si,copyright_str   mov si,copyright_str
293   call writestr  %else
294     mov si,[BIOSName]
295  %endif  %endif
296     call writestr_early
297    
298   ;   ;
299   ; Before modifying any memory, get the checksum of bytes   ; Before modifying any memory, get the checksum of bytes
300   ; 64-2048   ; 64-2048
301   ;   ;
302  initial_csum: xor edi,edi  initial_csum: xor edi,edi
303   mov si,_start1   mov si,bi_end
304   mov cx,(SECTOR_SIZE-64) >> 2   mov cx,(SECTOR_SIZE-64) >> 2
305  .loop: lodsd  .loop: lodsd
306   add edi,eax   add edi,eax
307   loop .loop   loop .loop
308   mov [FirstSecSum],edi   mov [FirstSecSum],edi
309    
310   mov [DriveNo],dl   mov [DriveNumber],dl
311  %ifdef DEBUG_MESSAGES  %ifdef DEBUG_MESSAGES
312   mov si,startup_msg   mov si,startup_msg
313   call writemsg   call writemsg
# Line 294  initial_csum: xor edi,edi Line 332  initial_csum: xor edi,edi
332   ; Other nonzero fields   ; Other nonzero fields
333   inc word [dsp_sectors]   inc word [dsp_sectors]
334    
335     ; Are we just pretending to be a CD-ROM?
336     cmp word [BIOSType],bios_cdrom
337     jne found_drive ; If so, no spec packet...
338    
339   ; Now figure out what we're actually doing   ; Now figure out what we're actually doing
340   ; Note: use passed-in DL value rather than 7Fh because   ; Note: use passed-in DL value rather than 7Fh because
341   ; at least some BIOSes will get the wrong value otherwise   ; at least some BIOSes will get the wrong value otherwise
342   mov ax,4B01h ; Get disk emulation status   mov ax,4B01h ; Get disk emulation status
343   mov dl,[DriveNo]   mov dl,[DriveNumber]
344   mov si,spec_packet   mov si,spec_packet
345   int 13h   call int13
346   jc award_hack ; changed for BrokenAwardHack   jc award_hack ; changed for BrokenAwardHack
347   mov dl,[DriveNo]   mov dl,[DriveNumber]
348   cmp [sp_drive],dl ; Should contain the drive number   cmp [sp_drive],dl ; Should contain the drive number
349   jne spec_query_failed   jne spec_query_failed
350    
# Line 330  found_drive: Line 372  found_drive:
372   mov si,noinfotable_msg   mov si,noinfotable_msg
373   call writemsg   call writemsg
374  %endif  %endif
375    
376   ; No such luck.  See if the the spec packet contained one.   ; No such luck.  See if the spec packet contained one.
377   mov eax,[sp_lba]   mov eax,[sp_lba]
378   and eax,eax   and eax,eax
379   jz set_file ; Good enough   jz set_file ; Good enough
# Line 340  found_drive: Line 382  found_drive:
382   mov si,noinfoinspec_msg   mov si,noinfoinspec_msg
383   call writemsg   call writemsg
384  %endif  %endif
385    
386   ; No such luck.  Get the Boot Record Volume, assuming single   ; No such luck.  Get the Boot Record Volume, assuming single
387   ; session disk, and that we're the first entry in the chain   ; session disk, and that we're the first entry in the chain.
388   mov eax,17 ; Assumed address of BRV   mov eax,17 ; Assumed address of BRV
389   mov bx,trackbuf   mov bx,trackbuf
390   call getonesec   call getonesec
# Line 354  found_drive: Line 396  found_drive:
396   mov eax,[trackbuf+28h] ; First boot entry   mov eax,[trackbuf+28h] ; First boot entry
397   ; And hope and pray this is us...   ; And hope and pray this is us...
398    
399   ; Some BIOSes apparently have limitations on the size   ; Some BIOSes apparently have limitations on the size
400   ; that may be loaded (despite the El Torito spec being very   ; that may be loaded (despite the El Torito spec being very
401   ; clear on the fact that it must all be loaded.)  Therefore,   ; clear on the fact that it must all be loaded.)  Therefore,
402   ; we load it ourselves, and *bleep* the BIOS.   ; we load it ourselves, and *bleep* the BIOS.
# Line 365  set_file: Line 407  set_file:
407  found_file:  found_file:
408   ; Set up boot file sizes   ; Set up boot file sizes
409   mov eax,[bi_length]   mov eax,[bi_length]
410   sub eax,SECTOR_SIZE-3   sub eax,SECTOR_SIZE-3 ; ... minus sector loaded
411   shr eax,2 ; bytes->dwords   shr eax,2 ; bytes->dwords
412   mov [ImageDwords],eax ; boot file dwords   mov [ImageDwords],eax ; boot file dwords
413   add eax,(2047 >> 2)   add eax,(2047 >> 2)
# Line 442  integrity_ok: Line 484  integrity_ok:
484  ;; Start of BrokenAwardHack --- 10-nov-2002           Knut_Petersen@t-online.de  ;; Start of BrokenAwardHack --- 10-nov-2002           Knut_Petersen@t-online.de
485  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
486  ;;  ;;
487  ;; There is a problem with certain versions of the AWARD BIOS ...  ;; There is a problem with certain versions of the AWARD BIOS ...
488  ;; the boot sector will be loaded and executed correctly, but, because the  ;; the boot sector will be loaded and executed correctly, but, because the
489  ;; int 13 vector points to the wrong code in the BIOS, every attempt to  ;; int 13 vector points to the wrong code in the BIOS, every attempt to
490  ;; load the spec packet will fail. We scan for the equivalent of  ;; load the spec packet will fail. We scan for the equivalent of
# Line 459  integrity_ok: Line 501  integrity_ok:
501  ;; for anybody to change it now or in the future. There are no opcodes  ;; for anybody to change it now or in the future. There are no opcodes
502  ;; that use encodings relativ to IP, so scanning is easy. If we find the  ;; that use encodings relativ to IP, so scanning is easy. If we find the
503  ;; code above in the BIOS code we can be pretty sure to run on a machine  ;; code above in the BIOS code we can be pretty sure to run on a machine
504  ;; with an broken AWARD BIOS ...  ;; with an broken AWARD BIOS ...
505  ;;  ;;
506  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
507       ;;       ;;
# Line 478  award_oldint13 dd 0     ;; Line 520  award_oldint13 dd 0     ;;
520  award_string db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah    ;;  award_string db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah    ;;
521       ;;       ;;
522   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
523  award_hack: mov si,spec_err_msg ; Moved to this place from  award_hack: mov si,spec_err_msg ; Moved to this place from
524   call writemsg ; spec_query_faild   call writemsg ; spec_query_faild
525   ;   ;
526  %ifdef DEBUG_MESSAGES ;  %ifdef DEBUG_MESSAGES ;
527   ;   ;
# Line 494  award_hack: mov si,spec_err_msg ; Move Line 536  award_hack: mov si,spec_err_msg ; Move
536  %ifdef DEBUG_MESSAGES ;  %ifdef DEBUG_MESSAGES ;
537   ;   ;
538   call writehex8 ;   call writehex8 ;
539   mov si,award_not_crlf ;   mov si,award_not_crlf ;
540   call writestr ;   call writestr_early ;
541  %endif ;  %endif ;
542   push es ; save ES   push es ; save ES
543   mov ax,0f000h ; ES = BIOS Seg   mov ax,0f000h ; ES = BIOS Seg
544   mov es,ax ;   mov es,ax ;
545       cld ;   cld ;
546   xor di,di ; start at ES:DI = f000:0   xor di,di ; start at ES:DI = f000:0
547  award_loop: push di ; save DI  award_loop: push di ; save DI
548   mov si,award_string ; scan for award_string   mov si,award_string ; scan for award_string
549   mov cx,7 ; length of award_string = 7dw   mov cx,7 ; length of award_string = 7dw
550   repz cmpsw ; compare   repz cmpsw ; compare
551   pop di ; restore DI   pop di ; restore DI
552   jcxz award_found ; jmp if found   jcxz award_found ; jmp if found
553   inc di ; not found, inc di   inc di ; not found, inc di
554   jno award_loop ;   jno award_loop ;
555   ;   ;
556  award_failed: pop es ; No, not this way :-((  award_failed: pop es ; No, not this way :-((
557  award_fail2: ;  award_fail2: ;
# Line 535  award_found: mov eax,[es:di+0eh] ; load Line 577  award_found: mov eax,[es:di+0eh] ; load
577   ;   ;
578  %ifdef DEBUG_MESSAGES ;  %ifdef DEBUG_MESSAGES ;
579   ;   ;
580   push eax ; display message and   push eax ; display message and
581   mov si,award_not_new ; new vector address   mov si,award_not_new ; new vector address
582   call writemsg ;   call writemsg ;
583   pop eax ;   pop eax ;
584   call writehex8 ;   call writehex8 ;
585   mov si,award_not_crlf ;   mov si,award_not_crlf ;
586   call writestr ;   call writestr_early ;
587  %endif ;  %endif ;
588   mov ax,4B01h ; try to read the spec packet   mov ax,4B01h ; try to read the spec packet
589   mov dl,[DriveNo] ; now ... it should not fail   mov dl,[DriveNumber] ; now ... it should not fail
590   mov si,spec_packet ; any longer   mov si,spec_packet ; any longer
591   int 13h ;   int 13h ;
592   jc award_fail2 ;   jc award_fail2 ;
593   ;   ;
594  %ifdef DEBUG_MESSAGES ;  %ifdef DEBUG_MESSAGES ;
# Line 572  spec_query_failed: Line 614  spec_query_failed:
614  .test_loop: pusha  .test_loop: pusha
615   mov ax,4B01h   mov ax,4B01h
616   mov si,spec_packet   mov si,spec_packet
617   mov byte [si],13 ; Size of buffer   mov byte [si],13h ; Size of buffer
618   int 13h   call int13
619   popa   popa
620   jc .still_broken   jc .still_broken
621    
# Line 589  spec_query_failed: Line 631  spec_query_failed:
631   ; Okay, good enough...   ; Okay, good enough...
632   mov si,alright_msg   mov si,alright_msg
633   call writemsg   call writemsg
634   mov [DriveNo],dl  .found_drive0: mov [DriveNumber],dl
635  .found_drive: jmp found_drive  .found_drive: jmp found_drive
636    
637   ; Award BIOS 4.51 apparently passes garbage in sp_drive,   ; Award BIOS 4.51 apparently passes garbage in sp_drive,
638   ; but if this was the drive number originally passed in   ; but if this was the drive number originally passed in
639   ; DL then consider it "good enough"   ; DL then consider it "good enough"
640  .maybe_broken:  .maybe_broken:
641   cmp byte [DriveNo],dl   mov al,[DriveNumber]
642     cmp al,dl
643   je .found_drive   je .found_drive
644    
645     ; Intel Classic R+ computer with Adaptec 1542CP BIOS 1.02
646     ; passes garbage in sp_drive, and the drive number originally
647     ; passed in DL does not have 80h bit set.
648     or al,80h
649     cmp al,dl
650     je .found_drive0
651    
652  .still_broken: dec dx  .still_broken: dec dx
653   cmp dl, 80h   cmp dl, 80h
654   jnb .test_loop   jnb .test_loop
# Line 608  spec_query_failed: Line 658  spec_query_failed:
658   ; 4B01h, so we can't query a spec packet no matter   ; 4B01h, so we can't query a spec packet no matter
659   ; what.  If we got a drive number in DL, then try to   ; what.  If we got a drive number in DL, then try to
660   ; use it, and if it works, then well...   ; use it, and if it works, then well...
661   mov dl,[DriveNo]   mov dl,[DriveNumber]
662   cmp dl,81h ; Should be 81-FF at least   cmp dl,81h ; Should be 81-FF at least
663   jb fatal_error ; If not, it's hopeless   jb fatal_error ; If not, it's hopeless
664    
# Line 634  fatal_error: Line 684  fatal_error:
684  writemsg: push ax  writemsg: push ax
685   push si   push si
686   mov si,isolinux_str   mov si,isolinux_str
687   call writestr   call writestr_early
688   pop si   pop si
689   call writestr   call writestr_early
690   pop ax   pop ax
691   ret   ret
692    
693  ;  ;
# Line 660  writechr_simple: Line 710  writechr_simple:
710   ret   ret
711    
712  ;  ;
713    ; int13: save all the segment registers and call INT 13h.
714    ; Some CD-ROM BIOSes have been found to corrupt segment registers
715    ; and/or disable interrupts.
716    ;
717    int13:
718     pushf
719     push bp
720     push ds
721     push es
722     push fs
723     push gs
724     int 13h
725     mov bp,sp
726     setc [bp+10] ; Propagate CF to the caller
727     pop gs
728     pop fs
729     pop es
730     pop ds
731     pop bp
732     popf
733     ret
734    
735    ;
736  ; Get one sector.  Convenience entry point.  ; Get one sector.  Convenience entry point.
737  ;  ;
738  getonesec:  getonesec:
# Line 669  getonesec: Line 742  getonesec:
742  ;  ;
743  ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.  ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
744  ;  ;
 ; Note that we can't always do this as a single request, because at least  
 ; Phoenix BIOSes has a 127-sector limit.  To be on the safe side, stick  
 ; to 32 sectors (64K) per request.  
 ;  
745  ; Input:  ; Input:
746  ; EAX - Linear sector number  ; EAX - Linear sector number
747  ; ES:BX - Target buffer  ; ES:BX - Target buffer
748  ; BP - Sector count  ; BP - Sector count
749  ;  ;
750  getlinsec:  getlinsec: jmp word [cs:GetlinsecPtr]
751    
752    %ifndef DEBUG_MESSAGES
753    
754    ;
755    ; First, the variants that we use when actually loading off a disk
756    ; (hybrid mode.)  These are adapted versions of the equivalent routines
757    ; in ldlinux.asm.
758    ;
759    
760    ;
761    ; getlinsec_ebios:
762    ;
763    ; getlinsec implementation for floppy/HDD EBIOS (EDD)
764    ;
765    getlinsec_ebios:
766     xor edx,edx
767     shld edx,eax,2
768     shl eax,2 ; Convert to HDD sectors
769     add eax,[bsHidden]
770     adc edx,[bsHidden+4]
771     shl bp,2
772    
773    .loop:
774                    push bp                         ; Sectors left
775    .retry2:
776     call maxtrans ; Enforce maximum transfer size
777     movzx edi,bp ; Sectors we are about to read
778     mov cx,retry_count
779    .retry:
780    
781     ; Form DAPA on stack
782     push edx
783     push eax
784     push es
785     push bx
786     push di
787     push word 16
788     mov si,sp
789     pushad
790                    mov dl,[DriveNumber]
791     push ds
792     push ss
793     pop ds ; DS <- SS
794     mov ah,42h ; Extended Read
795     call int13
796     pop ds
797     popad
798     lea sp,[si+16] ; Remove DAPA
799     jc .error
800     pop bp
801     add eax,edi ; Advance sector pointer
802     adc edx,0
803     sub bp,di ; Sectors left
804                    shl di,9 ; 512-byte sectors
805                    add bx,di ; Advance buffer pointer
806                    and bp,bp
807                    jnz .loop
808    
809                    ret
810    
811    .error:
812     ; Some systems seem to get "stuck" in an error state when
813     ; using EBIOS.  Doesn't happen when using CBIOS, which is
814     ; good, since some other systems get timeout failures
815     ; waiting for the floppy disk to spin up.
816    
817     pushad ; Try resetting the device
818     xor ax,ax
819     mov dl,[DriveNumber]
820     call int13
821     popad
822     loop .retry ; CX-- and jump if not zero
823    
824     ;shr word [MaxTransfer],1 ; Reduce the transfer size
825     ;jnz .retry2
826    
827     ; Total failure.  Try falling back to CBIOS.
828     mov word [GetlinsecPtr], getlinsec_cbios
829     ;mov byte [MaxTransfer],63 ; Max possibe CBIOS transfer
830    
831     pop bp
832     jmp getlinsec_cbios.loop
833    
834    ;
835    ; getlinsec_cbios:
836    ;
837    ; getlinsec implementation for legacy CBIOS
838    ;
839    getlinsec_cbios:
840     xor edx,edx
841     shl eax,2 ; Convert to HDD sectors
842     add eax,[bsHidden]
843     shl bp,2
844    
845    .loop:
846     push edx
847     push eax
848     push bp
849     push bx
850    
851     movzx esi,word [bsSecPerTrack]
852     movzx edi,word [bsHeads]
853     ;
854     ; Dividing by sectors to get (track,sector): we may have
855     ; up to 2^18 tracks, so we need to use 32-bit arithmetric.
856     ;
857     div esi
858     xor cx,cx
859     xchg cx,dx ; CX <- sector index (0-based)
860     ; EDX <- 0
861     ; eax = track #
862     div edi ; Convert track to head/cyl
863    
864     ; We should test this, but it doesn't fit...
865     ; cmp eax,1023
866     ; ja .error
867    
868     ;
869     ; Now we have AX = cyl, DX = head, CX = sector (0-based),
870     ; BP = sectors to transfer, SI = bsSecPerTrack,
871     ; ES:BX = data target
872     ;
873    
874     call maxtrans ; Enforce maximum transfer size
875    
876     ; Must not cross track boundaries, so BP <= SI-CX
877     sub si,cx
878     cmp bp,si
879     jna .bp_ok
880     mov bp,si
881    .bp_ok:
882    
883     shl ah,6 ; Because IBM was STOOPID
884     ; and thought 8 bits were enough
885     ; then thought 10 bits were enough...
886     inc cx ; Sector numbers are 1-based, sigh
887     or cl,ah
888     mov ch,al
889     mov dh,dl
890     mov dl,[DriveNumber]
891     xchg ax,bp ; Sector to transfer count
892     mov ah,02h ; Read sectors
893     mov bp,retry_count
894    .retry:
895     pushad
896     call int13
897     popad
898     jc .error
899    .resume:
900     movzx ecx,al ; ECX <- sectors transferred
901     shl ax,9 ; Convert sectors in AL to bytes in AX
902     pop bx
903     add bx,ax
904     pop bp
905     pop eax
906     pop edx
907     add eax,ecx
908     sub bp,cx
909     jnz .loop
910     ret
911    
912    .error:
913     dec bp
914     jnz .retry
915    
916     xchg ax,bp ; Sectors transferred <- 0
917     shr word [MaxTransfer],1
918     jnz .resume
919     jmp disk_error
920    
921    ;
922    ; Truncate BP to MaxTransfer
923    ;
924    maxtrans:
925     cmp bp,[MaxTransfer]
926     jna .ok
927     mov bp,[MaxTransfer]
928    .ok: ret
929    
930    %endif
931    
932    ;
933    ; This is the variant we use for real CD-ROMs:
934    ; LBA, 2K sectors, some special error handling.
935    ;
936    getlinsec_cdrom:
937   mov si,dapa ; Load up the DAPA   mov si,dapa ; Load up the DAPA
938   mov [si+4],bx   mov [si+4],bx
939   mov bx,es   mov [si+6],es
  mov [si+6],bx  
940   mov [si+8],eax   mov [si+8],eax
941  .loop:  .loop:
942   push bp ; Sectors left   push bp ; Sectors left
943   cmp bp,[MaxTransfer]   cmp bp,[MaxTransferCD]
944   jbe .bp_ok   jbe .bp_ok
945   mov bp,[MaxTransfer]   mov bp,[MaxTransferCD]
946  .bp_ok:  .bp_ok:
947   mov [si+2],bp   mov [si+2],bp
948   push si   push si
949   mov dl,[DriveNo]   mov dl,[DriveNumber]
950   mov ah,42h ; Extended Read   mov ah,42h ; Extended Read
951   call xint13   call xint13
952   pop si   pop si
# Line 710  getlinsec: Line 964  getlinsec:
964   ; INT 13h with retry   ; INT 13h with retry
965  xint13: mov byte [RetryCount],retry_count  xint13: mov byte [RetryCount],retry_count
966  .try: pushad  .try: pushad
967   int 13h   call int13
968   jc .error   jc .error
969   add sp,byte 8*4 ; Clean up stack   add sp,byte 8*4 ; Clean up stack
970   ret   ret
# Line 733  xint13: mov byte [RetryCount],retry_cou Line 987  xint13: mov byte [RetryCount],retry_cou
987   shr ah,1 ; Otherwise, try to reduce   shr ah,1 ; Otherwise, try to reduce
988   adc ah,0 ; the max transfer size, but not to 0   adc ah,0 ; the max transfer size, but not to 0
989  .setsize:  .setsize:
990   mov [MaxTransfer],ah   mov [MaxTransferCD],ah
991   mov [dapa+2],ah   mov [dapa+2],ah
992  .again:  .again:
993   pop ax   pop ax
# Line 744  xint13: mov byte [RetryCount],retry_cou Line 998  xint13: mov byte [RetryCount],retry_cou
998   mov al,[DiskError]   mov al,[DiskError]
999   call writehex2   call writehex2
1000   mov si,oncall_str   mov si,oncall_str
1001   call writestr   call writestr_early
1002   mov ax,[DiskSys]   mov ax,[DiskSys]
1003   call writehex4   call writehex4
1004   mov si,ondrive_str   mov si,ondrive_str
1005   call writestr   call writestr_early
1006   mov al,dl   mov al,dl
1007   call writehex2   call writehex2
1008   call crlf   call crlf
# Line 758  xint13: mov byte [RetryCount],retry_cou Line 1012  xint13: mov byte [RetryCount],retry_cou
1012  ; kaboom: write a message and bail out.  Wait for a user keypress,  ; kaboom: write a message and bail out.  Wait for a user keypress,
1013  ;  then do a hard reboot.  ;  then do a hard reboot.
1014  ;  ;
1015    disk_error:
1016  kaboom:  kaboom:
1017   lss sp,[cs:StackPtr]   RESET_STACK_AND_SEGS AX
  mov ax,cs  
  mov ds,ax  
  mov es,ax  
  mov fs,ax  
  mov gs,ax  
  sti  
1018   mov si,err_bootfailed   mov si,err_bootfailed
1019   call cwritestr   call writestr
1020   call getchar   call getchar
1021   cli   cli
1022   mov word [BIOS_magic],0 ; Cold reboot   mov word [BIOS_magic],0 ; Cold reboot
# Line 778  kaboom: Line 1027  kaboom:
1027  ; -----------------------------------------------------------------------------  ; -----------------------------------------------------------------------------
1028    
1029  %include "writestr.inc" ; String output  %include "writestr.inc" ; String output
1030  writestr equ cwritestr  writestr_early equ writestr
1031  %include "writehex.inc" ; Hexadecimal output  %include "writehex.inc" ; Hexadecimal output
1032    
1033  ; -----------------------------------------------------------------------------  ; -----------------------------------------------------------------------------
1034  ; Data that needs to be in the first sector  ; Data that needs to be in the first sector
1035  ; -----------------------------------------------------------------------------  ; -----------------------------------------------------------------------------
1036    
1037  syslinux_banner db CR, LF, 'ISOLINUX ', version_str, ' ', date, ' ', 0  syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
1038  copyright_str   db ' Copyright (C) 1994-', year, ' H. Peter Anvin'  copyright_str   db ' Copyright (C) 1994-'
1039   db CR, LF, 0   asciidec YEAR
1040     db ' H. Peter Anvin et al', CR, LF, 0
1041  isolinux_str db 'isolinux: ', 0  isolinux_str db 'isolinux: ', 0
1042  %ifdef DEBUG_MESSAGES  %ifdef DEBUG_MESSAGES
1043  startup_msg: db 'Starting up, DL = ', 0  startup_msg: db 'Starting up, DL = ', 0
1044  spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0  spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
1045  secsize_msg: db 'Sector size appears to be ', 0  secsize_msg: db 'Sector size ', 0
1046  offset_msg: db 'Loading main image from LBA = ', 0  offset_msg: db 'Main image LBA = ', 0
1047  size_msg: db 'Sectors to load = ', 0  size_msg: db 'Sectors to load = ', 0
1048  loaded_msg: db 'Loaded boot image, verifying...', CR, LF, 0  loaded_msg: db 'Loaded boot image, verifying...', CR, LF, 0
1049  verify_msg: db 'Image checksum verified.', CR, LF, 0  verify_msg: db 'Image checksum verified.', CR, LF, 0
# Line 803  noinfotable_msg db 'No boot info table, Line 1053  noinfotable_msg db 'No boot info table,
1053  noinfoinspec_msg db 'Spec packet missing LBA information, trying to wing it...', CR, LF, 0  noinfoinspec_msg db 'Spec packet missing LBA information, trying to wing it...', CR, LF, 0
1054  spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0  spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0
1055  maybe_msg: db 'Found something at drive = ', 0  maybe_msg: db 'Found something at drive = ', 0
1056  alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0  alright_msg: db 'Looks reasonable, continuing...', CR, LF, 0
1057  nospec_msg db 'Extremely broken BIOS detected, last ditch attempt with drive = ', 0  nospec_msg db 'Extremely broken BIOS detected, last attempt with drive = ', 0
1058  nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF  nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF
1059  trysbm_msg db 'See http://syslinux.zytor.com/sbm for more information.', CR, LF, 0  trysbm_msg db 'See http://syslinux.zytor.com/sbm for more information.', CR, LF, 0
1060  diskerr_msg: db 'Disk error ', 0  diskerr_msg: db 'Disk error ', 0
# Line 817  bailmsg equ err_bootfailed Line 1067  bailmsg equ err_bootfailed
1067  crlf_msg db CR, LF  crlf_msg db CR, LF
1068  null_msg db 0  null_msg db 0
1069    
1070   alignb 4, db 0  bios_cdrom_str db 'ETCD', 0
1071  StackPtr dw StackBuf, 0 ; SS:SP for stack reset  %ifndef DEBUG_MESSAGES
1072  MaxTransfer dw 32 ; Max sectors per transfer  bios_cbios_str db 'CHDD', 0
1073    bios_ebios_str db 'EHDD' ,0
1074    %endif
1075    
1076     alignz 4
1077    bios_cdrom: dw getlinsec_cdrom, bios_cdrom_str
1078    %ifndef DEBUG_MESSAGES
1079    bios_cbios: dw getlinsec_cbios, bios_cbios_str
1080    bios_ebios: dw getlinsec_ebios, bios_ebios_str
1081    %endif
1082    
1083    ; Maximum transfer size
1084    MaxTransfer dw 127 ; Hard disk modes
1085    MaxTransferCD dw 32 ; CD mode
1086    
1087  rl_checkpt equ $ ; Must be <= 800h  rl_checkpt equ $ ; Must be <= 800h
1088    
1089  rl_checkpt_off equ ($-$$)   ; This pads to the end of sector 0 and errors out on
1090  ;%ifndef DEPEND   ; overflow.
1091  ;%if rl_checkpt_off > 0x800   times 2048-($-$$) db 0
 ;%error "Sector 0 overflow"  
 ;%endif  
 ;%endif  
1092    
1093  ; ----------------------------------------------------------------------------  ; ----------------------------------------------------------------------------
1094  ;  End of code and data that have to be in the first sector  ;  End of code and data that have to be in the first sector
1095  ; ----------------------------------------------------------------------------  ; ----------------------------------------------------------------------------
1096    
1097  all_read:  all_read:
 ;  
 ; Initialize screen (if we're using one)  
 ;  
  ; Now set up screen parameters  
  call adjust_screen  
   
  ; Wipe the F-key area  
  mov al,NULLFILE  
  mov di,FKeyName  
  mov cx,10*(1 << FILENAME_MAX_LG2)  
  rep stosb  
   
  ; Patch the writechr routine to point to the full code  
  mov word [writechr+1], writechr_full-(writechr+3)  
   
 ; Tell the user we got this far...  
 %ifndef DEBUG_MESSAGES ; Gets messy with debugging on  
  mov si,copyright_str  
  call writestr  
 %endif  
1098    
1099  ; Test tracers  ; Test tracers
1100   TRACER 'T'   TRACER 'T'
# Line 866  all_read: Line 1106  all_read:
1106  %include "init.inc"  %include "init.inc"
1107  %include "cpuinit.inc"  %include "cpuinit.inc"
1108    
1109     ; Patch the writechr routine to point to the full code
1110     mov word [writechr+1], writechr_full-(writechr+3)
1111    
1112    ; Tell the user we got this far...
1113    %ifndef DEBUG_MESSAGES ; Gets messy with debugging on
1114     mov si,copyright_str
1115     call writestr_early
1116    %endif
1117    
1118  ;  ;
1119  ; Now we're all set to start with our *real* business. First load the  ; Now we're all set to start with our *real* business. First load the
1120  ; configuration file (if any) and parse it.  ; configuration file (if any) and parse it.
# Line 885  all_read: Line 1134  all_read:
1134  ; mkisofs gave us a pointer to the primary volume descriptor  ; mkisofs gave us a pointer to the primary volume descriptor
1135  ; (which will be at 16 only for a single-session disk!); from the PVD  ; (which will be at 16 only for a single-session disk!); from the PVD
1136  ; we should be able to find the rest of what we need to know.  ; we should be able to find the rest of what we need to know.
1137  ;  ;
1138  get_fs_structures:  get_fs_structures:
1139   mov eax,[bi_pvd]   mov eax,[bi_pvd]
1140   mov bx,trackbuf   mov bx,trackbuf
# Line 893  get_fs_structures: Line 1142  get_fs_structures:
1142    
1143   mov eax,[trackbuf+156+2]   mov eax,[trackbuf+156+2]
1144   mov [RootDir+dir_lba],eax   mov [RootDir+dir_lba],eax
1145   mov [CurDir+dir_lba],eax   mov [CurrentDir+dir_lba],eax
1146  %ifdef DEBUG_MESSAGES  %ifdef DEBUG_MESSAGES
1147   mov si,dbg_rootdir_msg   mov si,dbg_rootdir_msg
1148   call writemsg   call writemsg
# Line 901  get_fs_structures: Line 1150  get_fs_structures:
1150   call crlf   call crlf
1151  %endif  %endif
1152   mov eax,[trackbuf+156+10]   mov eax,[trackbuf+156+10]
1153   mov [RootDir+dir_len],eax   mov [RootDir+dir_len],eax
1154   mov [CurDir+dir_len],eax   mov [CurrentDir+dir_len],eax
1155   add eax,SECTOR_SIZE-1   add eax,SECTOR_SIZE-1
1156   shr eax,SECTOR_SHIFT   shr eax,SECTOR_SHIFT
1157   mov [RootDir+dir_clust],eax   mov [RootDir+dir_clust],eax
1158   mov [CurDir+dir_clust],eax   mov [CurrentDir+dir_clust],eax
1159    
1160   ; Look for an isolinux directory, and if found,   ; Look for an isolinux directory, and if found,
1161   ; make it the current directory instead of the root   ; make it the current directory instead of the root
1162   ; directory.   ; directory.
1163     ; Also copy the name of the directory to CurrentDirName
1164     mov word [CurrentDirName],ROOT_DIR_WORD ; Write '/',0 to the CurrentDirName
1165   mov di,boot_dir ; Search for /boot/isolinux   mov di,boot_dir ; Search for /boot/isolinux
1166   mov al,02h   mov al,02h
1167     push di
1168   call searchdir_iso   call searchdir_iso
1169     pop di
1170   jnz .found_dir   jnz .found_dir
1171   mov di,isolinux_dir   mov di,isolinux_dir
1172   mov al,02h ; Search for /isolinux   mov al,02h ; Search for /isolinux
1173     push di
1174   call searchdir_iso   call searchdir_iso
1175     pop di
1176   jz .no_isolinux_dir   jz .no_isolinux_dir
1177  .found_dir:  .found_dir:
1178   mov [CurDir+dir_len],eax   ; Copy current directory name to CurrentDirName
1179     push si
1180     push di
1181     mov si,di
1182     mov di,CurrentDirName
1183     call strcpy
1184     mov byte [di],0 ;done in case it's not word aligned
1185     dec di
1186     mov byte [di],'/'
1187     pop di
1188     pop si
1189    
1190     mov [CurrentDir+dir_len],eax
1191   mov eax,[si+file_left]   mov eax,[si+file_left]
1192   mov [CurDir+dir_clust],eax   mov [CurrentDir+dir_clust],eax
1193   xor eax,eax ; Free this file pointer entry   xor eax,eax ; Free this file pointer entry
1194   xchg eax,[si+file_sector]   xchg eax,[si+file_sector]
1195   mov [CurDir+dir_lba],eax   mov [CurrentDir+dir_lba],eax
1196  %ifdef DEBUG_MESSAGES  %ifdef DEBUG_MESSAGES
1197   push si   push si
1198   mov si,dbg_isodir_msg   mov si,dbg_isodir_msg
# Line 945  load_config: Line 1212  load_config:
1212   call writemsg   call writemsg
1213  %endif  %endif
1214    
1215   mov di,isolinux_cfg   mov si,config_name
1216     mov di,ConfigName
1217     call strcpy
1218    
1219     mov di,ConfigName
1220   call open   call open
1221   jz no_config_file ; Not found or empty   jz no_config_file ; Not found or empty
1222    
# Line 961  load_config: Line 1232  load_config:
1232  %include "ui.inc"  %include "ui.inc"
1233    
1234  ;  ;
1235  ; Linux kernel loading code is common.  ; Enable disk emulation.  The kind of disk we emulate is dependent on the
1236  ;  ; size of the file: 1200K, 1440K or 2880K floppy, otherwise harddisk.
 %include "runkernel.inc"  
   
 ;  
 ; COMBOOT-loading code  
 ;  
 %include "comboot.inc"  
 %include "com32.inc"  
 %include "cmdline.inc"  
   
 ;  
 ; Boot sector loading code  
 ;  
 %include "bootsect.inc"  
   
 ;  
 ; Enable disk emulation.  The kind of disk we emulate is dependent on the size of  
 ; the file: 1200K, 1440K or 2880K floppy, otherwise harddisk.  
1237  ;  ;
1238  is_disk_image:  is_disk_image:
1239   TRACER CR   TRACER CR
# Line 987  is_disk_image: Line 1241  is_disk_image:
1241   TRACER 'D'   TRACER 'D'
1242   TRACER ':'   TRACER ':'
1243    
1244   shl edx,16   mov edx,eax ; File size
  mov dx,ax ; Set EDX <- file size  
1245   mov di,img_table   mov di,img_table
1246   mov cx,img_table_count   mov cx,img_table_count
1247   mov eax,[si+file_sector] ; Starting LBA of file   mov eax,[si+file_sector] ; Starting LBA of file
# Line 1012  is_disk_image: Line 1265  is_disk_image:
1265   mov bx,trackbuf   mov bx,trackbuf
1266   mov cx,1 ; Load 1 sector   mov cx,1 ; Load 1 sector
1267   call getfssec   call getfssec
1268    
1269   cmp word [trackbuf+510],0aa55h ; Boot signature   cmp word [trackbuf+510],0aa55h ; Boot signature
1270   jne .bad_image ; Image not bootable   jne .bad_image ; Image not bootable
1271    
# Line 1031  is_disk_image: Line 1284  is_disk_image:
1284  .part_loop:  .part_loop:
1285   add di,byte 16   add di,byte 16
1286   loop .part_scan   loop .part_scan
1287    
1288   push eax ; H/S   push eax ; H/S
1289   push edx ; File size   push edx ; File size
1290   mov bl,ah   mov bl,ah
# Line 1080  is_disk_image: Line 1333  is_disk_image:
1333    
1334   mov ax,4C00h ; Enable emulation and boot   mov ax,4C00h ; Enable emulation and boot
1335   mov si,dspec_packet   mov si,dspec_packet
1336   mov dl,[DriveNo]   mov dl,[DriveNumber]
1337   lss sp,[InitStack]   lss sp,[InitStack]
1338   TRACER 'X'   TRACER 'X'
1339    
1340   int 13h   call int13
1341    
1342   ; If this returns, we have problems   ; If this returns, we have problems
1343  .bad_image:  .bad_image:
1344   mov si,err_disk_image   mov si,err_disk_image
1345   call cwritestr   call writestr
1346   jmp enter_command   jmp enter_command
1347    
1348  ;  ;
# Line 1109  is_disk_image: Line 1362  is_disk_image:
1362  .done_sector: ret  .done_sector: ret
1363    
1364  ;  ;
1365  ; Boot a specified local disk.  AX specifies the BIOS disk number; or  ; close_file:
1366  ; 0xFFFF in case we should execute INT 18h ("next device.")  ;     Deallocates a file structure (pointer in SI)
1367    ;     Assumes CS == DS.
1368  ;  ;
1369  local_boot:  close_file:
1370   call vgaclearmode   and si,si
1371   lss sp,[cs:Stack] ; Restore stack pointer   jz .closed
1372   xor dx,dx   mov dword [si],0 ; First dword == file_left
1373   mov ds,dx   xor si,si
1374   mov es,dx  .closed: ret
  mov fs,dx  
  mov gs,dx  
  mov si,localboot_msg  
  call writestr  
  cmp ax,-1  
  je .int18  
   
  ; Load boot sector from the specified BIOS device and jump to it.  
  mov dl,al  
  xor dh,dh  
  push dx  
  xor ax,ax ; Reset drive  
  call xint13  
  mov ax,0201h ; Read one sector  
  mov cx,0001h ; C/H/S = 0/0/1 (first sector)  
  mov bx,trackbuf  
  call xint13  
  pop dx  
  cli ; Abandon hope, ye who enter here  
  mov si,trackbuf  
  mov di,07C00h  
  mov cx,512 ; Probably overkill, but should be safe  
  rep movsd  
  lss sp,[cs:InitStack]  
  jmp 0:07C00h ; Jump to new boot sector  
   
 .int18:  
  int 18h ; Hope this does the right thing...  
  jmp kaboom ; If we returned, oh boy...  
   
 ;  
 ; Abort loading code  
 ;  
 %include "abort.inc"  
1375    
1376  ;  ;
1377  ; searchdir:  ; searchdir:
# Line 1163  local_boot: Line 1383  local_boot:
1383  ;     If successful:  ;     If successful:
1384  ; ZF clear  ; ZF clear
1385  ; SI = file pointer  ; SI = file pointer
1386  ; DX:AX or EAX = file length in bytes  ; EAX = file length in bytes
1387  ;     If unsuccessful  ;     If unsuccessful
1388  ; ZF set  ; ZF set
1389  ;  ;
# Line 1187  searchdir_iso: Line 1407  searchdir_iso:
1407   push es   push es
1408   push ds   push ds
1409   pop es ; ES = DS   pop es ; ES = DS
1410   mov si,CurDir   mov si,CurrentDir
1411   cmp byte [di],'/' ; If filename begins with slash   cmp byte [di],'/' ; If filename begins with slash
1412   jne .not_rooted   jne .not_rooted
1413   inc di ; Skip leading slash   inc di ; Skip leading slash
# Line 1195  searchdir_iso: Line 1415  searchdir_iso:
1415  .not_rooted:  .not_rooted:
1416   mov eax,[si+dir_clust]   mov eax,[si+dir_clust]
1417   mov [bx+file_left],eax   mov [bx+file_left],eax
1418     shl eax,SECTOR_SHIFT
1419     mov [bx+file_bytesleft],eax
1420   mov eax,[si+dir_lba]   mov eax,[si+dir_lba]
1421   mov [bx+file_sector],eax   mov [bx+file_sector],eax
1422   mov edx,[si+dir_len]   mov edx,[si+dir_len]
# Line 1275  searchdir_iso: Line 1497  searchdir_iso:
1497   mov eax,[si+2] ; Location of extent   mov eax,[si+2] ; Location of extent
1498   mov [bx+file_sector],eax   mov [bx+file_sector],eax
1499   mov eax,[si+10] ; Data length   mov eax,[si+10] ; Data length
1500     mov [bx+file_bytesleft],eax
1501   push eax   push eax
1502   add eax,SECTOR_SIZE-1   add eax,SECTOR_SIZE-1
1503   shr eax,SECTOR_SHIFT   shr eax,SECTOR_SHIFT
1504   mov [bx+file_left],eax   mov [bx+file_left],eax
1505   pop eax   pop eax
1506   mov edx,eax   jz .failure ; Empty file?
1507   shr edx,16   ; ZF = 0
  and bx,bx ; ZF = 0  
1508   mov si,bx   mov si,bx
1509   pop es   pop es
1510   ret   ret
# Line 1320  allocate_file: Line 1542  allocate_file:
1542   ret   ret
1543    
1544  ;  ;
1545  ; iso_compare_names:  ; iso_compare_names:
1546  ; Compare the names DS:SI and DS:DI and report if they are  ; Compare the names DS:SI and DS:DI and report if they are
1547  ; equal from an ISO 9660 perspective.  SI is the name from  ; equal from an ISO 9660 perspective.  SI is the name from
1548  ; the filesystem; CX indicates its length, and ';' terminates.  ; the filesystem; CX indicates its length, and ';' terminates.
# Line 1373  iso_compare_names: Line 1595  iso_compare_names:
1595  ;  ;
1596  ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed  ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed
1597  ;       to by ES:DI; ends on encountering any whitespace.  ;       to by ES:DI; ends on encountering any whitespace.
1598    ;       DI is preserved.
1599  ;  ;
1600  ;       This verifies that a filename is < FILENAME_MAX characters,  ;       This verifies that a filename is < FILENAME_MAX characters,
1601  ;       doesn't contain whitespace, zero-pads the output buffer,  ;       doesn't contain whitespace, zero-pads the output buffer,
1602  ;       and removes trailing dots and redundant slashes,  ;       and removes trailing dots and redundant slashes,
1603  ;       so "repe cmpsb" can do a compare, and the  ;       so "repe cmpsb" can do a compare, and the
1604  ;       path-searching routine gets a bit of an easier job.  ;       path-searching routine gets a bit of an easier job.
1605  ;        ;
1606  mangle_name:  mangle_name:
1607     push di
1608   push bx   push bx
1609   xor ax,ax   xor ax,ax
1610   mov cx,FILENAME_MAX-1   mov cx,FILENAME_MAX-1
# Line 1401  mangle_name: Line 1625  mangle_name:
1625  .mn_end:  .mn_end:
1626   cmp bx,di ; At the beginning of the buffer?   cmp bx,di ; At the beginning of the buffer?
1627   jbe .mn_zero   jbe .mn_zero
1628   cmp byte [di-1],'.' ; Terminal dot?   cmp byte [es:di-1],'.' ; Terminal dot?
1629   je .mn_kill   je .mn_kill
1630   cmp byte [di-1],'/' ; Terminal slash?   cmp byte [es:di-1],'/' ; Terminal slash?
1631   jne .mn_zero   jne .mn_zero
1632  .mn_kill: dec di ; If so, remove it  .mn_kill: dec di ; If so, remove it
1633   inc cx   inc cx
# Line 1413  mangle_name: Line 1637  mangle_name:
1637   xor ax,ax ; Zero-fill name   xor ax,ax ; Zero-fill name
1638   rep stosb   rep stosb
1639   pop bx   pop bx
1640     pop di
1641   ret ; Done   ret ; Done
1642    
1643  ;  ;
1644  ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled  ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled
1645  ;                filename to the conventional representation.  This is needed  ;                filename to the conventional representation.  This is needed
1646  ;                for the BOOT_IMAGE= parameter for the kernel.  ;                for the BOOT_IMAGE= parameter for the kernel.
 ;                NOTE: A 13-byte buffer is mandatory, even if the string is  
 ;                known to be shorter.  
1647  ;  ;
1648  ;                DS:SI -> input mangled file name  ;                DS:SI -> input mangled file name
1649  ;                ES:DI -> output buffer  ;                ES:DI -> output buffer
# Line 1442  unmangle_name: call strcpy Line 1665  unmangle_name: call strcpy
1665  ;  On exit:  ;  On exit:
1666  ; SI -> File pointer (or 0 on EOF)  ; SI -> File pointer (or 0 on EOF)
1667  ; CF = 1 -> Hit EOF  ; CF = 1 -> Hit EOF
1668    ; ECX -> Bytes actually read
1669  ;  ;
1670  getfssec:  getfssec:
1671   TRACER 'F'   TRACER 'F'
   
1672   push ds   push ds
1673   push cs   push cs
1674   pop ds ; DS <- CS   pop ds ; DS <- CS
# Line 1456  getfssec: Line 1679  getfssec:
1679   mov ecx,[si+file_left]   mov ecx,[si+file_left]
1680  .ok_size:  .ok_size:
1681    
1682   mov bp,cx   pushad
  push cx  
  push si  
1683   mov eax,[si+file_sector]   mov eax,[si+file_sector]
1684     mov bp,cx
1685   TRACER 'l'   TRACER 'l'
1686   call getlinsec   call getlinsec
1687   xor ecx,ecx   popad
  pop si  
  pop cx  
1688    
1689     ; ECX[31:16] == 0 here...
1690   add [si+file_sector],ecx   add [si+file_sector],ecx
1691   sub [si+file_left],ecx   sub [si+file_left],ecx
1692   ja .not_eof ; CF = 0   shl ecx,SECTOR_SHIFT ; Convert to bytes
1693     cmp ecx,[si+file_bytesleft]
1694   xor ecx,ecx   jb .not_all
1695   mov [si+file_sector],ecx ; Mark as unused   mov ecx,[si+file_bytesleft]
1696   xor si,si  .not_all: sub [si+file_bytesleft],ecx
1697     jnz .ret ; CF = 0 in this case...
1698     push eax
1699     xor eax,eax
1700     mov [si+file_sector],eax ; Unused
1701     mov si,ax
1702     pop eax
1703   stc   stc
1704    .ret:
 .not_eof:  
1705   pop ds   pop ds
1706   TRACER 'f'   TRACER 'f'
1707   ret   ret
# Line 1486  getfssec: Line 1712  getfssec:
1712    
1713  %include "getc.inc" ; getc et al  %include "getc.inc" ; getc et al
1714  %include "conio.inc" ; Console I/O  %include "conio.inc" ; Console I/O
1715    %include "configinit.inc" ; Initialize configuration
1716  %include "parseconfig.inc" ; High-level config file handling  %include "parseconfig.inc" ; High-level config file handling
1717  %include "parsecmd.inc" ; Low-level config file handling  %include "parsecmd.inc" ; Low-level config file handling
1718  %include "bcopy32.inc" ; 32-bit bcopy  %include "bcopy32.inc" ; 32-bit bcopy
# Line 1495  getfssec: Line 1722  getfssec:
1722  %include "highmem.inc" ; High memory sizing  %include "highmem.inc" ; High memory sizing
1723  %include "strcpy.inc" ; strcpy()  %include "strcpy.inc" ; strcpy()
1724  %include "rawcon.inc" ; Console I/O w/o using the console functions  %include "rawcon.inc" ; Console I/O w/o using the console functions
1725    %include "idle.inc" ; Idle handling
1726    %include "adv.inc" ; Auxillary Data Vector
1727    %include "localboot.inc" ; Disk-based local boot
1728    
1729  ; -----------------------------------------------------------------------------  ; -----------------------------------------------------------------------------
1730  ;  Begin data section  ;  Begin data section
# Line 1502  getfssec: Line 1732  getfssec:
1732    
1733   section .data   section .data
1734    
 boot_prompt db 'boot: ', 0  
 wipe_char db BS, ' ', BS, 0  
 err_notfound db 'Could not find kernel image: ',0  
 err_notkernel db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0  
 err_noram db 'It appears your computer has less than '  
  asciidec dosram_k  
  db 'K of low ("DOS")'  
  db CR, LF  
  db 'RAM.  Linux needs at least this amount to boot.  If you get'  
  db CR, LF  
  db 'this message in error, hold down the Ctrl key while'  
  db CR, LF  
  db 'booting, and I will take your word for it.', CR, LF, 0  
 err_badcfg      db 'Unknown keyword in config file.', CR, LF, 0  
 err_noparm      db 'Missing parameter in config file.', CR, LF, 0  
 err_noinitrd    db CR, LF, 'Could not find ramdisk image: ', 0  
 err_nohighmem   db 'Not enough memory to load specified kernel.', CR, LF, 0  
 err_highload    db CR, LF, 'Kernel transfer failure.', CR, LF, 0  
 err_oldkernel   db 'Cannot load a ramdisk with an old kernel image.'  
                 db CR, LF, 0  
 err_notdos db ': attempted DOS system call', CR, LF, 0  
 err_comlarge db 'COMBOOT image too large.', CR, LF, 0  
 err_bssimage db 'BSS images not supported.', CR, LF, 0  
 err_a20 db CR, LF, 'A20 gate not responding!', CR, LF, 0  
 notfound_msg db 'not found', CR, LF, 0  
 localboot_msg db 'Booting from local disk...', CR, LF, 0  
 cmdline_msg db 'Command line: ', CR, LF, 0  
 ready_msg db 'Ready.', CR, LF, 0  
 trying_msg db 'Trying to load: ', 0  
 crlfloading_msg db CR, LF ; Fall through  
 loading_msg     db 'Loading ', 0  
 dotdot_msg      db '.'  
 dot_msg         db '.', 0  
 fourbs_msg db BS, BS, BS, BS, 0  
 aborted_msg db ' aborted.', CR, LF, 0  
 crff_msg db CR, FF, 0  
1735  default_str db 'default', 0  default_str db 'default', 0
1736  default_len equ ($-default_str)  default_len equ ($-default_str)
1737  boot_dir db '/boot' ; /boot/isolinux  boot_dir db '/boot' ; /boot/isolinux
1738  isolinux_dir db '/isolinux', 0  isolinux_dir db '/isolinux', 0
1739  ConfigName equ $  config_name db 'isolinux.cfg', 0
 isolinux_cfg db 'isolinux.cfg', 0  
1740  err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0  err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0
1741    
1742  %ifdef DEBUG_MESSAGES  %ifdef DEBUG_MESSAGES
# Line 1552  dbg_isodir_msg db 'isolinux directory at Line 1745  dbg_isodir_msg db 'isolinux directory at
1745  dbg_config_msg db 'About to load config file...', CR, LF, 0  dbg_config_msg db 'About to load config file...', CR, LF, 0
1746  dbg_configok_msg db 'Configuration file opened...', CR, LF, 0  dbg_configok_msg db 'Configuration file opened...', CR, LF, 0
1747  %endif  %endif
 ;  
 ; Command line options we'd like to take a look at  
 ;  
 ; mem= and vga= are handled as normal 32-bit integer values  
 initrd_cmd db 'initrd='  
 initrd_cmd_len equ 7  
1748    
1749  ;  ;
1750  ; Config file keyword table  ; Config file keyword table
# Line 1567  initrd_cmd_len equ 7 Line 1754  initrd_cmd_len equ 7
1754  ;  ;
1755  ; Extensions to search for (in *forward* order).  ; Extensions to search for (in *forward* order).
1756  ;  ;
1757   align 4, db 0   alignz 4
1758  exten_table: db '.cbt' ; COMBOOT (specific)  exten_table: db '.cbt' ; COMBOOT (specific)
1759   db '.img' ; Disk image   db '.img' ; Disk image
1760   db '.bin' ; CD boot sector   db '.bin' ; CD boot sector
# Line 1579  exten_table_end: Line 1766  exten_table_end:
1766  ;  ;
1767  ; Floppy image table  ; Floppy image table
1768  ;  ;
1769   align 4, db 0   alignz 4
1770  img_table_count equ 3  img_table_count equ 3
1771  img_table:  img_table:
1772   dd 1200*1024 ; 1200K floppy   dd 1200*1024 ; 1200K floppy
# Line 1610  img_table: Line 1797  img_table:
1797  ; **** ISOLINUX:: We may have to make this flexible, based on what the  ; **** ISOLINUX:: We may have to make this flexible, based on what the
1798  ; **** BIOS expects our "sector size" to be.  ; **** BIOS expects our "sector size" to be.
1799  ;  ;
1800   alignb 4, db 0   alignz 4
1801  BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf  BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf
 BufSafeSec dw trackbufsize/SECTOR_SIZE ; = how many sectors?  
1802  BufSafeBytes dw trackbufsize ; = how many bytes?  BufSafeBytes dw trackbufsize ; = how many bytes?
 EndOfGetCBuf dw getcbuf+trackbufsize ; = getcbuf+BufSafeBytes  
1803  %ifndef DEPEND  %ifndef DEPEND
1804  %if ( trackbufsize % SECTOR_SIZE ) != 0  %if ( trackbufsize % SECTOR_SIZE ) != 0
1805  %error trackbufsize must be a multiple of SECTOR_SIZE  %error trackbufsize must be a multiple of SECTOR_SIZE

Legend:
Removed from v.1132  
changed lines
  Added in v.1133