NEWS: Document Bruce Robson's Adaptec bug fix
[profile/ivi/syslinux.git] / ldlinux.asm
index 733f2ec..0f06315 100644 (file)
@@ -11,7 +11,7 @@
 ;  from MS-LOSS, and can be especially useful in conjunction with the
 ;  umsdos filesystem.
 ;
-;   Copyright (C) 1994-2007   H. Peter Anvin
+;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
 ;
 ;  This program is free software; you can redistribute it and/or modify
 ;  it under the terms of the GNU General Public License as published by
@@ -58,12 +58,13 @@ SECTOR_SIZE equ (1 << SECTOR_SHIFT)
 ; The following structure is used for "virtual kernels"; i.e. LILO-style
 ; option labels.  The options we permit here are `kernel' and `append
 ; Since there is no room in the bottom 64K for all of these, we
-; 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.
 ;
                struc vkernel
 vk_vname:      resb FILENAME_MAX       ; Virtual name **MUST BE FIRST!**
 vk_rname:      resb FILENAME_MAX       ; Real name
 vk_appendlen:  resw 1
+vk_type:       resb 1                  ; Type of file
                alignb 4
 vk_append:     resb max_cmd_len+1      ; Command line
                alignb 4
@@ -77,9 +78,8 @@ vk_end:               equ $                   ; Should be <= vk_size
 ;
 ; 0000h - main code/data segment (and BIOS segment)
 ;
-real_mode_seg  equ 4000h
-cache_seg      equ 3000h               ; 64K area for metadata cache
-vk_seg          equ 2000h              ; Virtual kernels
+real_mode_seg  equ 3000h
+cache_seg      equ 2000h               ; 64K area for metadata cache
 xfer_buf_seg   equ 1000h               ; Bounce buffer for I/O to high mem
 comboot_seg    equ real_mode_seg       ; COMBOOT image loading zone
 
@@ -107,8 +107,7 @@ file_left   resd 1                  ; Number of sectors left
                section .earlybss
 trackbufsize   equ 8192
 trackbuf       resb trackbufsize       ; Track buffer goes here
-getcbuf                resb trackbufsize
-               ; ends at 4800h
+               ; ends at 2800h
 
                section .bss
                alignb 8
@@ -122,7 +121,6 @@ RootDir             resd 1                  ; Location of root directory proper
 DataArea       resd 1                  ; Location of data area
 RootDirSize    resd 1                  ; Root dir size in sectors
 TotalSectors   resd 1                  ; Total number of sectors
-EndSector      resd 1                  ; Location of filesystem end
 ClustSize      resd 1                  ; Bytes/cluster
 ClustMask      resd 1                  ; Sectors/cluster - 1
 CopySuper      resb 1                  ; Distinguish .bs versus .bss
@@ -133,18 +131,6 @@ ClustByteShift     resb 1                  ; Shift count for bytes/cluster
                alignb open_file_t_size
 Files          resb MAX_OPEN*open_file_t_size
 
-;
-; 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
-
-
                section .text
 ;
 ; Some of the things that have to be saved very early are saved
@@ -154,7 +140,8 @@ xbs_vgatmpbuf       equ 2*trackbufsize
 StackBuf       equ $-44-32             ; Start the stack here (grow down - 4K)
 PartInfo       equ StackBuf            ; Saved partition table entry
 FloppyTable    equ PartInfo+16         ; Floppy info table (must follow PartInfo)
-OrigFDCTabPtr  equ StackBuf-4          ; The high dword on the stack
+OrigFDCTabPtr  equ StackBuf-8          ; The 2nd high dword on the stack
+OrigESDI       equ StackBuf-4          ; The high dword on the stack
 
 ;
 ; Primary entry point.  Tempting as though it may be, we can't put the
@@ -224,12 +211,14 @@ start:
                xor ax,ax
                mov ss,ax
                mov sp,StackBuf         ; Just below BSS
+               push es                 ; Save initial ES:DI -> $PnP pointer
+               push di
                mov es,ax
 ;
 ; DS:SI may contain a partition table entry.  Preserve it for us.
 ;
                mov cx,8                ; Save partition info
-               mov di,sp
+               mov di,PartInfo
                rep movsw
 
                mov ds,ax               ; Now we can initialize DS...
@@ -403,11 +392,11 @@ getlinsec_ebios:
                popad
                lea sp,[si+16]                  ; Remove DAPA
                jc .error
-               pop bp
+               pop bp
                add eax,edi                     ; Advance sector pointer
                sub bp,di                       ; Sectors left
                 shl di,SECTOR_SHIFT            ; 512-byte sectors
-                add bx,di                      ; Advance buffer pointer
+                add bx,di                      ; Advance buffer pointer
                 and bp,bp
                 jnz .loop
 
@@ -525,7 +514,7 @@ disk_error:
 kaboom:
                xor si,si
                mov ss,si
