From ab5e5dd0a017e95cde09cf6becd31c511ef65f07d704cecae6a5fc9a551e5cda Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Mon, 10 Aug 2009 14:27:07 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/syslinux?expand=0&rev=15 --- syslinux-3.82-gfxboot.diff | 2837 +++++++---------------------------- syslinux-3.82-s_herbst.diff | 237 +++ syslinux.changes | 5 - syslinux.spec | 15 +- 4 files changed, 749 insertions(+), 2345 deletions(-) create mode 100644 syslinux-3.82-s_herbst.diff diff --git a/syslinux-3.82-gfxboot.diff b/syslinux-3.82-gfxboot.diff index bb706af..af7c54c 100644 --- a/syslinux-3.82-gfxboot.diff +++ b/syslinux-3.82-gfxboot.diff @@ -1,3 +1,223 @@ +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 @@ -173,30 +393,16 @@ index 2627c2d..a0910fb 100644 ; ----------------------------------------------------------------------------- ; Common modules ; ----------------------------------------------------------------------------- -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/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 @@ -211,9 +417,18 @@ index 8ff9da1..91061fc 100644 section .data diff --git a/core/runkernel.inc b/core/runkernel.inc -index 8bfc8b8..f458fc7 100644 +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 @@ -223,6 +438,15 @@ index 8bfc8b8..f458fc7 100644 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!! @@ -233,7 +457,30 @@ index 8bfc8b8..f458fc7 100644 mov si,ready_msg call writestr_qchk -@@ -489,6 +494,8 @@ old_kernel: +@@ -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 @@ -242,7 +489,7 @@ index 8bfc8b8..f458fc7 100644 mov si,err_oldkernel jmp abort_load .load: -@@ -613,6 +620,8 @@ loadinitrd: +@@ -613,6 +624,8 @@ loadinitrd: ret .notthere: @@ -251,8 +498,28 @@ index 8bfc8b8..f458fc7 100644 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..be4f385 100644 +index 1b40717..2bc56a1 100644 --- a/core/ui.inc +++ b/core/ui.inc @@ -468,6 +468,8 @@ bad_kernel: @@ -276,85 +543,7 @@ index 1b40717..be4f385 100644 jmp abort_load ; -diff --git a/core/comboot.inc b/core/comboot.inc -index cdba16d..1a1dbfe 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 -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/runkernel.inc b/core/runkernel.inc -index f458fc7..f6ed644 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 -@@ -634,7 +634,7 @@ loadinitrd: - ; assumes CS == DS - ; - writestr_qchk: -- test byte [QuietBoot],01h -+ test byte [QuietBoot],03h - jz writestr - ret - -@@ -689,4 +689,6 @@ 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 -diff --git a/core/ui.inc b/core/ui.inc -index be4f385..2bc56a1 100644 ---- a/core/ui.inc -+++ b/core/ui.inc -@@ -596,7 +596,7 @@ kernel_good: +@@ -591,7 +596,7 @@ kernel_good: ; xor ax,ax mov [InitRDPtr],ax @@ -363,288 +552,11 @@ index be4f385..2bc56a1 100644 %if IS_PXELINUX mov [KeepPXE],al %endif -diff --git a/core/runkernel.inc b/core/runkernel.inc -index f6ed644..286c9c8 100644 ---- a/core/runkernel.inc -+++ b/core/runkernel.inc -@@ -259,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 - -@@ -431,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] -@@ -439,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 - -@@ -692,3 +696,5 @@ LoadFlags resb 1 ; Loadflags from kernel - - section .data - QuietBoot db 0 ; Set if a quiet boot is requested -+ alignz 4 -+KernelStart dd 100000h -diff --git a/core/comboot.inc b/core/comboot.inc -index 1a1dbfe..ee3fd77 100644 ---- a/core/comboot.inc -+++ b/core/comboot.inc -@@ -962,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 -@@ -969,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 -@@ -1021,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 - -@@ -1041,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/comboot.inc b/core/comboot.inc -index ee3fd77..a11b15b 100644 ---- a/core/comboot.inc -+++ b/core/comboot.inc -@@ -1034,12 +1034,14 @@ comapi_run2: - mov [comboot_sp_save],sp ; save stack pointer - mov word [comboot_hook],comboot_hook_entry - or byte [QuietBoot],2 -+ mov byte [comboot_run2_active],1 - 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 -+ mov byte [comboot_run2_active],0 - clc - ret - -@@ -1150,6 +1152,7 @@ int22_count equ ($-int22_table)/2 - comboot_sp_save dw 0 - comboot_hook dw comboot_hook_nop - comboot_far dd 0 -+comboot_run2_active db 0 - - APIKeyWait db 0 - APIKeyFlag db 0 -diff --git a/core/ui.inc b/core/ui.inc -index 2bc56a1..59b5724 100644 ---- a/core/ui.inc -+++ b/core/ui.inc -@@ -379,9 +379,13 @@ vk_check: - push word real_mode_seg - pop es - mov di,cmd_line_here -+ ; append line already included in this case -+ cmp byte [comboot_run2_active],0 -+ jnz .no_append_copy - mov si,VKernelBuf+vk_append - mov cx,[VKernelBuf+vk_appendlen] - rep movsb -+.no_append_copy: - mov [CmdLinePtr],di ; Where to add rest of cmd - pop es - mov di,KernelName -diff --git a/core/comboot.inc b/core/comboot.inc -index a11b15b..b40c4ae 100644 ---- a/core/comboot.inc -+++ b/core/comboot.inc -@@ -1067,6 +1067,7 @@ comboot_hook_entry: - push fs - push es - push ds -+ mov ecx,[KernelSize] - call far [comboot_far] - pop ds - pop es -diff --git a/core/ui.inc b/core/ui.inc -index 59b5724..02c17ff 100644 ---- a/core/ui.inc -+++ b/core/ui.inc -@@ -633,6 +633,7 @@ kernel_good: - ; At this point, EAX contains the size of the kernel, SI contains - ; the file handle/cluster pointer, and ECX contains the extension (if any.) - ; -+ mov [KernelSize],eax - movzx di,byte [KernelType] - add di,di - jmp [kerneltype_table+di] diff --git a/doc/comboot.txt b/doc/comboot.txt -index f5fefda..f4ea31b 100644 +index f5fefda..9fe7f28 100644 --- a/doc/comboot.txt +++ b/doc/comboot.txt -@@ -955,3 +955,32 @@ AX=0024h [3.80] Cleanup, shuffle and boot, raw version +@@ -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. @@ -657,1978 +569,233 @@ index f5fefda..f4ea31b 100644 + + Sets the current working directory. For SYSLINUX, ISOLINUX, + and PXELINUX, this will be an absolute path. -+ -+ -+AX=0026h [3.84] Read file system metadata [ISOLINUX] -+ Input: AX 00026h -+ Output: None -+ -+ Reads filesystem data (e.g. after a CDROM change). -+ -+ -+AX=0027h [3.84] Run command -+ Input: AX 0027h -+ ES:BX null-terminated command string -+ SI comboot callback function (called via far call) -+ EDI kernel load address -+ Output: Does not return if the kernel loads correctly. -+ -+ Executes the command line as if it had been entered by the user. -+ Note that this function does return (with CF = 0) if there are -+ problems or the user aborted the load. Else it terminates the -+ COMBOOT program and starts the kernel. -diff --git a/modules/Makefile b/modules/Makefile -index 80eb995..65661a4 100644 ---- a/modules/Makefile -+++ b/modules/Makefile -@@ -19,6 +19,11 @@ include $(topdir)/MCONFIG.embedded +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 - INCLUDES = -I$(com32)/include - -+CFLAGS_COM = -O2 -Wall -Wno-pointer-sign -fomit-frame-pointer -m32 -march=i386 \ -+ -fno-align-functions -fno-align-labels -fno-align-jumps -fno-align-loops \ -+ -fno-builtin -nostdinc -I . -+ASMFLAGS_COM = -O99 -felf -+ - BINS = pxechain.com gfxboot.com poweroff.com - - all: $(BINS) -@@ -49,6 +54,15 @@ $(LIB): $(LIBOBJS) - %.ppm.gz: %.png - $(PNGTOPNM) $< | gzip -9 > $@ - -+libio.o: libio.asm -+ nasm $(ASMFLAGS_COM) -o $@ -l $*.lst $< -+ -+gfxboot.o: gfxboot.c libio.h -+ $(CC) -g $(CFLAGS_COM) -c -o $@ $< -+ -+gfxboot.com: gfxboot.o libio.o -+ ld -M -Tcom.ld -o $@ $^ >$*.map -+ - tidy dist: - rm -f *.o *.a *.lst *.elf *.map .*.d - -diff --git a/modules/com.ld b/modules/com.ld -new file mode 100644 -index 0000000..a98f9aa ---- /dev/null -+++ b/modules/com.ld -@@ -0,0 +1,16 @@ -+/* -+ linker script for DOS program (.COM) -+ */ -+ -+OUTPUT_FORMAT("binary") -+OUTPUT_ARCH(i386) -+SEARCH_DIR(".") -+ENTRY(_start) -+SECTIONS -+{ -+ .init 0x100 : { *(.init) } -+ .text : { *(.text) } -+ .rodata : { *(.rodata*) } -+ .data : { *(.data) } -+ .bss : { __bss_start = .; *(.bss) } -+} -diff --git a/modules/gfxboot.c b/modules/gfxboot.c -new file mode 100644 -index 0000000..6b0d300 ---- /dev/null -+++ b/modules/gfxboot.c -@@ -0,0 +1,898 @@ -+/* -+ * -+ * gfxboot.c -+ * -+ * A comboot program to load gfxboot graphics. -+ * -+ * It is based on work done by Sebastian Herbszt in gfxboot.asm. -+ * -+ * Copyright (c) 2009 Steffen Winterfeldt. -+ * -+ * 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 the -+ * Free Software Foundation, Inc., 53 Temple Place Ste 330, Boston MA -+ * 02111-1307, USA; either version 2 of the License, or (at your option) any -+ * later version; incorporated herein by reference. -+ * -+ */ -+ -+#include -+ -+#define ID_SYSLINUX 0x31 -+#define ID_PXELINUX 0x32 -+#define ID_ISOLINUX 0x33 -+#define ID_EXTLINUX 0x34 -+ -+#define MAX_CONFIG_LINE_LEN 2048 -+#define MAX_CMDLINE_LEN 1024 -+ -+#define GFX_BC_INIT 0 -+#define GFX_BC_DONE 1 -+#define GFX_BC_INPUT 2 -+#define GFX_BC_MENU_INIT 3 -+#define GFX_BC_INFOBOX_INIT 4 -+#define GFX_BC_INFOBOX_DONE 5 -+#define GFX_BC_PROGRESS_INIT 6 -+#define GFX_BC_PROGRESS_DONE 7 -+#define GFX_BC_PROGRESS_UPDATE 8 -+#define GFX_BC_PROGRESS_LIMIT 9 // unused -+#define GFX_BC_PASSWORD_INIT 10 -+#define GFX_BC_PASSWORD_DONE 11 -+ -+// for now, static values -+#define MENU_LABEL_SIZE 128 -+#define MENU_ARG_SIZE 512 -+#define MENU_ENTRY_SIZE (MENU_LABEL_SIZE + MENU_ARG_SIZE) -+// entry 0 is reserved for the default entry -+#define MAX_MENU_ENTRIES (0x10000 / MENU_ENTRY_SIZE) -+ -+ -+typedef struct { -+ uint16_t handle; -+ uint16_t block_size; -+ int file_size; // file size (-1: unknown) -+ uint32_t buf; // must be block_size -+ unsigned buf_size; // in block_size units -+ unsigned data_len; // valid bytes in buf -+ unsigned buf_idx; // read pos in buffer -+} fd_t; -+ -+ -+// gfx config data (52 bytes) -+typedef struct __attribute__ ((packed)) { -+ uint8_t bootloader; // 0: boot loader type (0: lilo, 1: syslinux, 2: grub) -+ uint8_t sector_shift; // 1: sector shift -+ uint8_t media_type; // 2: media type (0: disk, 1: floppy, 2: cdrom) -+ uint8_t failsafe; // 3: turn on failsafe mode (bitmask) -+ // 0: SHIFT pressed -+ // 1: skip gfxboot -+ // 2: skip monitor detection -+ uint8_t sysconfig_size; // 4: size of sysconfig data -+ uint8_t boot_drive; // 5: BIOS boot drive -+ uint16_t callback; // 6: offset to callback handler -+ uint16_t bootloader_seg; // 8: code/data segment used by bootloader; must follow gfx_callback -+ uint16_t reserved_1; // 10 -+ uint32_t user_info_0; // 12: data for info box -+ uint32_t user_info_1; // 16: data for info box -+ uint32_t bios_mem_size; // 20: BIOS memory size (in bytes) -+ uint16_t xmem_0; // 24: extended mem area 0 (start:size in MB; 12:4 bits) -+ uint16_t xmem_1; // 26: extended mem area 1 -+ uint16_t xmem_2; // 28: extended mem area 2 -+ uint16_t xmem_3; // 30: extended mem area 3 -+ uint32_t file; // 32: start of gfx file -+ uint32_t archive_start; // 36: start of cpio archive -+ uint32_t archive_end; // 40: end of cpio archive -+ uint32_t mem0_start; // 44: low free memory start -+ uint32_t mem0_end; // 48: low free memory end -+} gfx_config_t; -+ -+ -+// menu description (18 bytes) -+typedef struct __attribute__ ((packed)) { -+ uint16_t entries; -+ uint32_t default_entry; // seg:ofs -+ uint32_t label_list; // seg:ofs -+ uint16_t label_size; -+ uint32_t arg_list; // seg:ofs -+ uint16_t arg_size; -+} menu_t; -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// global file descriptor, implicitly used by read(), getc(), fgets() -+fd_t fd; -+ -+gfx_config_t gfx_config; -+menu_t menu; -+ -+struct { -+ uint32_t jmp_table[12]; -+ uint16_t code_seg; -+ char fname_buf[64]; -+} gfx; -+ -+unsigned comboot, comboot_len; -+unsigned io_buf, io_buf_len; -+unsigned menu_buf, menu_buf_len; -+unsigned freemem, freemem_len; -+ -+int timeout; -+ -+char cmdline[MAX_CMDLINE_LEN]; -+char current_label[64]; -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ -+int open(char *name); -+int open32(uint32_t name); -+int read(void *buf, int size); -+int read32(uint32_t buf, int size); -+int getc(void); -+char *fgets(char *s, int size); -+ -+int strlen(char *s); -+int strcmp(char *s1, char *s2); -+char *skip_spaces(char *s); -+char *skip_nonspaces(char *s); -+void chop_line(char *s); -+ -+int atoi(char *s); -+ -+uint32_t get_config_file_name32(void); -+int read_config_file(void); -+ -+unsigned magic_ok(uint32_t buf); -+unsigned find_file(uint32_t buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len); -+ -+int gfx_init(char *file); -+void gfx_done(void); -+int gfx_input(void); -+int gfx_menu_init(void); -+ -+void gfx_infobox32(int type, uint32_t str1, uint32_t str2); -+void gfx_infobox(int type, char *str1, char *str2); -+ -+void boot(void); -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+int main(int argc, char **argv) -+{ -+ x86regs_t r; -+ uint8_t syslinux_id; -+ int menu_index; -+ -+ r.eax = 0x0a; // Get Derivative-Specific Information -+ r.ecx = 9; -+ x86int(0x22, &r); -+ syslinux_id = (uint8_t) r.eax; -+ gfx_config.sector_shift = (uint8_t) r.ecx; -+ gfx_config.boot_drive = (uint8_t) r.edx; -+ -+ // define our memory layout -+ // all must be at least 16 bytes aligned -+ -+ // 64k comboot code -+ comboot = comboot_seg() << 4; -+ comboot_len = 0x10000; -+ -+ // 16k file io buffer -+ io_buf = comboot + comboot_len; -+ io_buf_len = 0x4000; -+ -+ // 64k for parsed menu data -+ menu_buf = io_buf + io_buf_len; -+ menu_buf_len = 0x10000; -+ -+ // use remaining mem for gfx core -+ freemem = menu_buf + menu_buf_len; -+ // comboot api passes low memory end at address 2 -+ freemem_len = ((*(uint16_t *) 2) << 4) - freemem; -+ -+ -+ gfx_config.bootloader = 1; -+ gfx_config.sysconfig_size = sizeof gfx_config; -+ gfx_config.bootloader_seg = comboot >> 4; -+ -+ // not gfx_cb() directly, we need a wrapper -+ gfx_config.callback = (uint32_t) _gfx_cb; -+ -+ if(syslinux_id == ID_PXELINUX) { -+ gfx_config.sector_shift = 11; -+ gfx_config.boot_drive = 0; -+ } -+ -+ if(argc != 2) { -+ printf("Usage: gfxboot.com \n"); -+ return 0; -+ } -+ -+ if(read_config_file()) { -+ printf("Error reading config file\n"); -+ return 0; -+ } -+ -+ if(gfx_init(argv[1])) { -+ printf("Error setting up gfxboot\n"); -+ return 0; -+ } -+ -+ gfx_menu_init(); -+ -+ for(;;) { -+ menu_index = gfx_input(); -+ -+ // abort gfx, return to text mode prompt -+ if(menu_index == -1) { -+ gfx_done(); -+ break; -+ } -+ -+ // get label name, is needed later for messages etc. -+ memcpy(current_label, cmdline, sizeof current_label); -+ current_label[sizeof current_label - 1] = 0; -+ *skip_nonspaces(current_label) = 0; -+ -+ // does not return if it succeeds -+ boot(); -+ } -+ -+ return 0; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// -+// return: -+// 0: ok, -1: error -+// -+int open32(uint32_t name) -+{ -+ x86regs_t r; -+ -+ fd.handle = 0; -+ fd.data_len = fd.buf_idx = 0; -+ -+ r.esi = name & 0xf; -+ r.eax = 0x06; // Open file -+ r.es = name >> 4; -+ x86int(0x22, &r); -+ -+ fd.block_size = r.ecx; -+ fd.file_size = r.eax; -+ -+ if( -+ (r.eflags & X86_CF) || -+ !fd.file_size || !fd.block_size || fd.block_size > io_buf_len -+ ) return -1; -+ -+ fd.handle = r.esi; -+ -+ fd.buf = io_buf; -+ fd.buf_size = io_buf_len / fd.block_size; -+ -+ // printf("block size = 0x%x, file size = %d\n", fd.block_size, fd.file_size); -+ -+ return 0; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// -+// return: -+// 0: ok, -1: error -+// -+int open(char *name) -+{ -+ return open32((uint32_t) name + comboot); -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// -+// Note: buf is 32bit address -+// -+int read32(uint32_t buf, int size) -+{ -+ x86regs_t r; -+ int i, len = 0; -+ -+ while(size) { -+ i = fd.data_len - fd.buf_idx; -+ -+ if(i > 0) { -+ i = i < size ? i : size; -+ memcpy32(buf, fd.buf + fd.buf_idx, i); -+ len += i; -+ buf += i; -+ size -= i; -+ fd.buf_idx += i; -+ } -+ -+ if(!size || !fd.handle) break; -+ -+ r.eax = 0x07; // Read file -+ r.ecx = fd.buf_size; -+ r.ebx = 0; -+ r.es = fd.buf >> 4; -+ r.esi = fd.handle; -+ x86int(0x22, &r); -+ fd.handle = r.esi; -+ fd.data_len = r.ecx; -+ fd.buf_idx = 0; -+ } -+ -+ return len; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+int read(void *buf, int size) -+{ -+ return read32((uint32_t) buf + comboot, size); -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+int getc() -+{ -+ char buf[1]; -+ -+ return read(buf, 1) ? *buf : EOF; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+char *fgets(char *s, int size) -+{ -+ char *buf = s; -+ int c = EOF; -+ -+ while(size--) { -+ c = getc(); -+ if(c == EOF) break; -+ *buf++ = c; -+ if(c == 0x0a) break; -+ } -+ -+ *buf = 0; -+ -+ return c == EOF && s == buf ? 0 : s; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+int strlen(char *s) -+{ -+ char *s0 = s + 1; -+ -+ while(*s++); -+ -+ return s - s0; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+int strcmp(char *s1, char *s2) -+{ -+ while(*s1 && *s1 == *s2) s1++, s2++; -+ -+ return (uint8_t) *s1 - (uint8_t) *s2; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+char *skip_spaces(char *s) -+{ -+ while(*s && (*s == ' ' || *s == '\t')) s++; -+ -+ return s; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+char *skip_nonspaces(char *s) -+{ -+ while(*s && *s != ' ' && *s != '\t') s++; -+ -+ return s; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+void chop_line(char *s) -+{ -+ int i = strlen(s); -+ -+ if(!i) return; -+ -+ while(--i >= 0) { -+ if(s[i] == ' ' || s[i] == '\t' || s[i] == '\n') { -+ s[i] = 0; -+ } -+ else { -+ break; -+ } -+ } -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+int atoi(char *s) -+{ -+ int i = 0, sign = 1; -+ -+ if(*s == '-') s++, sign = -1; -+ if(*s == '+') s++; -+ -+ while(*s >= '0' && *s <= '9') { -+ i = 10 * i + *s++ - '0'; -+ } -+ -+ return sign * i; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// -+// return: -+// config file name (32 bit address) -+// -+uint32_t get_config_file_name32() -+{ -+ x86regs_t r; -+ -+ r.eax = 0x0e; // Get configuration file name -+ x86int(0x22, &r); -+ -+ return (r.es << 4) + (uint16_t) r.ebx; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// Read and parse syslinux config file. -+// -+// return: -+// 0: ok, 1: error -+// -+int read_config_file(void) -+{ -+ char *s, *t, buf[MAX_CONFIG_LINE_LEN]; -+ unsigned u; -+ int menu_idx = 0; -+ -+ // clear memory before we start -+ memset32(menu_buf, 0, menu_buf_len); -+ -+ if(open32(get_config_file_name32()) == -1) return 1; -+ -+ while((s = fgets(buf, sizeof buf))) { -+ chop_line(s); -+ s = skip_spaces(s); -+ if(!*s || *s == '#') continue; -+ t = skip_nonspaces(s); -+ if(*t) *t++ = 0; -+ t = skip_spaces(t); -+ -+ if(!strcmp(s, "timeout")) { -+ timeout = atoi(t); -+ } -+ -+ if(!strcmp(s, "default")) { -+ u = strlen(t); -+ if(u > MENU_LABEL_SIZE - 1) u = MENU_LABEL_SIZE - 1; -+ memcpy32(menu_buf, comboot + (uint32_t) t, u); -+ } -+ -+ if(!strcmp(s, "label")) { -+ menu_idx++; -+ if(menu_idx < MAX_MENU_ENTRIES) { -+ u = strlen(t); -+ if(u > MENU_LABEL_SIZE - 1) u = MENU_LABEL_SIZE - 1; -+ memcpy32( -+ menu_buf + menu_idx * MENU_LABEL_SIZE, -+ comboot + (uint32_t) t, -+ u -+ ); -+ } -+ } -+ -+ if(!strcmp(s, "append")) { -+ if(menu_idx < MAX_MENU_ENTRIES) { -+ u = strlen(t); -+ if(u > MENU_ARG_SIZE - 1) u = MENU_ARG_SIZE - 1; -+ memcpy32( -+ menu_buf + menu_idx * MENU_ARG_SIZE + MAX_MENU_ENTRIES * MENU_LABEL_SIZE, -+ comboot + (uint32_t) t, -+ u -+ ); -+ } -+ } -+ } -+ -+ menu.entries = menu_idx; -+ menu.label_size = MENU_LABEL_SIZE; -+ menu.arg_size = MENU_ARG_SIZE; -+ menu.default_entry = ((menu_buf >> 4) << 16) + (menu_buf & 0xf); -+ u = menu_buf + MENU_LABEL_SIZE; -+ menu.label_list = ((u >> 4) << 16) + (u & 0xf); -+ u = menu_buf + MAX_MENU_ENTRIES * MENU_LABEL_SIZE + MENU_ARG_SIZE; -+ menu.arg_list = ((u >> 4) << 16) + (u & 0xf); -+ -+ return 0; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// Check header and return code start offset. -+// -+// Note: buf is 32bit address -+// -+unsigned magic_ok(uint32_t buf) -+{ -+ if( -+ _mem32(buf) == 0x0b2d97f00 && /* magic id */ -+ (_mem8(buf + 4) == 8) /* version 8 */ -+ ) { -+ return _mem32(buf + 8); -+ } -+ -+ return 0; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// -+// Search cpio archive for gfx file. -+// -+// Note: buf is 32bit address -+// -+unsigned find_file(uint32_t buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len) -+{ -+ unsigned i, fname_len, code_start = 0; -+ -+ *gfx_file_start = 0; -+ -+ for(i = 0; i < len;) { -+ if((len - i) >= 0x1a && _mem16(buf + i) == 0x71c7) { -+ fname_len = _mem16(buf + i + 20); -+ *file_len = _mem16(buf + i + 24) + (_mem16(buf + i + 22) << 16); -+ i += 26 + fname_len; -+ i = ((i + 1) & ~1); -+ if((code_start = magic_ok(buf + i))) { -+ *gfx_file_start = i; -+ return code_start; -+ } -+ i += *file_len; -+ i = ((i + 1) & ~1); -+ } -+ else { -+ break; -+ } -+ } -+ -+ return code_start; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+void gfx_cb(x86regs_t *r) -+{ -+ uint8_t f_nr = r->eax; -+ -+ switch(f_nr) { -+ case 0: // cb_status -+ // edx = filename buffer (64 bytes) -+ r->edx = comboot + (uint32_t) gfx.fname_buf; -+ r->eax = 0; -+ // printf("<0x%x, %p + 0x%x>", r->edx, gfx.fname_buf, comboot); -+ break; -+ -+ case 1: // cb_fopen -+ // file name in gfx.fname_buf -+ // al = 0: ok, 1: file not found -+ // ecx = file length (al = 0) -+ if(open(gfx.fname_buf) == -1) { -+ r->eax = 1; -+ } -+ else { -+ r->eax = 0; -+ r->ecx = fd.file_size; -+ } -+ break; -+ -+ case 2: // cb_fread -+ // edx = buffer address (linear) -+ // ecx = data length (< 64k) -+ if(!fd.handle) { -+ r->eax = r->ecx = 0; -+ break; -+ } -+ r->esi = fd.handle; -+ r->ebx = 0; -+ r->es = io_buf >> 4; -+ r->ecx = io_buf_len / fd.block_size; -+ r->eax = 7; -+ x86int(0x22, r); -+ fd.handle = r->esi; -+ if((r->eflags & X86_CF)) { -+ r->eax = 1; -+ } -+ else { -+ r->edx = io_buf; -+ r->eax = 0; -+ } -+ break; -+ -+ case 3: // cb_getcwd -+ // edx filename -+ r->eax = 0x1f; // Get current working directory -+ x86int(0x22, r); -+ r->edx = (r->es << 4) + (uint16_t) r->ebx; -+ r->eax = 0; -+ break; -+ -+ case 4: // cb_chdir -+ r->es = comboot >> 4; -+ r->ebx = (uint32_t) gfx.fname_buf; -+ r->eax = 0x25; // Get current working directory -+ x86int(0x22, r); -+ break; -+ -+ case 5: // cb_readsector -+ // in: edx = sector -+ // out: edx = buffer (linear address) -+ r->esi = r->edi = 0; -+ r->ebx = 0; -+ r->es = io_buf >> 4; -+ r->ecx = 1; -+ r->eax = 0x19; // Read disk -+ x86int(0x22, r); -+ r->eax = 0; -+ r->edx = io_buf; -+ break; -+ -+ case 6: // cb_mount -+ r->eax = 0x26; -+ x86int(0x22, r); -+ r->eax = (r->eflags & X86_CF) ? 1 : 0; -+ break; -+ -+ default: -+ r->eax = 0xff; -+ } -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// -+// return: -+// 0: ok, 1: error -+// -+int gfx_init(char *file) -+{ -+ x86regs_t r; -+ -+ int file_max, file_size, ofs; -+ unsigned u, code_start, file_start = 0, file_len = 0; -+ -+ gfx_config.mem0_start = freemem; -+ gfx_config.mem0_end = freemem + freemem_len; -+ -+ gfx_config.bios_mem_size = 256 << 20; // fake -+ -+ gfx_config.xmem_0 = 0x17; // 7MB starting at 16MB -+ -+#if 0 -+ printf("mem = 0x%05x, mem0_start = 0x%05x, mem0_end = 0x%05x\n", -+ gfx.mem, gfx_config.mem0_start, gfx_config.mem0_end -+ ); -+#endif -+ -+ if(open(file) == -1) return 1; -+ -+ // leave room for later alignment -+ gfx_config.archive_start = gfx_config.mem0_start + 0x10; -+ -+ // read at most that much -+ file_size = file_max = gfx_config.mem0_end - gfx_config.archive_start; -+ -+ if(fd.file_size != -1 && fd.file_size > file_size) return 1; -+ -+ // if we have the real size, use it -+ if(fd.file_size != -1) file_size = fd.file_size; -+ -+ file_size = read32(gfx_config.archive_start, file_size); -+ -+ if(!file_size || file_size == file_max) return 1; -+ -+ gfx_config.archive_end = gfx_config.archive_start + file_size; -+ -+ // update free mem pointer & align it a bit -+ gfx_config.mem0_start = (gfx_config.archive_end + 3) & ~3; -+ -+ // locate file inside cpio archive -+ if(!(code_start = find_file(gfx_config.archive_start, file_size, &file_start, &file_len))) { -+ printf("%s: invalid file format\n", file); -+ -+ return 1; -+ } -+ -+#if 0 -+ printf("code_start = 0x%x, archive_start = 0x%x, file size = 0x%x, file_start = 0x%x, file_len = 0x%x\n", -+ code_start, gfx_config.archive_start, file_size, file_start, file_len -+ ); -+#endif -+ -+ if((ofs = (gfx_config.archive_start + file_start + code_start) & 0xf)) { -+ printf("oops: needs to be aligned!\n"); -+ -+ memcpy32(gfx_config.archive_start - ofs, gfx_config.archive_start, file_size); -+ gfx_config.archive_start -= ofs; -+ gfx_config.archive_end -= ofs; -+ -+ return 1; -+ } -+ -+ gfx_config.file = gfx_config.archive_start + file_start; -+ gfx.code_seg = (gfx_config.file + code_start) >> 4; -+ -+ for(u = 0; u < sizeof gfx.jmp_table / sizeof *gfx.jmp_table; u++) { -+ gfx.jmp_table[u] = (gfx.code_seg << 16) + _mem16(gfx_config.file + code_start + 2 * u); -+ } -+ -+#if 0 -+ for(u = 0; u < sizeof gfx.jmp_table / sizeof *gfx.jmp_table; u++) { -+ printf("%d: 0x%08x\n", u, gfx.jmp_table[u]); -+ } -+#endif -+ -+ // we are ready to start -+ -+ r.esi = comboot + (uint32_t) &gfx_config; -+ farcall(gfx.jmp_table[GFX_BC_INIT], &r); -+ -+ if((r.eflags & X86_CF)) { -+ printf("graphics initialization failed\n"); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+void gfx_done() -+{ -+ x86regs_t r; -+ -+ farcall(gfx.jmp_table[GFX_BC_DONE], &r); -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// -+// return: -+// boot menu index (-1: go to text mode prompt) -+// -+int gfx_input() -+{ -+ x86regs_t r; -+ -+ r.edi = comboot + (uint32_t) cmdline; -+ r.ecx = sizeof cmdline; -+ r.eax = timeout; -+ timeout = 0; // use timeout only first time -+ farcall(gfx.jmp_table[GFX_BC_INPUT], &r); -+ if((r.eflags & X86_CF)) r.eax = 1; -+ -+ if(r.eax == 1) return -1; -+ -+ return r.ebx; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+int gfx_menu_init() -+{ -+ x86regs_t r; -+ -+ r.esi = comboot + (uint32_t) &menu; -+ farcall(gfx.jmp_table[GFX_BC_MENU_INIT], &r); -+ -+ return 0; -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+void gfx_infobox(int type, char *str1, char *str2) -+{ -+ gfx_infobox32(type, comboot + (uint32_t) str1, str2 ? comboot + (uint32_t) str2 : 0); -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+void gfx_infobox32(int type, uint32_t str1, uint32_t str2) -+{ -+ x86regs_t r; -+ -+ r.eax = type; -+ r.esi = str1; -+ r.edi = str2; -+ farcall(gfx.jmp_table[GFX_BC_INFOBOX_INIT], &r); -+ r.edi = r.eax = 0; -+ farcall(gfx.jmp_table[GFX_BC_INPUT], &r); -+ farcall(gfx.jmp_table[GFX_BC_INFOBOX_DONE], &r); -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+// Load & run kernel. -+// -+// Returns only on error. -+// -+void boot() -+{ -+ x86regs_t r; -+ -+ r.es = comboot >> 4; -+ r.ebx = (uint32_t) cmdline; -+ r.edi = 8 << 20; // kernel load address: 8MB -+ r.esi = (uint32_t) _syslinux_hook; // cs:si = syslinux callbacks -+ r.eax = 0x27; // Load & run kernel (extended API) -+ x86int(0x22, &r); -+ if(!(r.eflags & X86_CF)) return; -+ -+ r.es = comboot >> 4; -+ r.ebx = (uint32_t) cmdline; -+ r.eax = 3; // Run command -+ x86int(0x22, &r); -+} -+ -+ -+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+void syslinux_hook(x86regs_t *r) -+{ -+ uint8_t f_nr = r->eax; -+ -+ // bit 7: 0/1 continue/don't continue kernel loading in syslinux -+ -+ switch(f_nr & 0x7f) { -+ case 0: // abort kernel/initrd loading -+ gfx_infobox(0, "abort kernel loading", 0); -+ break; -+ -+ case 1: // kernel/initrd not found -+ gfx_infobox(0, "kernel not found: ", current_label); -+ break; -+ -+ case 2: // kernel corrupt -+ gfx_infobox(0, "kernel broken", 0); -+ break; -+ -+ case 3: // out of memory (while initrd loading) -+ gfx_infobox(0, "out of memory", 0); -+ break; -+ -+ case 4: // progress start -+ r->eax = r->ecx >> gfx_config.sector_shift; // kernel size in sectors -+ r->eax = 0; -+ r->esi = comboot + (uint32_t) current_label; -+ farcall(gfx.jmp_table[GFX_BC_PROGRESS_INIT], r); -+ break; -+ -+ case 5: // progress increment -+ // always 64k -+ r->eax = 0x10000 >> gfx_config.sector_shift; -+ farcall(gfx.jmp_table[GFX_BC_PROGRESS_UPDATE], r); -+ break; -+ -+ case 6: // progress end: kernel loaded, stop gfxboot -+ farcall(gfx.jmp_table[GFX_BC_PROGRESS_DONE], r); -+ gfx_done(); -+ break; -+ } -+} -+ -+ -diff --git a/modules/libio.asm b/modules/libio.asm -new file mode 100644 -index 0000000..57bcde3 ---- /dev/null -+++ b/modules/libio.asm -@@ -0,0 +1,854 @@ -+; -+; libio.asm -+; -+; A very minimalistic libc fragment. -+; -+; Copyright (c) 2009 Steffen Winterfeldt. -+; -+; 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 the Free -+; Software Foundation, Inc., 53 Temple Place Ste 330, Boston MA 02111-1307, -+; USA; either version 2 of the License, or (at your option) any later -+; version; incorporated herein by reference. -+; -+ -+ -+; max argv elements passed to main() -+%define MAX_ARGS 8 -+ -+ -+ bits 16 -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; interface functions -+; -+; Make sure not to modify registers! -+; -+ -+ global printf -+ global getchar -+ global clrscr -+ global memcpy -+ global memcpy32 -+ global memset -+ global memset32 -+ global x86int -+ global farcall -+ global reboot -+ -+ global _gfx_cb -+ extern gfx_cb -+ global _syslinux_hook -+ extern syslinux_hook -+ -+ global _start -+ extern _main -+ -+ extern __bss_start -+ -+ section .init -+ -+_start: -+ cld -+ -+ ; clear static memory -+ mov di,__bss_start -+ mov cx,sp -+ sub cx,di -+ xor ax,ax -+ rep stosb -+ -+ ; parse args -+ mov bx,80h -+ movzx si,byte [bx] -+ mov byte [si+81h],0dh ; just make sure -+ xor ecx,ecx -+ sub sp,MAX_ARGS * 4 -+ mov ebp,esp -+ inc cx -+cmd_10: -+ inc bx -+ call skip_spaces -+ cmp al,0dh -+ jz cmd_60 -+ imul si,cx,4 -+ mov [bp+si],ebx -+ call skip_nonspaces -+ mov byte [bx],0 -+ inc cx -+ cmp cx,MAX_ARGS -+ jae cmd_60 -+ cmp al,0dh -+ jnz cmd_10 -+cmd_60: -+ mov byte [bx],0 -+ -+ mov [bp],ebx ; argv[0] = "" -+ -+ push ebp -+ push ecx -+ -+ call dword _main -+ -+ add sp,MAX_ARGS * 4 + 8 -+ -+ ret -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+skip_spaces: -+ mov al,[bx] -+ cmp al,0dh -+ jz skip_spaces_90 -+ cmp al,' ' -+ jz skip_spaces_10 -+ cmp al,9 -+ jnz skip_spaces_90 -+skip_spaces_10: -+ inc bx -+ jmp skip_spaces -+skip_spaces_90: -+ ret -+ -+skip_nonspaces: -+ mov al,[bx] -+ cmp al,0dh -+ jz skip_nonspaces_90 -+ cmp al,' ' -+ jz skip_nonspaces_90 -+ cmp al,9 -+ jz skip_nonspaces_90 -+ inc bx -+ jmp skip_nonspaces -+skip_nonspaces_90: -+ ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ section .text -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Write text to console. -+; -+; args on stack -+; -+; Note: 32 bit call/ret! -+; -+printf: -+ mov [pf_args],sp -+ -+ pushad -+ -+ call pf_next_arg -+ call pf_next_arg -+ mov si,ax -+printf_10: -+ lodsb -+ or al,al -+ jz printf_90 -+ cmp al,'%' -+ jnz printf_70 -+ mov byte [pf_pad],' ' -+ lodsb -+ dec si -+ cmp al,'0' -+ jnz printf_20 -+ mov [pf_pad],al -+printf_20: -+ call get_number -+ mov [pf_num],ecx -+ lodsb -+ or al,al -+ jz printf_90 -+ cmp al,'%' -+ jz printf_70 -+ -+ cmp al,'S' -+ jnz printf_23 -+ mov byte [pf_raw_char],1 -+ jmp printf_24 -+printf_23: -+ cmp al,'s' -+ jnz printf_30 -+printf_24: -+ push si -+ -+ call pf_next_arg -+ mov si,ax -+ call puts -+ -+ sub ecx,[pf_num] -+ neg ecx -+ mov al,' ' -+ call putc_n -+ -+ pop si -+ -+ mov byte [pf_raw_char],0 -+ jmp printf_10 -+ -+printf_30: -+ cmp al,'u' -+ jnz printf_35 -+ -+ mov dx,10 -+printf_31: -+ push si -+ -+ call pf_next_arg -+ or dh,dh -+ jz printf_34 -+ test eax,eax -+ jns printf_34 -+ neg eax -+ push eax -+ mov al,'-' -+ call putc -+ pop eax -+printf_34: -+ mov cl,[pf_num] -+ mov ch,[pf_pad] -+ call number -+ call puts -+ -+ pop si -+ -+ jmp printf_10 -+ -+printf_35: -+ cmp al,'x' -+ jnz printf_36 -+ -+printf_35a: -+ mov dx,10h -+ jmp printf_31 -+ -+printf_36: -+ cmp al,'d' -+ jnz printf_37 -+printf_36a: -+ mov dx,10ah -+ jmp printf_31 -+ -+printf_37: -+ cmp al,'i' -+ jz printf_36a -+ -+ cmp al,'p' -+ jnz printf_40 -+ mov al,'0' -+ call putc -+ mov al,'x' -+ call putc -+ jmp printf_35a -+ -+printf_40: -+ cmp al,'c' -+ jnz printf_45 -+ -+ push si -+ call pf_next_arg -+ call putc -+ pop si -+ jmp printf_10 -+printf_45: -+ -+ ; more ... -+ -+ -+printf_70: -+ call putc -+ jmp printf_10 -+printf_90: -+ popad -+ -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Get next printf arg from [pf_args]. -+; -+; return: -+; eax arg -+; -+; changes no regs -+; -+pf_next_arg: -+ movzx eax,word [pf_args] -+ add word [pf_args],4 -+ mov eax,[eax] -+ ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Convert string to number. -+; -+; si string -+; -+; return: -+; ecx number -+; si points past number -+; CF not a number -+; -+get_number: -+ -+ xor ecx,ecx -+ mov ah,1 -+get_number_10: -+ lodsb -+ or al,al -+ jz get_number_90 -+ sub al,'0' -+ jb get_number_90 -+ cmp al,9 -+ ja get_number_90 -+ movzx eax,al -+ imul ecx,ecx,10 -+ add ecx,eax -+ jmp get_number_10 -+get_number_90: -+ dec si -+ shr ah,1 -+ ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Convert a number to string. -+; -+; eax number -+; cl field size -+; ch padding char -+; dl base -+; -+; return: -+; si string -+; -+number: -+ mov di,num_buf -+ push ax -+ push cx -+ mov al,ch -+ mov cx,num_buf_end - num_buf -+ rep stosb -+ pop cx -+ pop ax -+ movzx cx,cl -+ movzx ebx,dl -+number_10: -+ xor edx,edx -+ div ebx -+ cmp dl,9 -+ jbe number_20 -+ add dl,27h -+number_20: -+ add dl,'0' -+ dec edi -+ mov [di],dl -+ or eax,eax -+ jz number_30 -+ cmp di,num_buf -+ ja number_10 -+number_30: -+ mov si,di -+ or cx,cx -+ jz number_90 -+ cmp cx,num_buf_end - num_buf -+ jae number_90 -+ mov si,num_buf_end -+ sub si,cx -+number_90: -+ ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Write string. -+; -+; si text -+; -+; return: -+; cx length -+; -+puts: -+ xor cx,cx -+puts_10: -+ lodsb -+ or al,al -+ jz puts_90 -+ call putc -+ inc cx -+ jmp puts_10 -+puts_90: -+ ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Write char multiple times. -+; -+; al char -+; cx count (does nothing if count <= 0) -+; -+putc_n: -+ cmp cx,0 -+ jle putc_n_90 -+ call putc -+ dec cx -+ jmp putc_n -+putc_n_90: -+ ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Print char. -+; -+; al char -+; -+putc: -+ pusha -+ cmp al,0ah -+ jnz putc_30 -+ push ax -+ mov al,0dh -+ call putc_50 -+ pop ax -+putc_30: -+ call putc_50 -+ popa -+ ret -+putc_50: -+ mov bx,7 -+ mov ah,0eh -+ int 10h -+ ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Read char from stdin. -+; -+; return: -+; eax char -+; -+; Note: 32 bit call/ret! -+; -+getchar: -+ pushad -+ mov ah,10h -+ int 16h -+ mov [gc_tmp],al -+ popad -+ movzx eax,byte [gc_tmp] -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; Clear screen. -+; -+; Note: 32 bit call/ret! -+; -+clrscr: -+ pushad -+ push es -+ push word 40h -+ pop es -+ mov ax,600h -+ mov bh,7 -+ xor cx,cx -+ mov dl,[es:4ah] -+ or dl,dl -+ jnz clrscr_20 -+ mov dl,80 -+clrscr_20: -+ dec dl -+ mov dh,[es:84h] -+ or dh,dh -+ jnz clrscr_30 -+ mov dh,24 -+clrscr_30: -+ int 10h -+ mov ah,2 -+ mov bh,[es:62h] -+ xor dx,dx -+ int 10h -+ pop es -+ popad -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; dst = memcpy(dst, src, size). -+; -+; args on stack -+; -+; return: -+; eax dst -+; -+; Note: 32 bit call/ret! -+; -+memcpy: -+ pushad -+ -+ mov edi,[esp+0x20+4] -+ mov esi,[esp+0x20+8] -+ mov ecx,[esp+0x20+12] -+ -+ rep movsb -+ -+ popad -+ -+ mov eax,[esp+4] -+ -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; dst = memset(dst, val, size). -+; -+; args on stack -+; -+; return: -+; eax dst -+; -+; Note: 32 bit call/ret! -+; -+memset: -+ pushad -+ -+ mov edi,[esp+0x20+4] -+ mov al,[esp+0x20+8] -+ mov ecx,[esp+0x20+12] -+ -+ rep stosb -+ -+ popad -+ -+ mov eax,[esp+4] -+ -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; dst = memset32(dst, val, size). -+; -+; args on stack -+; -+; return: -+; eax dst -+; -+; Note: 32 bit call/ret! -+; -+memset32: -+ pushad -+ -+ push es -+ -+ mov ebx,[esp+0x22+4] ; edi -+ mov al,[esp+0x22+8] -+ mov edx,[esp+0x22+12] -+ -+memset32_20: -+ mov edi,ebx -+ mov ecx,ebx -+ and di,0fh -+ shr ecx,4 -+ mov es,cx -+ -+ mov ecx,0fff0h -+ cmp edx,ecx -+ ja memset32_40 -+ mov ecx,edx -+memset32_40: -+ add ebx,ecx -+ sub edx,ecx -+ -+ rep stosb -+ -+ jnz memset32_20 -+ -+ pop es -+ -+ popad -+ -+ mov eax,[esp+4] -+ -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; dst = memcpy32(dst, src, size). -+; -+; dst, src are 32bit linear addresses -+; -+; args on stack -+; -+; return: -+; eax dst -+; -+; Note: 32 bit call/ret! -+; -+memcpy32: -+ pushad -+ -+ push ds -+ push es -+ -+ mov ebx,[esp+0x24+4] ; edi -+ mov eax,[esp+0x24+8] ; esi -+ mov edx,[esp+0x24+12] -+ -+memcpy32_20: -+ mov edi,ebx -+ mov ecx,ebx -+ and di,0fh -+ shr ecx,4 -+ mov es,cx -+ -+ mov esi,eax -+ mov ecx,eax -+ and si,0fh -+ shr ecx,4 -+ mov ds,cx -+ -+ mov ecx,0fff0h -+ cmp edx,ecx -+ ja memcpy32_40 -+ mov ecx,edx -+memcpy32_40: -+ add ebx,ecx -+ add eax,ecx -+ sub edx,ecx -+ -+ rep movsb -+ -+ jnz memcpy32_20 -+ -+ pop es -+ pop ds -+ -+ popad -+ -+ mov eax,[esp+4] -+ -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; x86int(int, *regs). -+; -+; args on stack -+; -+; Note: 32 bit call/ret! -+; -+x86int: -+ pushad -+ -+ mov al,[esp+0x20+4] -+ mov [x86int_p],al -+ mov ebx,[esp+0x20+8] -+ -+ mov ecx,[bx+8] -+ mov edx,[bx+0ch] -+ mov esi,[bx+10h] -+ mov edi,[bx+14h] -+ mov ebp,[bx+18h] -+ mov ah,[bx+1ch] ; eflags -+ sahf -+ mov eax,[bx] -+ -+ mov es,[bx+22h] -+ mov fs,[bx+24h] -+ mov gs,[bx+26h] -+ mov ds,[bx+20h] -+ -+ mov ebx,[cs:bx+4] -+ -+ int 0h -+x86int_p equ $-1 -+ -+ push ebx -+ mov ebx,[esp+0x24+8] -+ pop dword [cs:bx+4] -+ -+ mov [cs:bx],eax -+ mov [cs:bx+20h],ds -+ + boot: + mov ax,cs -+ mov ds,ax -+ -+ mov [cs:bx+22h],es -+ mov [cs:bx+24h],fs -+ mov [cs:bx+26h],gs -+ + mov es,ax -+ mov fs,ax -+ mov gs,ax ++ mov bx,command_line ++ mov si,syslinux_hook ++ mov edi,8 << 20 ; at 8MB ++ mov ax,27h ++ int 22h ++ jnc input + -+ mov [bx+8],ecx -+ mov [bx+0ch],edx -+ mov [bx+10h],esi -+ mov [bx+14h],edi -+ mov [bx+18h],ebp -+ pushfd -+ pop dword [bx+1ch] ++ ; 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 + -+ popad -+ -+ o32 ret -+ -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; farcall(addr, *regs). +; -+; args on stack ++; Callback function used at various places in syslinux. +; -+; Note: 32 bit call/ret! ++; Can modify all regs & sregs. +; -+farcall: -+ pushad -+ -+ mov ebx,[esp+0x20+8] -+ -+ mov ecx,[bx+8] -+ mov edx,[bx+0ch] -+ mov esi,[bx+10h] -+ mov edi,[bx+14h] -+ mov ebp,[bx+18h] -+ mov ah,[bx+1ch] ; eflags -+ sahf -+ mov eax,[bx] -+ -+ mov [farcall_stack],sp -+ sub word [farcall_stack],1000h ; 4k stack should be enough for gfxboot -+ mov [farcall_stack+2],ss -+ -+ mov es,[bx+22h] -+ mov fs,[bx+24h] -+ mov gs,[bx+26h] -+ mov ds,[bx+20h] -+ -+ mov ebx,[cs:bx+4] -+ -+ call far [esp+0x20+4] -+ -+ push ebx -+ mov ebx,[esp+0x24+8] -+ pop dword [cs:bx+4] -+ -+ mov [cs:bx],eax -+ mov [cs:bx+20h],ds -+ -+ mov ax,cs -+ mov ds,ax -+ -+ mov [cs:bx+22h],es -+ mov [cs:bx+24h],fs -+ mov [cs:bx+26h],gs -+ -+ mov es,ax -+ mov fs,ax -+ mov gs,ax -+ -+ mov [bx+8],ecx -+ mov [bx+0ch],edx -+ mov [bx+10h],esi -+ mov [bx+14h],edi -+ mov [bx+18h],ebp -+ pushfd -+ pop dword [bx+1ch] -+ -+ popad -+ -+ o32 ret -+ -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; wrapper around gfx_cb() ++; 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 +; -+; we need to switch stack to ensure ss = cs = ds = es for gcc -+; -+_gfx_cb: ++syslinux_hook: + push cs + pop ds -+ push cs -+ pop es -+ mov [cb_stack],sp -+ mov [cb_stack+2],ss -+ lss sp,[farcall_stack] -+ sub sp,28h ; sizeof x86regs_t -+ mov [esp+18h],ebp -+ mov ebp,esp -+ push ebp -+ mov [bp],eax -+ mov [bp+4],ebx -+ mov [bp+8],ecx -+ mov [bp+0ch],edx -+ mov [bp+10h],esi -+ mov [bp+14h],edi -+ call dword gfx_cb -+ lea ebp,[esp+4] -+ mov eax,[bp] -+ mov ebx,[bp+4] -+ mov ecx,[bp+8] -+ mov edx,[bp+0ch] -+ mov esi,[bp+10h] -+ mov edi,[bp+14h] -+ mov ebp,[bp+18h] -+ lss sp,[cb_stack] ++ 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 + -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+; wrapper around syslinux_hook() -+; -+; ensure cs = ds = es for gcc -+; -+_syslinux_hook: -+ push cs -+ pop ds ++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 -+ sub sp,28h ; sizeof x86regs_t -+ mov [esp+18h],ebp -+ mov ebp,esp -+ push ebp -+ mov [bp],eax -+ mov [bp+4],ebx -+ mov [bp+8],ecx -+ mov [bp+0ch],edx -+ mov [bp+10h],esi -+ mov [bp+14h],edi -+ call dword syslinux_hook -+ lea ebp,[esp+4] -+ mov eax,[bp] -+ mov ebx,[bp+4] -+ mov ecx,[bp+8] -+ mov edx,[bp+0ch] -+ mov esi,[bp+10h] -+ mov edi,[bp+14h] -+ mov ebp,[bp+18h] -+ add sp,28h+4 -+ retf ++ 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 + -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+reboot: -+ mov word [472h],1234h -+ jmp 0ffffh:0 -+ int 19h -+ jmp $ + 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 + -+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ section .data ++ mov ax,[es:bx+12] ++ mov [gfx_bc_progress_init],ax ++ mov [gfx_bc_progress_init+2],es + -+farcall_stack dd 0 -+cb_stack dd 0 ++ mov ax,[es:bx+14] ++ mov [gfx_bc_progress_done],ax ++ mov [gfx_bc_progress_done+2],es + -+; buffer for number conversions -+; must be large enough for ps_status_info() -+num_buf times 23h db 0 -+num_buf_end db 0 ++ mov ax,[es:bx+16] ++ mov [gfx_bc_progress_update],ax ++ mov [gfx_bc_progress_update+2],es + -+; temp data for printf -+pf_args dw 0 -+pf_num dd 0 -+pf_sig db 0 -+pf_pad db 0 -+pf_raw_char db 0 -+gc_tmp db 0 ++ mov ax,[es:bx+18] ++ mov [gfx_bc_progress_limit],ax ++ mov [gfx_bc_progress_limit+2],es + -diff --git a/modules/libio.h b/modules/libio.h -new file mode 100644 -index 0000000..b7a3dc6 ---- /dev/null -+++ b/modules/libio.h -@@ -0,0 +1,131 @@ -+/* -+ * -+ * libio.h include file for libio -+ * -+ * Copyright (c) 2009 Steffen Winterfeldt. -+ * -+ * 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 the -+ * Free Software Foundation, Inc., 53 Temple Place Ste 330, Boston MA -+ * 02111-1307, USA; either version 2 of the License, or (at your option) any -+ * later version; incorporated herein by reference. -+ * -+ */ ++ mov ax,[es:bx+20] ++ mov [gfx_bc_password_init],ax ++ mov [gfx_bc_password_init+2],es + -+#ifndef _LIBIO_H -+#define _LIBIO_H -+ -+ -+asm(".code16gcc\n"); -+ -+ -+#define int8_t char -+#define int16_t short -+#define int32_t int -+#define uint8_t unsigned char -+#define uint16_t unsigned short -+#define uint32_t unsigned -+ -+#define X86_CF 0x0001 -+#define X86_PF 0x0004 -+#define X86_AF 0x0010 -+#define X86_ZF 0x0040 -+#define X86_SF 0x0080 -+#define X86_TF 0x0100 -+#define X86_IF 0x0200 -+#define X86_DF 0x0400 -+#define X86_OF 0x0800 -+ -+#define EOF -1 -+ -+#define main _main -+ -+ -+typedef struct __attribute ((packed)) { -+ uint32_t eax, ebx, ecx, edx, esi, edi, ebp, eflags; -+ uint16_t ds, es, fs, gs; -+} x86regs_t; -+ -+ -+static inline uint16_t comboot_seg(void) -+{ -+ uint16_t u; -+ -+ asm("mov %%cs, %0" : "=r" (u)); -+ -+ return u; -+} -+ -+ -+static inline uint8_t _mem8(uint32_t p) -+{ -+ uint8_t u; -+ -+ asm( -+ "movl %1,%%esi\n" -+ "shrl $4,%%esi\n" -+ "mov %%si,%%fs\n" -+ "movl %1,%%esi\n" -+ "and $15, %%si\n" -+ "movb %%fs:(%%si),%0\n" -+ : "=abcd" (u) : "r" (p) : "si" -+ ); -+ -+ return u; -+} -+ -+ -+static inline uint16_t _mem16(uint32_t p) -+{ -+ uint16_t u; -+ -+ asm( -+ "movl %1,%%esi\n" -+ "shrl $4,%%esi\n" -+ "mov %%si,%%fs\n" -+ "movl %1,%%esi\n" -+ "and $15, %%si\n" -+ "movw %%fs:(%%si),%0\n" -+ : "=r" (u) : "r" (p) : "si" -+ ); -+ -+ return u; -+} -+ -+ -+static inline uint32_t _mem32(uint32_t p) -+{ -+ uint32_t u; -+ -+ asm( -+ "movl %1,%%esi\n" -+ "shrl $4,%%esi\n" -+ "mov %%si,%%fs\n" -+ "movl %1,%%esi\n" -+ "and $15, %%si\n" -+ "movl %%fs:(%%si),%0\n" -+ : "=r" (u) : "r" (p) : "si" -+ ); -+ -+ return u; -+} -+ -+ -+int _main(int argc, char **argv); -+void printf(char *format, ...) __attribute__ ((format (printf, 1, 2))); -+int getchar(void); -+void clrscr(void); -+void *memcpy(void *dest, const void *src, int n); -+uint32_t memcpy32(uint32_t dest, uint32_t src, int n); -+void *memset(void *dest, int c, int n); -+uint32_t memset32(uint32_t dest, int c, int n); -+void x86int(unsigned intr, x86regs_t *regs); -+void farcall(uint32_t seg_ofs, x86regs_t *regs); -+void gfx_cb(x86regs_t *r); -+void _gfx_cb(void); -+void syslinux_hook(x86regs_t *r); -+void _syslinux_hook(void); -+void reboot(void); -+ -+#endif /* _LIBIO_H */ ++ 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 + diff --git a/syslinux-3.82-s_herbst.diff b/syslinux-3.82-s_herbst.diff new file mode 100644 index 0000000..68783cc --- /dev/null +++ b/syslinux-3.82-s_herbst.diff @@ -0,0 +1,237 @@ +diff --git a/modules/gfxboot.asm b/modules/gfxboot.asm +index c9fdd1b..5c7b118 100644 +--- a/modules/gfxboot.asm ++++ b/modules/gfxboot.asm +@@ -144,7 +144,15 @@ got_config_file: + push cs + pop es + call parse_config ++ cmp word [label_cnt],0 ++ ja labels_defined + ++ mov bx,msg_no_labels_defined ++ mov ax,2 ++ int 22h ++ ret ++ ++labels_defined: + ; get_gfx_file + mov ax,cs + add ax,2000h +@@ -417,6 +425,14 @@ gfx_read_file: + mov si,pspCmdArg+1 + int 22h + jnc gfx_file_read ++ ++ mov ax,2 ++ mov bx,pspCmdArg+1 ++ int 22h ++ ++ mov ax,2 ++ mov bx,msg_not_found ++ int 22h + stc + ret + +@@ -641,8 +657,7 @@ gfx_input: + shl edi,4 + add edi, command_line ; buffer (0: no buffer) + mov ecx, max_cmd_len ; buffer size +-; xor eax,eax ; timeout value (0: no timeout) +- mov eax,100 ; timeout value (0: no timeout) ++ mov eax,[menu_timeout] ; timeout value (0: no timeout) + + call far [gfx_bc_input] + ret +@@ -699,33 +714,39 @@ parse_config: + mov bx, msg_crlf + int 22h + %endif ++ mov bx,keywords ++ mov cx,[keyword_cnt] ++.keywords_loop: ++ push cx + push si + push di +- xor ecx,ecx ++ xor cx,cx + mov si,configbuf +- mov di,label_keyword+1 +- mov cl, byte [label_keyword] ++ mov di,[bx] ++ mov cl,byte [di] ++ inc di + call memcmp + pop di + pop si +- jz .do_label ++ jnz .not_found ++ pop cx ++ call [bx+2] ; call keyword handler ++ jmp .read + +- push si +- push di +- xor ecx,ecx +- mov si,configbuf +- mov di,default_keyword+1 +- mov cl, byte [default_keyword] +- call memcmp +- pop di +- pop si +- jz .do_default ++.not_found: ++ add bx,4 ++ pop cx ++ loop .keywords_loop + + .nextline: + call skipline + jmp .read + +-.do_label: ++.eof: ++.noparm: ++ ret ++ ++do_label: + call skipspace + jz .eof + jc .noparm +@@ -742,10 +763,11 @@ parse_config: + pop di + pop es + inc word [label_cnt] ++.eof: ++.noparm: ++ ret + +- jmp .read +- +-.do_default: ++do_default: + call skipspace + jz .eof + jc .noparm +@@ -759,8 +781,42 @@ parse_config: + pop di + pop es + +- jmp .read ++.eof: ++.noparm: ++ ret + ++do_timeout: ++ call skipspace ++ jz .eof ++ jc .noparm ++ call ungetc ++ push es ++ push di ++ push cs ++ pop es ++ mov di,NumBuf ++.getnum: ++ cmp di,NumBufEnd ++ jae .loaded ++ call getc ++ stosb ++ cmp al,'-' ++ jnb .getnum ++ call ungetc ++ dec di ++.loaded: ++ mov byte [di],0 ++ pop di ++ pop es ++ push cs ++ pop ds ++ mov si,NumBuf ++ push ebx ++ call parseint ++ jc .err ++ mov [menu_timeout],ebx ++.err: ++ pop ebx + .eof: + .noparm: + ret +@@ -876,23 +932,63 @@ memcmp: + pop si + ret + +- section .data +-label_keyword db 6,'label',0 +-default_keyword db 7,'default',0 ++parseint: ++ push eax ++ push ecx ++ xor eax,eax ++ xor ebx,ebx ++ xor ecx,ecx ++ mov cl,10 ++.loop: ++ lodsb ++ and al,al ++ jz .done ++ cmp al,'0' ++ jb .err ++ cmp al,'9' ++ ja .err ++ sub al,'0' ++ imul ebx,ecx ++ add ebx,eax ++ jmp short .loop ++.done: ++ clc ++.ret: ++ pop ecx ++ pop eax ++ ret ++.err: ++ stc ++ jmp short .ret + ++ section .data + msg_progname db 'gfxboot: ',0 + msg_config_file db 'Configuration file',0 + msg_missing db 'missing',0 + msg_usage db 'Usage: gfxboot.com ',0dh,0ah,0 + msg_memory db 'Could not detect available memory size',0dh,0ah,0 + msg_bootlogo_toobig db 'bootlogo file too big',0dh,0ah,0 +-msg_pxelinux db 'pxelinux is not supported',0dh,0ah,0 + msg_unknown_file_size db 'unknown file size',0dh,0ah,0 ++msg_not_found db ' not found',0dh,0ah,0 ++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 ++keyword_text_default db 7,'default',0 ++keyword_text_timeout db 7,'timeout',0 ++keywords equ $ ++ dw keyword_text_label ++ dw do_label ++ dw keyword_text_default ++ dw do_default ++ dw keyword_text_timeout ++ dw do_timeout ++keyword_cnt dw ($-keywords)/4 + + ; menu entry descriptor + menu_entries equ 0 +@@ -942,6 +1038,9 @@ dentry_buf_len equ $ - dentry_buf + max_cmd_len equ 2047 + command_line resb max_cmd_len+2 + ++NumBuf resb 15 ++NumBufEnd resb 1 ++ + alignb 4 + derivative_id resb 1 + drivenumber resb 1 diff --git a/syslinux.changes b/syslinux.changes index 96bbef2..de5650f 100644 --- a/syslinux.changes +++ b/syslinux.changes @@ -1,8 +1,3 @@ -------------------------------------------------------------------- -Fri Aug 7 13:47:54 CEST 2009 - snwint@suse.de - -- replaced gfxboot.com with an enhanced version - ------------------------------------------------------------------- Tue Aug 4 10:49:19 CEST 2009 - snwint@suse.de diff --git a/syslinux.spec b/syslinux.spec index ff3e9fc..462f9ca 100644 --- a/syslinux.spec +++ b/syslinux.spec @@ -20,6 +20,9 @@ Name: syslinux ExclusiveArch: %ix86 x86_64 BuildRequires: libpng-devel nasm netpbm python +%ifarch x86_64 +BuildRequires: gcc-32bit glibc-devel-32bit +%endif Url: http://syslinux.zytor.com/ License: GPL v2 or later Group: System/Boot @@ -27,14 +30,15 @@ Requires: mtools AutoReqProv: on Summary: Boot Loader for Linux Version: 3.82 -Release: 3 +Release: 4 Source: %{name}-%{version}.tar.bz2 Source1: isolinux-config Source2: README.gfxboot -Patch0: %{name}-%{version}-gfxboot.diff -Patch1: %{name}-%{version}-suse.diff -Patch2: %{name}-%{version}-compat.diff -Patch3: %{name}-%{version}-isohybrid.diff +Patch0: %{name}-%{version}-s_herbst.diff +Patch1: %{name}-%{version}-gfxboot.diff +Patch2: %{name}-%{version}-suse.diff +Patch3: %{name}-%{version}-compat.diff +Patch4: %{name}-%{version}-isohybrid.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -55,6 +59,7 @@ Authors: %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 %build cp %{SOURCE2} .