syslinux/syslinux-3.31.diff

2379 lines
48 KiB
Diff

--- abort.inc
+++ abort.inc
@@ -21,6 +21,11 @@
; abort_check: let the user abort with <ESC> or <Ctrl-C>
;
abort_check:
+%ifdef WITH_GFX
+ ; don't
+ cmp byte [gfx_ok],0
+ jnz .ret1
+%endif
call pollchar
jz .ret1
pusha
--- add_crc
+++ add_crc
@@ -0,0 +1,57 @@
+#! /usr/bin/perl
+
+use integer;
+
+# for isolinux
+#
+# Ensure checksum over (first sector - 64 bytes) [internally: FirstSecSum]
+# is 0 by adjusting the variable csum_value.
+#
+# Though isolinux checks the integrity with a separate checksum after all
+# data has been loaded this does not help with BIOSes that don't get even
+# the first 2k right. Hence this additional check. :-(
+#
+
+$file = shift;
+$list = "$file";
+$list =~ s/\.bin$/.lst/;
+
+open F, $list;
+
+while(<F>) {
+ if(/^\s*\d+\s*(\S+)\s*0+\s*(\<\d+\>\s*)?csum_value\s*dd\s*0/) {
+ $ofs = hex $1;
+ }
+}
+close F;
+
+die "oops 1\n" unless $ofs && !($ofs & 3);
+
+# print "$ofs\n";
+
+open F, $file or die "$file: $!\n";
+
+$file_size = -s $file;
+
+sysread F, $buf, $file_size;
+
+close F;
+
+die "oops 1\n" if $file_size != length($buf);
+
+@x = unpack "V512", $buf;
+
+for ($sum = 0, $i = 16; $i < 512; $i++) {
+ $sum += $x[$i];
+}
+
+# printf "0x%08x\n", $sum;
+
+$ns = pack "V", -$sum;
+
+substr($buf, $ofs, 4) = $ns;
+
+open F, ">$file" or die "$file: $!\n";
+
+syswrite F, $buf;
+
--- com32/lib/Makefile
+++ com32/lib/Makefile
@@ -79,6 +79,7 @@
tidy:
rm -f *.o .*.d */*.o */.*.d sys/vesa/alphatbl.c
+ rm -f sys/vesa/*.o sys/vesa/.*.d
clean: tidy
rm -f *.a
--- com32/libutil/get_key.c
+++ com32/libutil/get_key.c
@@ -42,6 +42,10 @@
#include <getkey.h>
#include <libutil.h>
+#ifndef CLK_TCK
+# define CLK_TCK __sysconf(2)
+#endif
+
struct keycode {
int code;
int seqlen;
--- com32/modules/cpuid.c
+++ com32/modules/cpuid.c
@@ -238,7 +238,7 @@
static int smp_scan_config (unsigned long base, unsigned long length)
{
- unsigned long *bp = base;
+ unsigned long *bp = (unsigned long *) base;
struct intel_mp_floating *mpf;
// printf("Scan SMP from %p for %ld bytes.\n", bp,length);
--- com32/samples/keytest.c
+++ com32/samples/keytest.c
@@ -25,6 +25,10 @@
#include <consoles.h> /* Provided by libutil */
#include <getkey.h>
+#ifndef CLK_TCK
+# define CLK_TCK __sysconf(2)
+#endif
+
static void cooked_keys(void)
{
int key;
--- conio.inc
+++ conio.inc
@@ -47,6 +47,13 @@
; set by routine searchdir
;
get_msg_file:
+%ifdef WITH_GFX
+ ; don't load if graphics code is active
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ ret
+.nogfx:
+%endif
push es
shl edx,16 ; EDX <- DX:AX (length of file)
mov dx,ax
--- gfxboot.inc
+++ gfxboot.inc
@@ -0,0 +1,1369 @@
+ section .text
+
+load_gfx_msg db 'Loading...', 0
+no_msg db 0
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; do a reboot
+;
+do_reboot:
+ call gfx_done
+ mov word [472h],1234h
+ push word 0ffffh
+ push word 0
+ retf
+ int 19h
+ jmp $
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; wait for 'enter' key pressed
+;
+wait_for_key:
+ pusha
+wait_for_key_10:
+ mov ah,0
+ int 16h
+ cmp al,13
+ jnz wait_for_key_10
+ popa
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; read gfx data
+get_gfx_file:
+ push si
+ mov si,load_gfx_msg
+ call cwritestr
+ pop si
+ mov word [gfx_mem_start_seg],first_free_seg
+ push ds
+ push 40h
+ pop ds
+ mov bx,[13h] ; mem size in kb
+ pop ds
+ shl bx,6
+ mov word [gfx_mem_end_seg],bx
+
+ call gfx_init ; Load and display file
+ cmp byte [gfx_ok],0
+ jz .done
+ mov si,crlf_msg
+ call cwritestr
+.done:
+ ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; read from disk, ask for disk change, if necessary
+
+; EAX - Linear sector number
+; ES:BX - Target buffer
+; BP - Sector count
+;
+; (es:)bx gets updated
+
+%if IS_SYSLINUX
+
+; %define DEBUG_XXX
+
+getlinsec3:
+%ifdef DEBUG_XXX
+ mov si,txt0
+ call dump_params
+ call crlf
+%endif
+ mov cx,[DiskSize]
+ or cx,cx
+ jz getlinsec3_70 ; unlimited
+
+ xor dx,dx
+ div cx
+ xchg ax,dx
+ movzx eax,ax
+
+ mov si,ax
+ add si,bp
+ sub si,cx
+ jbe getlinsec3_40
+ ; split
+
+ sub bp,si
+ movzx ebp,bp
+ push ebp
+ push eax
+ push si
+ push dx
+ call getlinsec3_40
+ pop dx
+ pop bp
+ pop eax
+ pop esi
+ add eax,esi
+ movzx ebp,bp
+ inc dl
+
+getlinsec3_40:
+ push es
+ pushad
+ call disk_change
+ popad
+ pop es
+ jc kaboom
+getlinsec3_70:
+%ifdef DEBUG_XXX
+ mov si,txt1
+ call dump_params
+ mov si,txt3
+ call cwritestr
+ push ax
+ mov al,[CurrentDisk]
+ call writehex2
+ pop ax
+ call crlf
+ pushad
+ call getchar
+ popad
+%endif
+ xor edx,edx
+ call getlinsec.jmp
+ ret
+
+%ifdef DEBUG_XXX
+dump_params:
+ push eax
+ call cwritestr
+ mov ax,es
+ call writehex4
+ mov si,txt2
+ call cwritestr
+ mov ax,bx
+ call writehex4
+ mov si,txt3
+ call cwritestr
+ pop eax
+ push eax
+ call writehex8
+ mov si,txt3
+ call cwritestr
+ mov ax,bp
+ call writehex4
+ pop eax
+ ret
+
+txt0 db 'linsec3: ', 0
+txt1 db 'linsec: ', 0
+txt2 db ':', 0
+txt3 db ', ', 0
+
+%include "writehex.inc"
+
+%endif
+
+
+; dl: new disk
+; return: CF = 1 -> error
+disk_change:
+ cmp dl,[CurrentDisk]
+ jz disk_change_90
+
+ mov [CurrentDisk],dl
+ movzx eax,dl
+ mov [gfx_user_info_0],eax
+ add dl,'1'
+ mov [boot_disk_msg0],dl
+ mov [boot_ndisk_msg0],dl
+
+disk_change_20:
+ cmp byte [gfx_ok],0
+ jz disk_change_40
+ mov al,3
+ xor di,di
+ xor si,si
+ call gfx_infobox
+
+ jmp disk_change_50
+disk_change_40:
+ mov si,clrln_msg
+ call cwritestr
+ mov si,boot_disk_msg
+ call cwritestr
+ call wait_for_key
+ mov si,clrln_msg
+ call cwritestr
+disk_change_50:
+ xor eax,eax
+ mov bp,1
+ push bx
+ xor edx,edx
+ call getlinsec.jmp
+ pop bx
+ mov eax,[es:bx+27h]
+ sub eax,[bsVolumeID]
+ movzx edx,byte [CurrentDisk]
+ cmp eax,edx
+ jz disk_change_90
+ mov [gfx_user_info_1],eax
+
+ cmp byte [gfx_ok],0
+ jz disk_change_70
+ mov al,4
+ xor di,di
+ xor si,si
+ call gfx_infobox
+
+ jmp disk_change_50
+disk_change_70:
+ mov si,clrln_msg
+ call cwritestr
+ mov si,boot_ndisk_msg
+ call cwritestr
+; mov eax,[es:bx+27h]
+; call writehex8
+ call wait_for_key
+ mov si,clrln_msg
+ call cwritestr
+
+ jmp disk_change_20
+disk_change_90:
+ ret
+
+
+bsVolumeID equ bsHugeSectors+7
+
+boot_disk_msg db 'Please insert boot disk '
+boot_disk_msg0 db '0; then press ENTER to continue.', 0
+boot_ndisk_msg db 'This is not boot disk '
+boot_ndisk_msg0 db '0. Press ENTER to continue.', 0
+
+DiskSize dw 0 ; unlimited
+CurrentDisk db 0 ; current disk
+
+clrln_msg db 0dh, ' ', 0dh, 0
+
+
+cache_metadata:
+ cmp word [DiskSize],0
+ jz cache_md_90
+
+ mov eax,[FAT]
+ mov ecx,[bxFATsecs]
+cache_md_20:
+ push eax
+ push cx
+ call getcachesector
+ pop cx
+ pop eax
+ inc eax
+ loop cache_md_20
+
+ mov eax,[RootDir]
+cache_md_40:
+ push eax
+ call getcachesector
+ pop eax
+ call nextsector
+ jnc cache_md_40
+
+cache_md_90:
+ ret
+
+
+%endif
+
+
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; gfx stuff
+;
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+gfx_menu_seg equ real_mode_seg
+
+; != 0 -> graphics active
+gfx_ok db 0
+gfx_cwritestr_old db 0c3h ; 'ret'
+gfx_cpio_swab db 0
+gfx_cd_changed db 0
+
+gfx_mem_start_seg dw 0
+gfx_mem_end_seg dw 0
+
+ align 4, db 0
+; the memory area we are working with
+gfx_mem dd 0 ; linear address
+
+gfx_save_area1 dd 0 ; 64k
+gfx_save_area1_used db 0 ; != 0 if area1 is in use
+
+; interface to loadable gfx extension (seg:ofs values)
+gfx_bc_jt dd 0
+
+gfx_bc_init dd 0
+gfx_bc_done dd 0
+gfx_bc_input dd 0
+gfx_bc_menu_init dd 0
+gfx_bc_infobox_init dd 0
+gfx_bc_infobox_done dd 0
+gfx_bc_progress_init dd 0
+gfx_bc_progress_done dd 0
+gfx_bc_progress_update dd 0
+gfx_bc_progress_limit dd 0
+gfx_bc_password_init dd 0
+gfx_bc_password_done dd 0
+
+; menu entry descriptor
+menu_entries equ 0
+menu_default equ 2 ; seg:ofs
+menu_ent_list equ 6 ; seg:ofs
+menu_ent_size equ 10
+menu_arg_list equ 12 ; seg:ofs
+menu_arg_size equ 16
+sizeof_menu_desc equ 18
+
+menu_desc zb sizeof_menu_desc
+
+; system config data (52 bytes)
+gfx_sysconfig equ $
+gfx_bootloader db 1 ; 0: boot loader type (0: lilo, 1: syslinux, 2: grub)
+gfx_sector_shift db SECTOR_SHIFT ; 1: sector shift
+gfx_media_type db 0 ; 2: media type (0: disk, 1: floppy, 2: cdrom)
+gfx_failsafe db 0 ; 3: turn on failsafe mode (bitmask)
+ ; 0: SHIFT pressed
+ ; 1: skip gfxboot
+ ; 2: skip monitor detection
+gfx_sysconfig_size db gfx_sysconfig_end-gfx_sysconfig ; 4: size of sysconfig data
+gfx_boot_drive db 0 ; 5: BIOS boot drive
+gfx_callback dw gfx_cb ; 6: offset to callback handler
+gfx_bootloader_seg dw 0 ; 8: code/data segment used by bootloader; must follow gfx_callback
+gfx_reserved_1 dw 0 ; 10
+gfx_user_info_0 dd 0 ; 12: data for info box
+gfx_user_info_1 dd 0 ; 16: data for info box
+gfx_bios_mem_size dd 0 ; 20: BIOS memory size (in bytes)
+gfx_xmem_0 dw 0 ; 24: extended mem area 0 (start:size in MB; 12:4 bits)
+gfx_xmem_1 dw 0 ; 26: extended mem area 1
+gfx_xmem_2 dw 0 ; 28: extended mem area 2
+gfx_xmem_3 dw 0 ; 20: extended mem area 3
+gfx_file dd 0 ; 32: start of gfx file
+gfx_archive_start dd 0 ; 36: start of cpio archive
+gfx_archive_end dd 0 ; 40: end of cpio archive
+gfx_mem0_start dd 0 ; 44: low free memory start
+gfx_mem0_end dd 0 ; 48: low free memory end
+gfx_sysconfig_end equ $
+
+gfx_slash db '/', 0
+
+%macro lin2segofs 3
+ push %1
+ call gfx_l2so
+ pop %3
+ pop %2
+%endmacro
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; must not change registers!
+;
+gfx_get_sysconfig:
+ push ax
+%if IS_ISOLINUX
+ mov al,[DriveNo]
+%else
+ mov al,[DriveNumber]
+%endif
+ mov [gfx_boot_drive],al
+
+%if IS_ISOLINUX
+ mov ah,2
+%else
+ mov ah,0
+%endif
+ cmp al,80h ; floppy ?
+ jae gfx_get_sysconfig_20
+ mov ah,1
+gfx_get_sysconfig_20:
+
+ mov [gfx_media_type],ah
+
+ mov [gfx_bootloader_seg],cs
+
+ pop ax
+ ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Initialize graphics code. Load and display graphics data.
+;
+; dx:ax file length
+; si start cluster
+;
+; return: [gfx_ok] = 0/1
+;
+gfx_init:
+ push es
+
+ test byte [KbdFlags],3
+ jz gfx_init_10
+ mov byte [gfx_failsafe],1
+ call ask_user
+gfx_init_10:
+
+ test byte [gfx_failsafe],2
+ jnz gfx_init_80
+
+ call highmemsize
+
+ ; setup extended memory areas
+ pusha
+ mov eax,[HighMemSize]
+ mov [gfx_bios_mem_size],eax
+ shr eax,20
+ cmp ax,16
+ jb gfx_init_40 ; at least 16MB
+ mov word [gfx_xmem_0],81h ; 1MB at 8MB
+ mov word [gfx_xmem_1],0a1h ; 1MB at 10MB
+
+ mov dword [gfx_save_area1],7f0000h ; 8MB-64k
+gfx_init_40:
+ popa
+
+ cld
+
+ movzx ebx,word [gfx_mem_start_seg]
+ shl ebx,4
+ jz gfx_init_80
+
+ movzx ecx,word [gfx_mem_end_seg]
+ shl ecx,4
+ jz gfx_init_80
+
+ cmp ecx,ebx
+ jbe gfx_init_80
+
+ ; define our memory area
+ ; gfx_mem _must_ be 16-byte aligned
+ mov dword [gfx_mem],ebx
+ mov dword [gfx_mem0_start],ebx
+ mov dword [gfx_mem0_end],ecx
+
+ call gfx_read_file
+ cmp byte [gfx_ok],0
+ jz near gfx_init_90
+
+ call gfx_get_sysconfig
+
+ ; align 4
+ mov eax,[gfx_mem0_start]
+ add eax,3
+ and eax,~3
+ mov [gfx_mem0_start],eax
+
+ ; setup jump table
+ les bx,[gfx_bc_jt]
+
+ mov ax,[es:bx]
+ mov [gfx_bc_init],ax
+ mov [gfx_bc_init+2],es
+
+ mov ax,[es:bx+2]
+ mov [gfx_bc_done],ax
+ mov [gfx_bc_done+2],es
+
+ mov ax,[es:bx+4]
+ mov [gfx_bc_input],ax
+ mov [gfx_bc_input+2],es
+
+ mov ax,[es:bx+6]
+ 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
+ add esi,gfx_sysconfig
+ call far [gfx_bc_init]
+ jc gfx_init_80
+
+ mov byte [gfx_ok],1
+
+ ; turn off 'cwritestr'
+ mov al,[cwritestr]
+ cmp al,0c3h
+ jz gfx_init_90
+ mov [gfx_cwritestr_old],al
+ mov byte [cwritestr],0c3h
+
+ jmp gfx_init_90
+
+gfx_init_80:
+ mov byte [gfx_ok],0
+gfx_init_90:
+ pop es
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Back to text mode.
+;
+; return: [gfx_ok] = 0
+;
+gfx_done:
+ push ax
+ cmp byte [gfx_ok],0
+ jz gfx_done_90
+ call far [gfx_bc_done]
+ mov byte [gfx_ok],0
+
+ ; reactivate 'cwritestr'
+ mov al,[gfx_cwritestr_old]
+ cmp al,0c3h
+ jz gfx_done_90
+ mov [cwritestr],al
+gfx_done_90:
+ pop ax
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_input:
+ cmp byte [gfx_ok],0
+ jz gfx_input_90
+ cmp byte [gfx_save_area1_used],0
+ jz gfx_input_10
+ ; recover saved menu layout, gfxboot has references into it
+ pushad
+ mov esi,[gfx_save_area1]
+ mov edi,gfx_menu_seg << 4
+ mov ecx,10000h
+ call bcopy
+ popad
+gfx_input_10:
+ call far [gfx_bc_input]
+ jnc gfx_input_50
+ mov ax,1
+gfx_input_50:
+ cmp ax,1
+ jnz gfx_input_90
+ push ax
+ call gfx_done
+ pop ax
+gfx_input_90:
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; es:di string
+; return:
+; cx length
+gfx_strlen:
+ mov cx,-1
+ mov al,0
+ repnz scasb
+ not cx
+ dec cx
+ ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_setup_menu:
+ push es
+ cmp byte [gfx_ok],0
+ jz gfx_setup_menu_90
+
+ mov dword [menu_desc+menu_default],gfx_menu_seg << 16
+
+ push ds
+ pop es
+ mov si,default_cmd
+ mov di,trackbuf
+ call mangle_name
+ mov si,trackbuf
+ les di,[menu_desc+menu_default]
+ call unmangle_name
+ inc di
+
+ mov [menu_desc+menu_ent_list],di
+ mov [menu_desc+menu_ent_list+2],es
+ mov [menu_desc+menu_arg_list],di
+ mov [menu_desc+menu_arg_list+2],es
+
+ ; first, count entries and find max kernel and append length
+
+ push ds
+ pop es
+
+ xor si,si
+ jmp gfx_setup_menu_20
+gfx_setup_menu_10:
+ push ds
+ push word vk_seg
+ pop ds
+ mov di,VKernelBuf
+ call rllunpack
+ pop ds
+
+ ; count only non empty entries
+ cmp byte [es:VKernelBuf],0
+ jz gfx_setup_menu_20
+
+ inc word [menu_desc+menu_entries]
+
+ push si
+ mov si,VKernelBuf
+ mov di,KernelCName
+ push di
+ call unmangle_name
+ pop di
+ pop si
+
+ call gfx_strlen
+
+ cmp cx,[menu_desc+menu_ent_size]
+ jbe gfx_setup_menu_15
+ mov [menu_desc+menu_ent_size],cx
+gfx_setup_menu_15:
+ mov ax,[VKernelBuf+vk_appendlen]
+ cmp ax,[menu_desc+menu_arg_size]
+ jbe gfx_setup_menu_20
+ mov [menu_desc+menu_arg_size],ax
+
+gfx_setup_menu_20:
+ cmp si,[VKernelBytes]
+ jb gfx_setup_menu_10
+
+ inc word [menu_desc+menu_ent_size]
+ mov ax,[menu_desc+menu_ent_size]
+ inc ax
+ add [menu_desc+menu_arg_size],ax
+
+ ; ...and again, but this time copy entries
+
+ mov word [menu_desc+menu_entries],0
+
+ xor si,si
+ jmp gfx_setup_menu_60
+gfx_setup_menu_30:
+ push ds
+ pop es
+ push ds
+ push word vk_seg
+ pop ds
+ mov di,VKernelBuf
+ call rllunpack
+ pop ds
+
+ ; count only non empty entries
+ cmp byte [es:VKernelBuf],0
+ jz gfx_setup_menu_60
+
+ mov di,[menu_desc+menu_arg_list]
+ add di,[menu_desc+menu_arg_size]
+ jc gfx_setup_menu_60
+
+ inc word [menu_desc+menu_entries]
+
+ push si
+
+ mov si,VKernelBuf
+ mov di,KernelCName
+ push ds
+ pop es
+ push di
+ call unmangle_name
+ pop si
+ mov cx,[menu_desc+menu_ent_size]
+ les di,[menu_desc+menu_arg_list]
+
+ rep movsb
+
+ mov cx,[VKernelBuf+vk_appendlen]
+ mov si,VKernelBuf+vk_append
+ rep movsb
+ mov byte [es:di],0
+
+ pop si
+
+ mov ax,[menu_desc+menu_arg_size]
+ add [menu_desc+menu_arg_list],ax
+
+gfx_setup_menu_60:
+ cmp si,[VKernelBytes]
+ jb gfx_setup_menu_30
+
+ mov ax,[menu_desc+menu_ent_size]
+ mov bx,[menu_desc+menu_arg_size]
+ mov [menu_desc+menu_ent_size],bx
+ add ax,[menu_desc+menu_ent_list]
+ mov [menu_desc+menu_arg_list],ax
+
+ mov esi,ds
+ shl esi,4
+ add esi,menu_desc
+
+ call far [gfx_bc_menu_init]
+
+ ; save menu structure, gfxboot uses references into it
+ mov edi,[gfx_save_area1]
+ or edi,edi
+ jz gfx_setup_menu_90
+ mov esi,gfx_menu_seg << 4
+ mov ecx,10000h
+ call bcopy
+ mov byte [gfx_save_area1_used],1
+
+gfx_setup_menu_90:
+ pop es
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_infobox:
+ pushad
+ cmp byte [gfx_ok],0
+ jz gfx_infobox_90
+ mov ecx,ds
+ shl ecx,4
+ movzx esi,si
+ movzx edi,di
+ or si,si
+ jz gfx_infobox_20
+ add esi,ecx
+gfx_infobox_20:
+ or di,di
+ jz gfx_infobox_30
+ add edi,ecx
+gfx_infobox_30:
+ call far [gfx_bc_infobox_init]
+ xor edi,edi
+ xor eax,eax
+ call far [gfx_bc_input]
+ call far [gfx_bc_infobox_done]
+gfx_infobox_90:
+ popad
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_init:
+ pushad
+ cmp byte [gfx_ok],0
+ jz gfx_progress_init_90
+ call far [gfx_bc_progress_init]
+gfx_progress_init_90:
+ popad
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_done:
+ pushad
+ cmp byte [gfx_ok],0
+ jz gfx_progress_done_90
+ call far [gfx_bc_progress_done]
+gfx_progress_done_90:
+ popad
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_update:
+ pushad
+ cmp byte [gfx_ok],0
+ jz gfx_progress_update_90
+ movzx eax,cx
+ call far [gfx_bc_progress_update]
+gfx_progress_update_90:
+ popad
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_progress_limit:
+ pushad
+ cmp byte [gfx_ok],0
+ jz gfx_progress_limit_90
+ movzx eax,ax
+ movzx edx,dx
+ call far [gfx_bc_progress_limit]
+gfx_progress_limit_90:
+ popad
+ ret
+
+
+%if 0
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_password:
+ pushad
+ cmp byte [gfx_ok],0
+ stc
+ jz gfx_password_90
+ call far [gfx_bc_password_init]
+ mov edi,ds
+ shl edi,4
+ add edi,gfx_password_buf
+ mov ecx,32
+ xor eax,eax
+ call far [gfx_bc_input]
+ mov esi,ds
+ shl esi,4
+ add esi,gfx_password_buf
+ call far [gfx_bc_password_done]
+ jnc gfx_password_90
+ mov esi,ds
+ shl esi,4
+ add esi,gfx_msg_wrong_password
+ xor edi,edi
+ mov al,0
+ call far [gfx_bc_infobox_init]
+ xor edi,edi
+ xor eax,eax
+ call far [gfx_bc_input]
+ call far [gfx_bc_infobox_done]
+ stc
+gfx_password_90:
+ popad
+ ret
+%endif
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Read graphics data and store them at [gfx_mem].
+;
+; dx:ax file length
+; si start cluster
+;
+; return: [gfx_ok] = 0/1
+;
+gfx_read_file:
+ push es
+ mov byte [gfx_ok],0
+ mov edi,[gfx_mem]
+ push dx ; DX:AX = length of file
+ push ax
+ pop edx
+ mov [gfx_archive_end],edx
+ mov eax,[gfx_mem0_start]
+ lea eax,[eax+edx+0fh] ; add space for alignment
+ cmp eax,[gfx_mem0_end] ; max. length
+ ja near gfx_read_file_90
+ mov [gfx_mem0_start],eax
+
+gfx_read_file_10:
+ mov bx,trackbuf
+ mov cx,[BufSafe]
+ push edi
+ push edx
+ call getfssec
+ pop edx
+ pop edi
+ movzx ecx,word [BufSafeBytes]
+ cmp edx,ecx
+ jae gfx_read_file_20
+ mov ecx,edx
+gfx_read_file_20:
+ push ecx
+ push edi
+ push si ; Save current cluster
+ push es
+ mov si,trackbuf
+ push edi
+ call gfx_l2so
+ pop di
+ pop es
+ rep movsb
+ pop es
+ pop si
+ pop edi
+ pop ecx
+ add edi,ecx
+ sub edx,ecx
+ ja gfx_read_file_10
+
+ call find_file
+ or eax,eax
+ jz gfx_read_file_90
+ push edi
+ push eax
+ add eax,edi
+ call align_it
+ pop eax
+ pop edi
+ sub edi,[gfx_mem]
+ mov ecx,[gfx_archive_start]
+ add edi,ecx
+ mov [gfx_file],edi
+ add [gfx_archive_end],ecx
+ add eax,edi
+ shr eax,4
+ mov [gfx_bc_jt+2],ax
+
+ mov byte [gfx_ok],1
+
+gfx_read_file_90:
+ pop es
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; locate graphics file
+;
+; return: eax: code offset (0 -> no file found)
+; edi: gfx file start
+;
+find_file:
+ mov edi,[gfx_mem]
+ lin2segofs edi,es,bx
+ call magic_ok
+ or eax,eax
+ jnz find_file_90
+
+ ; ok, maybe it's a cpio archive
+
+ ; note: edi must be properly aligned (2)!
+
+find_file_20:
+ mov ecx,[gfx_mem0_start]
+ sub ecx,26 + 12 ; min cpio header + gfx header
+ cmp edi,ecx
+ jae find_file_90
+
+ lin2segofs edi,es,bx
+ cmp word [es:bx],71c7h
+ jz find_file_30 ; normal cpio record
+ cmp word [es:bx],0c771h ; maybe byte-swapped?
+ jnz find_file_90 ; no cpio record
+ mov byte [gfx_cpio_swab],1
+
+find_file_30:
+ mov ax,[es:bx+20] ; file name size
+ call cpio_swab
+ movzx esi,ax
+
+ inc si
+ and si,~1 ; align
+
+ mov eax,[es:bx+22] ; data size
+ call cpio_swab
+ rol eax,16 ; get word order right
+ call cpio_swab
+ mov ecx,eax
+
+ inc ecx
+ and ecx,byte ~1 ; align
+
+ add si,26 ; skip header
+
+ add edi,esi
+ add bx,si
+ call magic_ok
+ or eax,eax
+ jnz find_file_90
+
+ add edi,ecx
+ jmp find_file_20
+
+find_file_90:
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; byte-swap cpio data if appropriate
+;
+; ax: word to swap
+;
+; return: ax: swapped if [gfx_cpio_swab], otherwise same as input
+;
+cpio_swab:
+ cmp byte [gfx_cpio_swab],0
+ jz cpio_swab_90
+ xchg ah,al
+
+cpio_swab_90:
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; es:bx file start
+;
+; return: eax: offset to code entry
+;
+; Notes:
+; - changes no regs except eax
+;
+magic_ok:
+ xor eax,eax
+ cmp dword [es:bx],0b2d97f00h ; header.magic_id
+ jnz magic_ok_90
+ cmp byte [es:bx+4],8 ; header.version
+ jnz magic_ok_90
+ mov eax,[es:bx+8]
+magic_ok_90:
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; eax address to be aligned
+;
+align_it:
+ push dword [gfx_mem]
+ pop dword [gfx_archive_start]
+ neg al
+ and eax,byte 0fh
+ jz align_it_90
+ add [gfx_archive_start],eax
+ mov esi,[gfx_mem]
+ mov ebx,[gfx_mem0_start]
+ sub ebx,esi
+ sub ebx,byte 0fh
+ add esi,ebx
+ dec esi
+
+ std
+
+align_it_30:
+ or ebx,ebx
+ jz align_it_60
+ mov ecx,ebx
+ cmp ebx,8000h
+ jb align_it_40
+ mov ecx,8000h
+align_it_40:
+ push esi
+ sub ebx,ecx
+ sub [esp],ecx
+ push esi
+ call gfx_l2so
+ pop si
+ add si,8000h
+ sub word [esp],(8000h >> 4)
+ pop es
+ mov di,si
+ add di,ax
+ es rep movsb
+ pop esi
+ jmp align_it_30
+align_it_60:
+
+ cld
+
+align_it_90:
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Ask user whether to continue.
+;
+; don't change regs
+;
+ask_user:
+ pushad
+
+ mov si,failsafe_msg_0
+ call cwritestr
+
+ mov dx,2
+ mov si,failsafe_msg_1
+ call ask_question
+
+ test byte [gfx_failsafe],2
+ jnz ask_user_90
+
+ mov dx,4
+ mov si,failsafe_msg_2
+ call ask_question
+
+ask_user_90:
+
+ popad
+ ret
+
+
+; si: text
+; dh: 'yes'-mask
+; dl: 'no'-mask
+ask_question:
+ push dx
+ call cwritestr
+ mov si,failsafe_msg_q
+ call cwritestr
+ pop dx
+
+ask_question_20:
+ push dx
+ mov ah,0
+ int 16h
+ pop dx
+
+ cmp al,13
+ jnz ask_question_30
+ mov al,'y'
+ask_question_30:
+ or al,20h ; force lower case
+
+ cmp al,'y'
+ jz ask_question_40
+ cmp al,'n'
+ jnz ask_question_20
+ or byte [gfx_failsafe],dl
+ jmp ask_question_50
+ask_question_40:
+ or byte [gfx_failsafe],dh
+ask_question_50:
+
+ mov si,failsafe_key
+ mov [si],al
+ call cwritestr
+
+ ret
+
+failsafe_msg_q db ' (y/n)? y', 8, 0
+
+failsafe_msg_0 db 13, 10, 10, 10, 0
+failsafe_msg_1 db 'Load boot graphics', 0
+failsafe_msg_2 db 'Detect display size', 0
+
+failsafe_key db 0, 13, 10, 0
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; Convert 32bit linear address to seg:ofs.
+;
+; dword [esp + 2]: linear address
+;
+; return:
+; dword [esp + 2]: seg:ofs
+;
+; Notes:
+; - changes no regs
+;
+gfx_l2so:
+ push eax
+ mov eax,[esp + 6]
+ shr eax,4
+ mov [esp + 8],ax
+ and word [esp + 6],byte 0fh
+ pop eax
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+cb_table dw cb_status
+ dw cb_fopen
+ dw cb_fread
+ dw cb_getcwd
+ dw cb_chdir
+ dw cb_readsector
+cb_len equ ($-cb_table)/2
+
+f_handle dw 0
+f_size dd 0
+fname_buf times 64 db 0
+fname_buf_len equ $ - fname_buf
+
+
+gfx_cb:
+ push cs
+ pop ds
+
+ cmp al,cb_len
+ jae gfx_cb_80
+
+ movzx bx,al
+ add bx,bx
+ call word [bx+cb_table]
+ jmp gfx_cb_90
+
+gfx_cb_80:
+ mov al,0ffh
+gfx_cb_90:
+ retf
+
+
+; Return status info.
+;
+; return:
+; edx filename buffer (64 bytes)
+;
+cb_status:
+ mov edx,cs
+ shl edx,4
+ add edx,fname_buf
+
+ xor al,al
+ ret
+
+; Open file.
+;
+; return:
+; al 0: ok, 1: file not found
+; ecx file length (al = 0)
+;
+cb_fopen:
+ mov si,fname_buf
+ mov di,VGAFileMBuf ; we just need some space
+ push ds
+ pop es
+ push di
+ call mangle_name
+ pop di
+ call searchdir
+ xchg ax,bx
+ mov al,1
+ jz cb_fopen_90
+ mov [f_handle],si
+ mov cx,dx
+ shl ecx,16
+ mov cx,bx
+ mov [f_size],ecx
+cb_fopen_80:
+ xor al,al
+cb_fopen_90:
+ ret
+
+
+; Read next chunk.
+;
+; return:
+; edx buffer address (linear)
+; ecx data length (< 64k)
+;
+cb_fread:
+ cmp dword [f_size],0
+ jz cb_fread_80
+ push cs
+ pop es
+ mov bx,trackbuf
+ mov cx,[BufSafe]
+ mov si,[f_handle]
+ call getfssec
+ mov [f_handle],si
+ mov ecx,[f_size]
+ movzx edx,word [BufSafeBytes]
+ cmp ecx,edx
+ jbe cb_fread_50
+ mov ecx,edx
+cb_fread_50:
+ sub [f_size],ecx
+ mov edx,cs
+ shl edx,4
+ add edx,trackbuf
+
+cb_fread_80:
+ xor al,al
+cb_fread_90:
+ ret
+
+
+; Return current working directory.
+;
+; return:
+; edx filename
+;
+cb_getcwd:
+ mov edx,cs
+ shl edx,4
+%if IS_ISOLINUX
+ add edx,isolinux_dir
+%else
+ add edx,gfx_slash
+%endif
+ xor al,al
+ ret
+
+
+; Set current working directory.
+;
+cb_chdir:
+%if IS_ISOLINUX
+
+ push cs
+ pop es
+ mov si,fname_buf
+ mov di,isolinux_dir
+cb_chdir_20:
+ lodsb
+ stosb
+ or al,al
+ jz cb_chdir_60
+ cmp di,isolinux_cfg - 1
+ jb cb_chdir_20
+ xor al,al
+ stosb
+cb_chdir_60:
+ call get_fs_structures
+
+%endif
+ xor al,al
+ ret
+
+
+; read sector
+;
+; edx sector
+;
+; return:
+; edx buffer (linear address)
+;
+; Note: does not return on error!
+;
+cb_readsector:
+ mov eax,edx
+ push ds
+ pop es
+ mov bx,trackbuf
+ call getonesec
+ mov edx,ds
+ shl edx,4
+ add edx,trackbuf
+ xor al,al
+ ret
+
--- isolinux.asm
+++ isolinux.asm
@@ -19,6 +19,10 @@
; ****************************************************************************
%define IS_ISOLINUX 1
+
+%define WITH_GFX 1
+; %define DEBUG_DISKIO
+
%include "head.inc"
;
@@ -70,6 +74,7 @@
vk_seg equ 2000h ; Virtual kernels
xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
+first_free_seg equ 4000h ; end of isolinux used memory
;
; File structure. This holds the information for each currently open file.
@@ -266,6 +271,21 @@
mov [FirstSecSum],edi
mov [DriveNo],dl
+
+ ; check whether the BIOS did load us correctly
+ cmp dl,80h ; some BIOSes try to do floppy emulation...
+ jb bios_err
+ cmp dword [FirstSecSum], byte 0
+ jz bios_ok
+bios_err:
+ mov si,broken_bios_msg
+ call writemsg
+ jmp short $
+broken_bios_msg db 13, 10, 'Cannot boot from this CD. Please use CD2 or try a BIOS update.', 13, 10, 0
+ align 4
+csum_value dd 0
+bios_ok:
+
%ifdef DEBUG_MESSAGES
mov si,startup_msg
call writemsg
@@ -290,6 +310,9 @@
; Other nonzero fields
inc word [dsp_sectors]
+%if 0
+ ; Some BIOSes don't like that call.
+
; Now figure out what we're actually doing
; Note: use passed-in DL value rather than 7Fh because
; at least some BIOSes will get the wrong value otherwise
@@ -310,6 +333,8 @@
call crlf
%endif
+%endif
+
found_drive:
; Alright, we have found the drive. Now, try to find the
; boot file itself. If we have a boot info table, life is
@@ -434,6 +459,9 @@
%endif
jmp all_read ; Jump to main code
+%if 0
+ ; doesn't work anyway, see above
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -617,6 +645,7 @@
mov si,trysbm_msg
call writemsg
jmp .found_drive ; Pray that this works...
+%endif
fatal_error:
mov si,nothing_msg
@@ -676,10 +705,17 @@
;
getlinsec:
mov si,dapa ; Load up the DAPA
+ mov [si+8],eax
+ ; seems that some BIOSes have problems if the target
+ ; segment is 0 (don't ask); to avoid this, we normalize
+ ; the buffer address here
+ ; -> seen on Acer TravelMate C102Ti
mov [si+4],bx
- mov bx,es
- mov [si+6],bx
- mov [si+8],eax
+ and word [si+4],0fh
+ mov ax,es
+ shr bx,4
+ add ax,bx
+ mov [si+6],ax
.loop:
push bp ; Sectors left
cmp bp,[MaxTransfer]
@@ -706,14 +742,77 @@
; INT 13h with retry
xint13: mov byte [RetryCount],retry_count
.try: pushad
+%ifdef DEBUG_DISKIO
+ pushad
+ mov cx,16
+.zap:
+ lodsb
+ call writehex2
+ mov al,' '
+ call writechr
+ loop .zap
+ mov ah,0
+ int 16h
+ popad
+%endif
+ ; seen buggy bios that overwrites buffer address on error...
+ push dword [dapa + 4]
int 13h
+ pop dword [dapa + 4]
+%ifdef DEBUG_DISKIO
+ pushad
+ pushf
+ push ax
+ mov al,':'
+ call writechr
+ mov al,' '
+ call writechr
+ pop ax
+ sbb al,al
+ call writehex4
+ call crlf
+ mov ah,0
+ int 16h
+ popf
+ popad
+%endif
jc .error
+.noerror:
add sp,byte 8*4 ; Clean up stack
ret
.error:
+ or ah,ah
+ jz .noerror
mov [DiskError],ah ; Save error code
popad
mov [DiskSys],ax ; Save system call number
+
+%if 0
+ ; eject currently not supported - doesn't work anyway with
+ ; most BIOSes
+
+ test byte [gfx_user_note],1
+ jz .noeject
+ cmp byte [RetryCount],4
+ ja .noeject
+ cmp byte [DiskError],0aah ; drive not ready
+ jnz .noeject
+ ; might have been cdrom eject, wait a bit
+ cmp byte [gfx_ok],0
+ jz .noeject
+ push si
+ push di
+ push ax
+ mov si,err_not_ready
+ xor di,di
+ mov al,0
+ call gfx_infobox
+ pop ax
+ pop di
+ pop si
+%endif
+.noeject:
+
dec byte [RetryCount]
jz .real_error
push ax
@@ -756,6 +855,17 @@
;
kaboom:
RESET_STACK_AND_SEGS AX
+
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ mov si,err_failed_gfx
+ xor di,di
+ mov al,1
+ call gfx_infobox
+ call gfx_done
+ call do_reboot
+.nogfx:
+
mov si,err_bootfailed
call cwritestr
call getchar
@@ -807,6 +917,9 @@
crlf_msg db CR, LF
null_msg db 0
+err_failed_gfx db 'Error reading boot CD.', 0
+err_not_ready db 'CDROM drive not ready.', 0
+
alignb 4, db 0
StackPtr dw StackBuf, 0 ; SS:SP for stack reset
MaxTransfer dw 32 ; Max sectors per transfer
@@ -876,6 +989,9 @@
; (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.
;
+ call get_fs_structures
+ jmp get_fs_struct_done
+
get_fs_structures:
mov eax,[bi_pvd]
mov bx,trackbuf
@@ -901,10 +1017,15 @@
; Look for an isolinux directory, and if found,
; make it the current directory instead of the root
; directory.
+
+ cmp byte [gfx_ok],0 ; don't look at both
+ jnz .gfx
+
mov di,boot_dir ; Search for /boot/isolinux
mov al,02h
call searchdir_iso
jnz .found_dir
+.gfx:
mov di,isolinux_dir
mov al,02h ; Search for /isolinux
call searchdir_iso
@@ -925,7 +1046,10 @@
call crlf
%endif
.no_isolinux_dir:
+ ret
+get_fs_struct_done:
+
;
; Locate the configuration file
;
@@ -1103,6 +1227,9 @@
; 0xFFFF in case we should execute INT 18h ("next device.")
;
local_boot:
+%ifdef WITH_GFX
+ call gfx_done
+%endif
call vgaclearmode
lss sp,[cs:Stack] ; Restore stack pointer
xor dx,dx
@@ -1120,7 +1247,7 @@
xor dh,dh
push dx
xor ax,ax ; Reset drive
- call xint13
+ int 13h ; we don't care about errors here...
mov ax,0201h ; Read one sector
mov cx,0001h ; C/H/S = 0/0/1 (first sector)
mov bx,trackbuf
@@ -1486,6 +1613,9 @@
%include "strcpy.inc" ; strcpy()
%include "rawcon.inc" ; Console I/O w/o using the console functions
+%include "gfxboot.inc" ; add gfx things
+
+
; -----------------------------------------------------------------------------
; Begin data section
; -----------------------------------------------------------------------------
@@ -1507,7 +1637,8 @@
db 'booting, and I will take your word for it.', CR, LF, 0
err_badcfg db 'Unknown keyword in config file.', CR, LF, 0
err_noparm db 'Missing parameter in config file.', CR, LF, 0
-err_noinitrd db CR, LF, 'Could not find ramdisk image: ', 0
+err_noinitrd db CR, LF
+err_noinitrda db '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.'
@@ -1532,6 +1663,7 @@
default_len equ ($-default_str)
boot_dir db '/boot' ; /boot/isolinux
isolinux_dir db '/isolinux', 0
+ zb 64
ConfigName equ $
isolinux_cfg db 'isolinux.cfg', 0
err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0
--- keywords
+++ keywords
@@ -32,3 +32,5 @@
f10
f11
f12
+gfxboot
+disksize
--- keywords.inc
+++ keywords.inc
@@ -76,8 +76,15 @@
%if IS_PXELINUX
keyword ipappend, pc_ipappend
%endif
-%if IS_PXELINUX || IS_ISOLINUX
+%if IS_PXELINUX || IS_ISOLINUX || IS_SYSLINUX
keyword localboot, pc_localboot
%endif
+%ifdef WITH_GFX
+ keyword gfxboot, pc_filecmd, get_gfx_file
+%if IS_SYSLINUX
+ keyword disksize, pc_disksize, DiskSize
+%endif
+%endif
+
keywd_count equ ($-keywd_table)/keywd_size
--- layout.inc
+++ layout.inc
@@ -26,7 +26,11 @@
; The secondary BSS section, above the text; we really wish we could
; just make it follow .bcopy32 or hang off the end,
; but it doesn't seem to work that way.
+%ifdef WITH_GFX
+LATEBSS_START equ 0B800h
+%else
LATEBSS_START equ 0B400h
+%endif
; Reserve memory for the stack. This causes checkov to abort the
; compile if we violate this space.
--- ldlinux.asm
+++ ldlinux.asm
@@ -24,6 +24,9 @@
%ifndef IS_MDSLINUX
%define IS_SYSLINUX 1
%endif
+
+%define WITH_GFX 1
+
%include "head.inc"
;
@@ -82,6 +85,7 @@
vk_seg equ 2000h ; Virtual kernels
xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
+first_free_seg equ 5000h ; end of syslinux used memory
;
; File structure. This holds the information for each currently open file.
@@ -368,6 +372,8 @@
add eax,[bsHidden] ; Add partition offset
xor edx,edx ; Zero-extend LBA (eventually allow 64 bits)
+.patch: jmp strict near .jmp
+
.jmp: jmp strict short getlinsec_cbios
;
@@ -927,6 +933,50 @@
%include "bootsect.inc"
;
+; Boot a specified local disk. AX specifies the BIOS disk number; or
+; 0xFFFF in case we should execute INT 18h ("next device.")
+;
+local_boot:
+%ifdef WITH_GFX
+ call gfx_done
+%endif
+ call vgaclearmode
+ lss sp,[cs:Stack] ; Restore stack pointer
+ xor dx,dx
+ mov ds,dx
+ mov es,dx
+ mov fs,dx
+ mov gs,dx
+ mov si,localboot_msg
+ call cwritestr
+ cmp ax,-1
+ je .int18
+
+ ; Load boot sector from the specified BIOS device and jump to it.
+ mov dl,al
+ xor dh,dh
+ push dx
+ xor ax,ax ; Reset drive
+ int 13h
+ mov ax,0201h ; Read one sector
+ mov cx,0001h ; C/H/S = 0/0/1 (first sector)
+ mov bx,trackbuf
+ int 13h
+ pop dx
+ cli ; Abandon hope, ye who enter here
+ mov si,trackbuf
+ mov di,07C00h
+ mov cx,512 ; Probably overkill, but should be safe
+ rep movsd
+ mov ss,cx
+ mov sp,7c00h
+ jmp 0:07C00h ; Jump to new boot sector
+
+.int18:
+ int 18h ; Hope this does the right thing...
+ jmp kaboom ; If we returned, oh boy...
+
+;
; Abort loading code
;
%include "abort.inc"
@@ -1048,6 +1098,15 @@
; starting with "kaboom.patch" with this part
kaboom2:
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ mov si,err_failed_gfx
+ xor di,di
+ mov al,1
+ call gfx_infobox
+ call gfx_done
+ call do_reboot
+.nogfx:
mov si,err_bootfailed
call cwritestr
call getchar
@@ -1418,6 +1477,8 @@
%include "strcpy.inc" ; strcpy()
%include "cache.inc" ; Metadata disk cache
+%include "gfxboot.inc" ; add gfx things
+
; -----------------------------------------------------------------------------
; Begin data section
; -----------------------------------------------------------------------------
@@ -1450,7 +1511,8 @@
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_noinitrd db CR, LF
+err_noinitrda db '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.'
@@ -1460,7 +1522,9 @@
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
+err_failed_gfx db 'Error reading from disk.', 0
ready_msg db 'Ready.', CR, LF, 0
+localboot_msg db 'Booting from local disk...', CR, LF, 0
crlfloading_msg db CR, LF
loading_msg db 'Loading ', 0
dotdot_msg db '.'
--- loadhigh.inc
+++ loadhigh.inc
@@ -47,7 +47,12 @@
.read_loop:
and si,si ; If SI == 0 then we have end of file
jz .eof
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jnz .no_message
+%endif
call bx
+.no_message:
push bx ; <AA> Pausebird function
push eax ; <A> Total bytes to transfer
@@ -63,7 +68,15 @@
push edi ; <C> Target buffer
mov cx,ax
xor bx,bx ; ES:0
+
+%ifdef WITH_GFX
+ call gfx_progress_update
+%endif
+
+ push dx
call getfssec ; Load the data into xfer_buf_seg
+ ; getfssec destroys dx!
+ pop dx
pop edi ; <C> Target buffer
pop ecx ; <B> Byte count this round
push ecx ; <B> Byte count this round
--- Makefile
+++ Makefile
@@ -121,7 +121,7 @@
kwdhash.gen: keywords genhash.pl
$(PERL) genhash.pl < keywords > kwdhash.gen
-ldlinux.bin: ldlinux.asm kwdhash.gen version.gen
+ldlinux.bin: ldlinux.asm kwdhash.gen version.gen gfxboot.inc
$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-DMAP=$(@:.bin=.map) -l $(@:.bin=.lst) -o $@ $<
$(PERL) checkov.pl ldlinux.map $@
@@ -131,16 +131,18 @@
-DMAP=$(@:.bin=.map) -l $(@:.bin=.lst) -o $@ $<
$(PERL) checkov.pl $(@:.bin=.map) $@
-isolinux.bin: isolinux.asm kwdhash.gen version.gen checksumiso.pl
+isolinux.bin: isolinux.asm kwdhash.gen version.gen checksumiso.pl gfxboot.inc
$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-DMAP=$(@:.bin=.map) -l $(@:.bin=.lst) -o $@ $<
+ ./add_crc $@
$(PERL) checkov.pl $(@:.bin=.map) $@
$(PERL) checksumiso.pl $@
# Special verbose version of isolinux.bin
-isolinux-debug.bin: isolinux-debug.asm kwdhash.gen version.gen checksumiso.pl
+isolinux-debug.bin: isolinux-debug.asm kwdhash.gen version.gen checksumiso.pl gfxboot.inc
$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-DMAP=$(@:.bin=.map) -l $(@:.bin=.lst) -o $@ $<
+ ./add_crc $@
$(PERL) checkov.pl $(@:.bin=.map) $@
$(PERL) checksumiso.pl $@
--- parseconfig.inc
+++ parseconfig.inc
@@ -81,7 +81,7 @@
;
; "localboot" command (PXELINUX, ISOLINUX)
;
-%if IS_PXELINUX || IS_ISOLINUX
+%if IS_PXELINUX || IS_ISOLINUX || IS_SYSLINUX
pc_localboot: call getint
cmp byte [VKernel],0 ; ("label" section only)
je .err
@@ -262,7 +262,26 @@
mov [SerialPort], word 0
ret
+%ifdef WITH_GFX
+%if IS_SYSLINUX
;
+; like pc_setint16, but patch sector read funtion, too
+;
+pc_disksize:
+ push ax
+ call getint
+ pop si
+ jc .err
+ mov [si],bx
+ mov word [getlinsec.patch+1], getlinsec3 - getlinsec.patch - 3
+ or bx,bx
+ jz .err
+ call cache_metadata
+.err: ret
+%endif
+%endif
+
+;
; "F"-key command
;
pc_fkey: push ax
--- pxelinux.asm
+++ pxelinux.asm
@@ -899,6 +899,9 @@
; AX contains the appropriate return code.
;
local_boot:
+%ifdef WITH_GFX
+ call gfx_done
+%endif
push cs
pop ds
mov [LocalBootType],ax
--- README.gfxboot
+++ README.gfxboot
@@ -0,0 +1,41 @@
+Graphical boot screen
+=====================
+
+ syslinux/isolinux support a graphical boot screen using VESA BIOS
+ extensions. (Note that this is different from the graphics support that
+ syslinux comes with).
+
+ To use it you have to prepare a special boot logo file and put a line like
+ this into syslinux.cfg/isolinux.cfg:
+
+ gfxboot foo
+
+ The tools to create 'foo' from the above example are in the gfxboot
+ package. Please _do_ have a look at its documentation before you begin.
+
+ Note that you cannot use comboot images and graphics at the same time as
+ the memory used overlaps the comboot loading area.
+
+ If you encouter problems with the graphics code, hold down SHIFT while
+ syslinux starts. This will put it into 'failsafe' mode that lets you
+ interactively skip critical parts (like monitor detection).
+
+
+
+Spread boot images over several floppy disks (syslinux)
+=======================================================
+
+ You can prepare boot disks with a file system that spans several disks.
+ The 'mkbootdisk' script from the openSUSE project can create a suitable
+ file system.
+
+ syslinux will ask you for disk changes if necessary. To enable this
+ feature, use
+
+ disksize <size_of_single_disk_in_sectors>
+
+ Note that every individual disk must have at least a valid FAT boot
+ sector. syslinux will use the serial number stored there to verify that
+ the correct disk has been inserted (its last hex digit is the zero based
+ disk number).
+
--- rllpack.inc
+++ rllpack.inc
@@ -28,7 +28,7 @@
;
; rllpack:
; Pack CX bytes from DS:SI into ES:DI
-; Returns updated SI, DI and CX = number of bytes output
+; Returns updated SI, DI and DX = number of bytes output
;
rllpack:
push ax
--- runkernel.inc
+++ runkernel.inc
@@ -202,6 +202,15 @@
pop ds
sub si,cmd_line_here
mov [CmdLineLen],si ; Length including final null
+
+%ifdef WITH_GFX
+ mov eax,[KernelSects]
+ mov esi,ds
+ shl esi,4
+ add esi,KernelCName
+ call gfx_progress_init
+%endif
+
;
; Now check if we have a large kernel, which needs to be loaded high
;
@@ -299,6 +308,19 @@
jz nk_noinitrd
call parse_load_initrd
nk_noinitrd:
+
+%ifdef WITH_GFX
+ call gfx_progress_done
+
+ cmp byte [gfx_cd_changed],0
+ jz .no_cd_change
+ mov al,6
+ xor si,si
+ xor di,di
+ call gfx_infobox
+.no_cd_change:
+%endif
+
;
; Abandon hope, ye that enter here! We do no longer permit aborts.
;
@@ -307,6 +329,10 @@
mov si,ready_msg
call cwritestr
+%ifdef WITH_GFX
+ call gfx_done
+%endif
+
call vgaclearmode ; We can't trust ourselves after this
UNLOAD_PREP ; Module-specific hook
@@ -521,6 +547,34 @@
.got_start:
push si
+
+%ifdef WITH_GFX
+ cmp byte [si],'+'
+ jnz .got_start_10
+ mov byte [cs:gfx_cd_changed],1
+ inc si
+ push es
+ push ds
+ push si
+ push cs
+ pop es
+ mov cx,100h
+ mov di,trackbuf
+ push di
+ rep movsb
+ mov byte [es:di],0
+ pop si
+ xor di,di
+ mov al,5 ; ask for cd change
+ push cs
+ pop ds
+ call gfx_infobox
+ pop si
+ pop ds
+ pop es
+.got_start_10:
+%endif
+
mov di,InitRD ; Target buffer for mangled name
call mangle_name
call loadinitrd
@@ -608,6 +662,20 @@
jmp crlf ; Print carriage return and return
.notthere:
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ mov si,InitRDCName
+ xor di,di
+ mov al,2
+ call gfx_infobox
+ call gfx_progress_done
+ mov si,no_msg
+ jmp abort_load
+.nogfx:
+%endif
+
mov si,err_noinitrd
call cwritestr
mov si,InitRDCName
@@ -616,7 +684,21 @@
jmp abort_load
no_high_mem: ; Error routine
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
mov si,err_nohighmem
+ xor di,di
+ mov al,0
+ call gfx_infobox
+ call gfx_progress_done
+ mov si,no_msg
+ jmp abort_load
+.nogfx:
+%endif
+
+ mov si,err_nohighmem
jmp abort_load
ret
--- syslinux.doc
+++ syslinux.doc
@@ -187,7 +187,7 @@
Append nothing. APPEND with a single hyphen as argument in a
LABEL section can be used to override a global APPEND.
- LOCALBOOT type [ISOLINUX, PXELINUX]
+ LOCALBOOT type [ISOLINUX, SYSLINUX, PXELINUX]
On PXELINUX, specifying "LOCALBOOT 0" instead of a "KERNEL"
option means invoking this particular label will cause a local
disk boot instead of booting a kernel.
@@ -201,12 +201,11 @@
UNDI or PXE stacks are, don't worry -- you don't want them,
just specify 0.
- On ISOLINUX, the "type" specifies the local drive number to
- boot from; 0x00 is the primary floppy drive and 0x80 is the
- primary hard drive. The special value -1 causes ISOLINUX to
- report failure to the BIOS, which, on recent BIOSes, should
- mean that the next boot device in the boot sequence should be
- activated.
+ On ISOLINUX and SYSLINUX, the "type" specifies the local drive
+ number to boot from; 0x00 is the primary floppy drive and 0x80 is
+ the primary hard drive. The special value -1 causes them to report
+ failure to the BIOS, which, on recent BIOSes, should mean that the
+ next boot device in the boot sequence should be activated.
IMPLICIT flag_val
If flag_val is 0, do not load a kernel image unless it has been
--- ui.inc
+++ ui.inc
@@ -15,6 +15,12 @@
;
call parse_config ; Parse configuration file
no_config_file:
+
+%ifdef WITH_GFX
+ ; build gfx menu
+ call gfx_setup_menu
+%endif
+
;
; Check whether or not we are supposed to display the boot prompt.
;
@@ -28,6 +34,21 @@
cmp word [NoEscape],0 ; If NOESCAPE, no prompt,
jne auto_boot ; always run default cmd
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ mov edi,ds
+ shl edi,4
+ add edi,command_line
+ mov ecx,max_cmd_len
+ xor eax,eax
+ xchg eax,[KbdTimeout] ; only the first time
+ call gfx_input
+ cmp ax,1
+ jnz load_kernel
+.nogfx:
+%endif
+
mov si,boot_prompt
call cwritestr
@@ -260,9 +281,21 @@
push word real_mode_seg
pop es
mov di,cmd_line_here
+
+%ifdef WITH_GFX
+ ; gfx code includes them
+ cmp byte [gfx_ok],0
+ jnz .isgfx
+%endif
+
mov si,VKernelBuf+vk_append
mov cx,[VKernelBuf+vk_appendlen]
rep movsb
+
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
mov [CmdLinePtr],di ; Where to add rest of cmd
pop es
mov di,KernelName
@@ -277,7 +310,7 @@
%endif
xor bx,bx ; Try only one version
-%if IS_PXELINUX || IS_ISOLINUX
+%if IS_PXELINUX || IS_ISOLINUX || IS_SYSLINUX
; Is this a "localboot" pseudo-kernel?
%if IS_PXELINUX
cmp byte [VKernelBuf+vk_rname+4], 0
@@ -361,6 +394,19 @@
push di
call unmangle_name ; Get human form
mov si,err_notfound ; Complain about missing kernel
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ pop si
+ xor di,di
+ mov al,2
+ call gfx_infobox
+ mov si,no_msg
+ jmp abort_load
+.nogfx:
+%endif
+
call cwritestr
pop si ; KernelCName
call cwritestr