-               mov sp,StackBuf-4       ; Reset stack
+               mov sp,StackBuf-4       ; Reset stack
                mov ds,si               ; Reset data segment
                pop dword [fdctab]      ; Restore FDC table
 .patch:                                        ; When we have full code, intercept here
@@ -541,7 +530,9 @@ kaboom:
                jmp short .loop
 .done:
                cbw                     ; AH <- 0
-               int 16h                 ; Wait for keypress
+.again:                int 16h                 ; Wait for keypress
+                                       ; NB: replaced by int 18h if
+                                       ; chosen at install time..
                int 19h                 ; And try once more to boot...
 .norge:                jmp short .norge        ; If int 19h returned; this is the end
 
@@ -564,7 +555,11 @@ bailmsg:   db 'Boot error', 0Dh, 0Ah, 0
 
 FirstSector    dd 0xDEADBEEF                   ; Location of sector 1
 MaxTransfer    dw 0x007F                       ; Max transfer size
-bootsignature  dw 0AA55h
+
+; This field will be filled in 0xAA55 by the installer, but we abuse it
+; to house a pointer to the INT 16h instruction at
+; kaboom.again, which gets patched to INT 18h in RAID mode.
+bootsignature  dw kaboom.again-bootsec
 
 ;
 ; ===========================================================================
@@ -794,9 +789,6 @@ genfatinfo:
 .have_secs:
                mov [TotalSectors],edx
 
-               add edx,eax
-               mov [EndSector],edx
-
                mov eax,[bxResSectors]
                mov [FAT],eax                   ; Beginning of FAT
                mov edx,[bxFATsecs]
@@ -821,20 +813,20 @@ genfatinfo:
                bsr cx,ax
                mov [ClustShift],cl
                push cx
-               add cl,9
+               add cl,SECTOR_SHIFT
                mov [ClustByteShift],cl
                pop cx
                dec ax
                mov [ClustMask],eax
                inc ax
-               shl eax,9
+               shl eax,SECTOR_SHIFT
                mov [ClustSize],eax
 
 ;
 ; FAT12, FAT16 or FAT28^H^H32?  This computation is fscking ridiculous.
 ;
 getfattype:
-               mov eax,[EndSector]
+               mov eax,[TotalSectors]
                sub eax,[DataArea]
                shr eax,cl                      ; cl == ClustShift
                mov cl,nextcluster_fat12-(nextcluster+2)
@@ -863,14 +855,6 @@ getfattype:
 %include "init.inc"
 
 ;
-; Clear Files structures
-;
-               mov di,Files
-               mov cx,(MAX_OPEN*open_file_t_size)/4
-               xor eax,eax
-               rep stosd
-
-;
 ; Initialize the metadata cache
 ;
                call initcache
@@ -899,6 +883,10 @@ getfattype:
 ;
 ; Load configuration file
 ;
+               mov si,config_name      ; Save configuration file name
+               mov di,ConfigName
+               call strcpy
+
                mov di,syslinux_cfg1
                call open
                jnz .config_open
@@ -919,28 +907,6 @@ getfattype:
 %include "ui.inc"
 
 ;
-; Linux kernel loading code is common.
-;
-%include "runkernel.inc"
-
-;
-; COMBOOT-loading code
-;
-%include "comboot.inc"
-%include "com32.inc"
-%include "cmdline.inc"
-
-;
-; Boot sector loading code
-;
-%include "bootsect.inc"
-
-;
-; Abort loading code
-;
-%include "abort.inc"
-
-;
 ; allocate_file: Allocate a file structure
 ;
 ;              If successful:
@@ -1059,6 +1025,17 @@ search_dos_dir:
                ret
 
 ;
+; close_file:
+;           Deallocates a file structure (pointer in SI)
+;           Assumes CS == DS.
+;
+close_file:
+               and si,si
+               jz .closed
+               mov dword [si],0                ; First dword == file_left
+.closed:       ret
+
+;
 ; searchdir:
 ;
 ;      Open a file
@@ -1151,24 +1128,32 @@ PrevDir         resd 1                  ; Last scanned directory
 kaboom2:
                mov si,err_bootfailed
                call cwritestr
+               cmp byte [kaboom.again+1],18h   ; INT 18h version?
+               je .int18
                call getchar
                call vgaclearmode
                int 19h                 ; And try once more to boot...
 .norge:                jmp short .norge        ; If int 19h returned; this is the end
+.int18:
+               call vgaclearmode
+               int 18h
+.noreg:                jmp short .noreg        ; Nynorsk
 
 ;
 ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed
 ;             to by ES:DI; ends on encountering any whitespace.
+;             DI is preserved.
 ;
 ;             This verifies that a filename is < FILENAME_MAX characters,
 ;             doesn't contain whitespace, zero-pads the output buffer,
