syslinux/syslinux-3.82-gfxboot.diff

802 lines
17 KiB
Diff

diff --git a/core/abort.inc b/core/abort.inc
index 5b16b9d..cc59fa7 100644
--- a/core/abort.inc
+++ b/core/abort.inc
@@ -24,6 +24,10 @@
; assumes CS == DS
;
dot_pause:
+ push ax
+ mov al,5
+ call [comboot_hook]
+ pop ax
push si
mov si,dot_msg
call writestr_qchk
@@ -63,6 +67,8 @@ abort_check:
abort_load:
mov bx,error_or_command
abort_load_chain:
+ mov al,80h
+ call [comboot_hook] ; may not return
RESET_STACK_AND_SEGS AX
call writestr ; Expects SI -> error msg
diff --git a/core/comboot.inc b/core/comboot.inc
index cdba16d..ee3fd77 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -96,24 +96,23 @@ is_comboot_image:
shl ax,6 ; Kilobytes -> paragraphs
mov word [es:02h],ax
-%ifndef DEPEND
-%if real_mode_seg != comboot_seg
-%error "This code assumes real_mode_seg == comboot_seg"
-%endif
-%endif
; Copy the command line from high memory
+ push word real_mode_seg
+ pop ds
mov si,cmd_line_here
mov cx,125 ; Max cmdline len (minus space and CR)
mov di,081h ; Offset in PSP for command line
mov al,' ' ; DOS command lines begin with a space
stosb
-.loop: es lodsb
+.loop: lodsb
and al,al
jz .done
stosb
loop .loop
.done:
+ push cs
+ pop ds
mov al,0Dh ; CR after last character
stosb
@@ -963,6 +962,45 @@ comapi_shufraw:
mov ecx,P_ECX
jmp shuffle_and_boot_raw
+
+;
+; INT 22h AX=0025h Set current working directory
+;
+%if IS_ISOLINUX
+comapi_setcwd:
+ mov si,P_BX
+ mov di,TmpDirName
+ mov cx,FILENAME_MAX
+ mov ds,P_ES
+.copy:
+ lodsb
+ stosb
+ or al,al
+ loopnz .copy
+ push cs
+ pop ds
+ stc
+ jnz .err
+ mov di,TmpDirName
+ call setcwd
+.err:
+ ret
+%else
+comapi_setcwd equ comapi_err
+%endif
+
+
+;
+; INT 22h AX=0026h Read filesystem meta data
+;
+%if IS_ISOLINUX
+comapi_mount:
+; call iso_mount
+ ret
+%else
+comapi_mount equ comapi_err
+%endif
+
section .data
%macro int21 2
@@ -970,6 +1008,88 @@ comapi_shufraw:
dw %2
%endmacro
+
+;
+; INT 22h AX=0027h Run command, return on error
+;
+; Terminates the COMBOOT program and executes the command line in
+; ES:BX as if it had been entered by the user.
+; CS:SI: comboot callback (via far call)
+; EDI kernel load address
+;
+comapi_run2:
+ push word P_CS
+ push word P_SI
+ pop dword [comboot_far]
+ push dword P_EDI
+ pop dword [KernelStart]
+ mov ds,P_ES
+ mov si,P_BX
+ mov di,command_line
+ call strcpy
+ push cs
+ pop ds
+ push cs
+ pop es
+ mov [comboot_sp_save],sp ; save stack pointer
+ mov word [comboot_hook],comboot_hook_entry
+ or byte [QuietBoot],2
+ jmp load_kernel ; Run a new kernel
+
+comapi_run2_cont:
+ mov word [comboot_hook],comboot_hook_nop
+ mov sp,[comboot_sp_save] ; fix stack pointer
+ and byte [QuietBoot],~2
+ clc
+ ret
+
+;
+; Callback function used at various places during kernel/initrd loading.
+;
+; The function either returns or continues at comapi_run2_cont.
+;
+; AL:
+; bit 7: 0/1 return/don't return
+; bit 0-6: function code
+; 0: abort kernel/initrd loading
+; 1: kernel/initrd not found
+; 2: kernel corrupt
+; 3: out of memory (while initrd loading)
+; 4: progress start
+; 5: progress increment
+; 6: progress end: kernel loaded, stop gfxboot
+;
+comboot_hook_entry:
+ pushad
+ push gs
+ push fs
+ push es
+ push ds
+ call far [comboot_far]
+ pop ds
+ pop es
+ pop fs
+ pop gs
+ popad
+ pushad
+ and al,7fh
+ cmp al,6
+ jnz .notlast
+ push es
+ mov si,DOSSaveVectors
+ mov di,4*20h
+ mov cx,20h
+ push word 0
+ pop es
+ rep movsd ; Restore DOS-range vectors
+ pop es
+.notlast:
+ popad
+ test al,80h
+ jnz comapi_run2_cont
+comboot_hook_nop:
+ ret
+
int21_table:
int21 00h, comboot_return
int21 01h, comboot_getkey
@@ -1022,8 +1142,15 @@ int22_table:
dw comapi_closedir ; 0022 close directory
dw comapi_shufsize ; 0023 query shuffler size
dw comapi_shufraw ; 0024 cleanup, shuffle and boot raw
+ dw comapi_setcwd ; 0025 set current working directory
+ dw comapi_mount ; 0026 read fs structures (aka mount)
+ dw comapi_run2 ; 0027 like 0003, but return on error
int22_count equ ($-int22_table)/2
+comboot_sp_save dw 0
+comboot_hook dw comboot_hook_nop
+comboot_far dd 0
+
APIKeyWait db 0
APIKeyFlag db 0
@@ -1042,8 +1169,9 @@ feature_flags_len equ ($-feature_flags)
err_notdos db ': attempted DOS system call INT ',0
err_comlarge db 'COMBOOT image too large.', CR, LF, 0
- section .bss1
+ section .bss2
alignb 4
DOSErrTramp resd 33 ; Error trampolines
+TmpDirName resb FILENAME_MAX
ConfigName resb FILENAME_MAX
CurrentDirName resb FILENAME_MAX
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 2627c2d..a0910fb 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -1135,73 +1135,23 @@ all_read:
; (which will be at 16 only for a single-session disk!); from the PVD
; we should be able to find the rest of what we need to know.
;
-get_fs_structures:
- mov eax,[bi_pvd]
- mov bx,trackbuf
- call getonesec
-
- mov eax,[trackbuf+156+2]
- mov [RootDir+dir_lba],eax
- mov [CurrentDir+dir_lba],eax
-%ifdef DEBUG_MESSAGES
- mov si,dbg_rootdir_msg
- call writemsg
- call writehex8
- call crlf
-%endif
- mov eax,[trackbuf+156+10]
- mov [RootDir+dir_len],eax
- mov [CurrentDir+dir_len],eax
- add eax,SECTOR_SIZE-1
- shr eax,SECTOR_SHIFT
- mov [RootDir+dir_clust],eax
- mov [CurrentDir+dir_clust],eax
-
- ; Look for an isolinux directory, and if found,
- ; make it the current directory instead of the root
- ; directory.
- ; Also copy the name of the directory to CurrentDirName
- mov word [CurrentDirName],ROOT_DIR_WORD ; Write '/',0 to the CurrentDirName
+ call iso_mount
mov di,boot_dir ; Search for /boot/isolinux
- mov al,02h
- push di
- call searchdir_iso
- pop di
- jnz .found_dir
- mov di,isolinux_dir
- mov al,02h ; Search for /isolinux
- push di
- call searchdir_iso
- pop di
- jz .no_isolinux_dir
+ call setcwd
+ jnc .found_dir
+ mov di,isolinux_dir ; Search for /isolinux
+ call setcwd
.found_dir:
- ; Copy current directory name to CurrentDirName
- push si
- push di
- mov si,di
- mov di,CurrentDirName
- call strcpy
- mov byte [di],0 ;done in case it's not word aligned
- dec di
- mov byte [di],'/'
- pop di
- pop si
- mov [CurrentDir+dir_len],eax
- mov eax,[si+file_left]
- mov [CurrentDir+dir_clust],eax
- xor eax,eax ; Free this file pointer entry
- xchg eax,[si+file_sector]
- mov [CurrentDir+dir_lba],eax
%ifdef DEBUG_MESSAGES
push si
mov si,dbg_isodir_msg
call writemsg
pop si
+ mov eax,[CurrentDir+dir_lba]
call writehex8
call crlf
%endif
-.no_isolinux_dir:
;
; Locate the configuration file
@@ -1706,6 +1656,90 @@ getfssec:
TRACER 'f'
ret
+;
+; setcwd: Set current working directory.
+;
+; On entry:
+; DI -> directory name
+; On exit:
+; CF = 1 -> error
+;
+; On error, the old working directory is kept.
+;
+setcwd:
+ mov al,02h
+ push di
+ call searchdir_iso
+ pop di
+ stc
+ jz .err
+ mov [CurrentDir+dir_len],eax
+ mov eax,[si+file_left]
+ mov [CurrentDir+dir_clust],eax
+ xor eax,eax
+ xchg eax,[si+file_sector]
+ mov [CurrentDir+dir_lba],eax
+ mov si,di
+ mov di,CurrentDirName
+ cmp si,di
+ jz .ok
+ mov cx,FILENAME_MAX
+ push ds
+ pop es
+.copy:
+ lodsb
+ stosb
+ or al,al
+ loopnz .copy
+ mov byte [di-1],0
+ jnz .err
+.ok:
+ clc
+.err:
+ ret
+
+;
+; Read fs meta data and setup RootDir and CurrentDir.
+;
+; On exit:
+; CF = 1 -> error
+;
+iso_mount:
+ mov eax,[bi_pvd]
+ mov bx,trackbuf
+ call getonesec
+
+ mov eax,[trackbuf+156+10]
+ mov [RootDir+dir_len],eax
+ add eax,SECTOR_SIZE-1
+ shr eax,SECTOR_SHIFT
+ mov [RootDir+dir_clust],eax
+ mov eax,[trackbuf+156+2]
+ mov [RootDir+dir_lba],eax
+
+ push ds
+ pop es
+ mov si,RootDir
+ mov di,CurrentDir
+ mov cx,dir_t_size
+ rep movsb
+
+%ifdef DEBUG_MESSAGES
+ mov si,dbg_rootdir_msg
+ call writemsg
+ call writehex8
+ call crlf
+%endif
+
+ mov di,CurrentDirName
+ call setcwd
+ jnc .ok
+ mov word [CurrentDirName],ROOT_DIR_WORD
+.ok:
+ clc
+ ret
+
+
; -----------------------------------------------------------------------------
; Common modules
; -----------------------------------------------------------------------------
diff --git a/core/layout.inc b/core/layout.inc
index 8c2e248..ca95d2b 100644
--- a/core/layout.inc
+++ b/core/layout.inc
@@ -123,4 +123,4 @@ real_mode_seg equ cache_seg + 1000h
pktbuf_seg equ cache_seg ; PXELINUX packet buffers
%endif
-comboot_seg equ real_mode_seg ; COMBOOT image loading zone
+comboot_seg equ real_mode_seg + 1000h ; COMBOOT image loading zone
diff --git a/core/loadhigh.inc b/core/loadhigh.inc
index 8ff9da1..91061fc 100644
--- a/core/loadhigh.inc
+++ b/core/loadhigh.inc
@@ -101,6 +101,8 @@ load_high:
ret
.overflow: mov si,err_nohighmem
+ mov al,83h
+ call [comboot_hook] ; may not return
jmp abort_load
section .data
diff --git a/core/runkernel.inc b/core/runkernel.inc
index 8bfc8b8..0cd2488 100644
--- a/core/runkernel.inc
+++ b/core/runkernel.inc
@@ -165,7 +165,7 @@ opt_mem:
ret
opt_quiet:
- mov byte [QuietBoot],1
+ or byte [QuietBoot],1
ret
%if IS_PXELINUX
@@ -228,6 +228,8 @@ new_kernel:
mov [LoadFlags],al
any_kernel:
+ mov al,4
+ call [comboot_hook]
mov si,loading_msg
call writestr_qchk
mov si,KernelCName ; Print kernel name part of
@@ -257,7 +259,7 @@ read_kernel:
mov ecx,8000h ; 32K
sub ecx,esi ; Number of bytes to copy
add esi,(real_mode_seg << 4) ; Pointer to source
- mov edi,100000h ; Copy to address 100000h
+ mov edi,[KernelStart] ; Copy to kernel address
call bcopy ; Transfer to high memory
@@ -319,6 +321,9 @@ load_initrd:
;
call abort_check ; Last chance!!
+ mov al,6
+ call [comboot_hook]
+
mov si,ready_msg
call writestr_qchk
@@ -426,7 +431,7 @@ setup_move:
mov eax,10000h ; Target address of low kernel
stosd
- mov eax,100000h ; Where currently loaded
+ mov eax,[KernelStart] ; Where currently loaded
stosd
neg eax
add eax,[KernelEnd]
@@ -434,9 +439,13 @@ setup_move:
inc cx
mov bx,9000h ; Revised real mode segment
+ jmp .loading_initrd
.loading_high:
+ mov eax,[KernelStart]
+ mov [fs:su_code32start],eax
+.loading_initrd:
cmp word [InitRDPtr],0 ; Did we have an initrd?
je .no_initrd
@@ -489,6 +498,8 @@ old_kernel:
xor ax,ax
cmp word [InitRDPtr],ax ; Old kernel can't have initrd
je .load
+ mov al,82h
+ call [comboot_hook] ; may not return
mov si,err_oldkernel
jmp abort_load
.load:
@@ -613,6 +624,8 @@ loadinitrd:
ret
.notthere:
+ mov al,81h
+ call [comboot_hook] ; may not return
mov si,err_noinitrd
call writestr
mov si,InitRDCName
@@ -625,7 +638,7 @@ loadinitrd:
; assumes CS == DS
;
writestr_qchk:
- test byte [QuietBoot],01h
+ test byte [QuietBoot],03h
jz writestr
ret
@@ -680,4 +693,9 @@ KernelVersion resw 1 ; Kernel protocol version
;
InitRDPtr resw 1 ; Pointer to initrd= option in command line
LoadFlags resb 1 ; Loadflags from kernel
-QuietBoot resb 1 ; Set if a quiet boot is requested
+
+ section .data
+QuietBoot db 0 ; Set if a quiet boot is requested
+ alignz 4
+KernelStart dd 100000h
+
diff --git a/core/ui.inc b/core/ui.inc
index 1b40717..2bc56a1 100644
--- a/core/ui.inc
+++ b/core/ui.inc
@@ -468,6 +468,8 @@ bad_kernel:
.really:
mov si,KernelName
mov di,KernelCName
+ mov al,81h
+ call [comboot_hook] ; may not return
push di
call unmangle_name ; Get human form
mov si,err_notfound ; Complain about missing kernel
@@ -510,7 +512,10 @@ on_error:
;
; kernel_corrupt: Called if the kernel file does not seem healthy
;
-kernel_corrupt: mov si,err_notkernel
+kernel_corrupt:
+ mov al,82h
+ call [comboot_hook] ; may not return
+ mov si,err_notkernel
jmp abort_load
;
@@ -591,7 +596,7 @@ kernel_good:
;
xor ax,ax
mov [InitRDPtr],ax
- mov [QuietBoot],al
+ and byte [QuietBoot],~1
%if IS_PXELINUX
mov [KeepPXE],al
%endif
diff --git a/doc/comboot.txt b/doc/comboot.txt
index f5fefda..9fe7f28 100644
--- a/doc/comboot.txt
+++ b/doc/comboot.txt
@@ -955,3 +955,12 @@ AX=0024h [3.80] Cleanup, shuffle and boot, raw version
with read/write data segments, matching the respective code
segment. For mode 0, B=0 and the limits will be 64K, for mode
1, B=1 and the limits will be 4 GB.
+
+
+AX=0025h [3.84] Set current working directory
+ Input: AX 00025h
+ ES:BX null-terminated directory name string
+ Output: None
+
+ Sets the current working directory. For SYSLINUX, ISOLINUX,
+ and PXELINUX, this will be an absolute path.
diff --git a/modules/gfxboot.asm b/modules/gfxboot.asm
index 5c7b118..7d1693f 100644
--- a/modules/gfxboot.asm
+++ b/modules/gfxboot.asm
@@ -179,6 +179,16 @@ input:
jmp input
boot:
+ mov ax,cs
+ mov es,ax
+ mov bx,command_line
+ mov si,syslinux_hook
+ mov edi,8 << 20 ; at 8MB
+ mov ax,27h
+ int 22h
+ jnc input
+
+ ; syslinux variant without function 27h
call far [gfx_bc_done]
mov ax,cs
mov es,ax
@@ -190,12 +200,77 @@ exit:
error:
ret
+sh_table: dw sh_abort ; 0
+ dw sh_not_found ; 1
+ dw sh_broken ; 2
+ dw sh_out_of_mem ; 3
+ dw sh_progress_start ; 4
+ dw sh_progress_inc ; 5
+ dw sh_progress_end ; 6
+sh_len equ ($-sh_table)/2
+
+;
+; Callback function used at various places in syslinux.
+;
+; Can modify all regs & sregs.
+;
+; AL:
+; bit 7: 0/1 return/don't return
+; bit 0-6: function code
+; 0: abort kernel/initrd loading
+; 1: kernel/initrd not found
+; 2: kernel corrupt
+; 3: out of memory (while initrd loading)
+; 4: progress start
+; 5: progress increment
+; 6: progress end: kernel loaded, stop gfxboot
+;
+syslinux_hook:
+ push cs
+ pop ds
+ and al,7fh
+ cmp al,sh_len
+ jae .end
+ movzx bx,al
+ add bx,bx
+ call word [bx+sh_table]
+.end:
+ retf
+
+sh_abort:
+ ret
+
+sh_not_found:
+ ret
+
+sh_broken:
+ ret
+
+sh_out_of_mem:
+ ret
+
+sh_progress_start:
+ call far [gfx_bc_progress_init]
+ ret
+
+sh_progress_inc:
+ mov eax,10000h ; chunk size
+ call far [gfx_bc_progress_update]
+ ret
+
+sh_progress_end:
+ call far [gfx_bc_progress_done]
+ call far [gfx_bc_done]
+ ret
+
+
cb_table dw cb_status ; 0
dw cb_fopen ; 1
dw cb_fread ; 2
dw cb_getcwd ; 3
dw cb_chdir ; 4
dw cb_readsector ; 5
+ dw cb_mount ; 6
cb_len equ ($-cb_table)/2
gfx_cb:
@@ -291,16 +366,25 @@ cb_fread_end:
; edx filename
;
cb_getcwd:
- mov edx,cs
+ mov ax,1fh
+ int 22h
+ mov edx,es
+ movzx ebx,bx
shl edx,4
- add edx,gfx_slash
+ add edx,ebx
xor al,al
ret
; Set current working directory
;
cb_chdir:
- xor al,al
+ push cs
+ pop es
+ mov bx,fname_buf
+ mov ax,25h
+ int 22h
+ mov al,0
+ adc al,0
ret
; Read sector
@@ -334,6 +418,17 @@ cb_readsector:
cb_readsector_end:
ret
+; Read filesystem meta data.
+;
+; return:
+;
+cb_mount:
+ mov ax,26h
+ int 22h
+ mov al,0
+ adc al,0
+ ret
+
gfx_init:
mov ax,0e801h
xor bx,bx
@@ -358,11 +453,10 @@ mem_below_16mb:
shl eax,10
mov [gfx_bios_mem_size],eax
shr eax,20
- cmp ax,16
+ cmp ax,32
jb skip_extended
- mov word [gfx_xmem_0],88h ; 8MB at 8MB
- mov dword [gfx_save_area1],7f0000h ; 8MB-64k
+ mov word [gfx_xmem_0],017h ; 3MB at 16MB
skip_extended:
movzx ebx,word [gfx_mem_start_seg]
@@ -405,7 +499,37 @@ skip_extended:
mov [gfx_bc_menu_init],ax
mov [gfx_bc_menu_init+2],es
-; ...
+ mov ax,[es:bx+8]
+ mov [gfx_bc_infobox_init],ax
+ mov [gfx_bc_infobox_init+2],es
+
+ mov ax,[es:bx+10]
+ mov [gfx_bc_infobox_done],ax
+ mov [gfx_bc_infobox_done+2],es
+
+ mov ax,[es:bx+12]
+ mov [gfx_bc_progress_init],ax
+ mov [gfx_bc_progress_init+2],es
+
+ mov ax,[es:bx+14]
+ mov [gfx_bc_progress_done],ax
+ mov [gfx_bc_progress_done+2],es
+
+ mov ax,[es:bx+16]
+ mov [gfx_bc_progress_update],ax
+ mov [gfx_bc_progress_update+2],es
+
+ mov ax,[es:bx+18]
+ mov [gfx_bc_progress_limit],ax
+ mov [gfx_bc_progress_limit+2],es
+
+ mov ax,[es:bx+20]
+ mov [gfx_bc_password_init],ax
+ mov [gfx_bc_password_init+2],es
+
+ mov ax,[es:bx+22]
+ mov [gfx_bc_password_done],ax
+ mov [gfx_bc_password_done+2],es
mov esi,cs
shl esi,4
@@ -974,8 +1098,6 @@ msg_no_labels_defined db 'No labels defined in config file',0dh,0ah,0
msg_space db ' ',0
msg_crlf db 0dh,0ah,0
-gfx_slash db '/', 0
-db0 db 0
menu_timeout dd 100
keyword_text_label db 6,'label',0
@@ -1071,8 +1193,6 @@ gfx_mem_end_seg resw 1
alignb 4
gfx_mem resd 1 ; linear address
-gfx_save_area1 resd 1 ; 64k
-gfx_save_area1_used resb 1 ; != 0 if area1 is in use
alignb 4
; interface to loadable gfx extension (seg:ofs values)
@@ -1082,3 +1202,12 @@ gfx_bc_init resd 1
gfx_bc_done resd 1
gfx_bc_input resd 1
gfx_bc_menu_init resd 1
+gfx_bc_infobox_init resd 1
+gfx_bc_infobox_done resd 1
+gfx_bc_progress_init resd 1
+gfx_bc_progress_done resd 1
+gfx_bc_progress_update resd 1
+gfx_bc_progress_limit resd 1
+gfx_bc_password_init resd 1
+gfx_bc_password_done resd 1
+