-;             and removes trailing dots and redundant slashes, plus changes
+;             and removes trailing dots and redundant slashes, plus changes
 ;              backslashes to forward slashes,
 ;             so "repe cmpsb" can do a compare, and the path-searching routine
 ;              gets a bit of an easier job.
 ;
 ;
 mangle_name:
+               push di
                push bx
                xor ax,ax
                mov cx,FILENAME_MAX-1
@@ -1205,6 +1190,7 @@ mangle_name:
                xor ax,ax                       ; Zero-fill name
                rep stosb
                pop bx
+               pop di
                ret                             ; Done
 
 ;
@@ -1461,10 +1447,10 @@ nextcluster_fat28:
 
 ;
 ; nextsector:  Given a sector in EAX on input, return the next sector
-;              of the same filesystem object, which may be the root
-;                      directory or a cluster chain.  Returns  EOF.
+;              of the same filesystem object, which may be the root
+;              directory or a cluster chain.  Returns  EOF.
 ;
-;              Assumes CS == DS.
+;              Assumes CS == DS.
 ;
 nextsector:
                push edi
@@ -1532,6 +1518,7 @@ getfatsector:
 %include "conio.inc"           ; Console I/O
 %include "plaincon.inc"                ; writechr
 %include "writestr.inc"                ; String output
+%include "configinit.inc"      ; Initialize configuration
 %include "parseconfig.inc"     ; High-level config file handling
 %include "parsecmd.inc"                ; Low-level config file handling
 %include "bcopy32.inc"         ; 32-bit bcopy
@@ -1541,6 +1528,7 @@ getfatsector:
 %include "highmem.inc"         ; High memory sizing
 %include "strcpy.inc"           ; strcpy()
 %include "cache.inc"           ; Metadata disk cache
+%include "adv.inc"             ; Auxillary Data Vector
 
 ; -----------------------------------------------------------------------------
 ;  Begin data section
@@ -1549,44 +1537,12 @@ getfatsector:
                section .data
 copyright_str   db ' Copyright (C) 1994-', year, ' H. Peter Anvin'
                db CR, LF, 0
-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 syslinux.cfg.', CR, LF, 0
-err_noparm      db 'Missing parameter in syslinux.cfg.', 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_a20                db CR, LF, 'A20 gate not responding!', CR, LF, 0
 err_bootfailed db CR, LF, 'Boot failed: please change disks and press '
                db 'a key to continue.', CR, LF, 0
-ready_msg      db 'Ready.', CR, LF, 0
-crlfloading_msg        db CR, LF
-loading_msg     db 'Loading ', 0
-dotdot_msg      db '.'
-dot_msg         db '.', 0
-aborted_msg    db ' aborted.'                  ; Fall through to crlf_msg!
-crlf_msg       db CR, LF
-null_msg       db 0
-crff_msg       db CR, FF, 0
 syslinux_cfg1  db '/boot'                      ; /boot/syslinux/syslinux.cfg
 syslinux_cfg2  db '/syslinux'                  ; /syslinux/syslinux.cfg
 syslinux_cfg3  db '/'                          ; /syslinux.cfg
-ConfigName     db 'syslinux.cfg', 0            ; syslinux.cfg
+config_name    db 'syslinux.cfg', 0            ; syslinux.cfg
 
 ;
 ; Command line options we'd like to take a look at
@@ -1603,11 +1559,11 @@ initrd_cmd_len  equ 7
 ;
 ; Extensions to search for (in *forward* order).
 ;
-exten_table:   db 'CBT',0              ; COMBOOT (specific)
-               db 'BSS',0              ; Boot Sector (add superblock)
-               db 'BS ',0              ; Boot Sector
-               db 'COM',0              ; COMBOOT (same as DOS)
-               db 'C32',0              ; COM32
+exten_table:   db '.cbt'               ; COMBOOT (specific)
+               db '.bss'               ; Boot Sector (add superblock)
+               db '.bs', 0             ; Boot Sector
+               db '.com'               ; COMBOOT (same as DOS)
+               db '.c32'               ; COM32
 exten_table_end:
                dd 0, 0                 ; Need 8 null bytes here
 
@@ -1620,9 +1576,7 @@ debug_magic       dw 0D00Dh               ; Debug code sentinel
 
                alignb 4, db 0
 BufSafe                dw trackbufsize/SECTOR_SIZE     ; Clusters we can load into trackbuf
-BufSafeSec     dw trackbufsize/SECTOR_SIZE     ; = how many sectors?
 BufSafeBytes   dw trackbufsize         ; = how many bytes?
-EndOfGetCBuf   dw getcbuf+trackbufsize ; = getcbuf+BufSafeBytes
 %ifndef DEPEND
 %if ( trackbufsize % SECTOR_SIZE ) != 0
 %error trackbufsize must be a multiple of SECTOR_SIZE