Репозитории ALT
S: | 4.04-alt19 |
D: | 3.61-alt1 |
5.1: | 3.63-alt4 |
4.1: | 3.36-alt2 |
4.0: | 3.36-alt2 |
3.0: | 2.11-alt1 |
Группа :: Система/Ядро и оборудование
Пакет: syslinux
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: syslinux-2.11.patch
Скачать
Скачать
--- add_crc
+++ add_crc
@@ -0,0 +1,49 @@
+#! /usr/bin/perl
+
+use integer;
+
+# patch crc over first sector - 64 bytes into isolinux
+
+$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;
+
--- bcopy32.inc
+++ bcopy32.inc
@@ -65,7 +65,17 @@
; EDI - first byte after target
; ECX - zero
;
-bcopy: push eax
+bcopy:
+%if do_test
+ add esi,ecx
+ add edi,ecx
+ mov ecx,1000000*100
+.delay:
+ a32 ; NOT at the same line as the loop!
+ loop .delay
+ ret
+%endif
+ push eax
pushf ; Saves, among others, the IF flag
push gs
push fs
--- config.inc
+++ config.inc
@@ -20,6 +20,8 @@
%ifndef _CONFIG_INC
%define _CONFIG_INC
+%define do_test 0
+
max_cmd_len equ 255 ; Must be odd; 255 is the kernel limit
HIGHMEM_MAX equ 037FFFFFFh ; DEFAULT highest address for an initrd
DEFAULT_BAUD equ 9600 ; Default baud rate for serial port
--- conio.inc
+++ conio.inc
@@ -46,6 +46,13 @@
; set by routine searchdir
;
get_msg_file:
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ ; don't load if we have a graphics image
+ ret
+.nogfx:
+%endif
push es
shl edx,16 ; EDX <- DX:AX (length of file)
mov dx,ax
@@ -323,6 +330,9 @@
RESET_IDLE
.again:
DO_IDLE
+%ifdef WITH_GFX
+ call chk_update
+%endif
mov ah,1 ; Poll keyboard
int 16h
jnz .kbd ; Keyboard input?
--- fixofs
+++ fixofs
@@ -0,0 +1,4 @@
+#! /usr/bin/perl -p
+
+$ok = 1 if /org\s+7c00h/i;
+s/^(\s*(\d+)\s+)([0-9A-Fa-f]{8})/$1 . sprintf("%08X", hex($3)+0x7c00)/e if $ok;
--- gethostip.c
+++ gethostip.c
@@ -120,7 +120,7 @@
if ( output & 4 ) {
unsigned long addr =
- (((unsigned char *)host->h_addr)[0] << 24UL) +
+ ((unsigned long) ((unsigned char *)host->h_addr)[0] << 24UL) +
(((unsigned char *)host->h_addr)[1] << 16UL) +
(((unsigned char *)host->h_addr)[2] << 8UL) +
(((unsigned char *)host->h_addr)[3]);
--- gfxlogo.inc
+++ gfxlogo.inc
@@ -0,0 +1,637 @@
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; gfx stuff
+;
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+; != 0 -> everything's fine
+; note: moved to ldlinux.asm/isolinux.asm
+; gfx_ok db 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_mem_align dd 0 ; aligned data start
+gfx_mem_file dd 0 ; aligned gfx data start
+gfx_mem_max dd 0 ; end address
+gfx_mem_free dd 0 ; start of free area for malloc (after pcx image)
+
+; 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
+
+gfx_menu_max_entries equ 16
+gfx_menu_tmp equ mi_buf ; a reasonably sized buffer
+gfx_menu_def zb 13
+gfx_menu_entry zb 13 * gfx_menu_max_entries
+
+%if 0
+gfx_password_buf zb 32
+gfx_msg_wrong_image db 'Could not find kernel image: ', 0
+gfx_msg_wrong_password db 'Sorry, incorrect password.', 0
+%endif
+
+; 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
+gfx_sysconfig equ $
+gfx_bootloader db 1
+gfx_update db 0
+gfx_video_mode_list dw fb_mode_list
+gfx_video_modes db fb_mode_entries
+gfx_boot_drive db 0
+gfx_reload_fs db 0
+gfx_user_note dw 0
+gfx_reserved zb 3
+gfx_user_info_0 dd 0
+gfx_user_info_1 dd 0
+gfx_mem_size dd 0
+
+%macro lin2segofs 3
+ push %1
+ call gfx_l2so
+ pop %3
+ pop %2
+%endmacro
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; must not change registers!
+;
+gfx_get_sysconfig:
+ push ax
+ mov al,[wants_update]
+ mov [gfx_update],al
+%if IS_ISOLINUX
+ mov al,[DriveNo]
+%else
+ mov al,[bsDriveNumber]
+%endif
+ mov [gfx_boot_drive],al
+ push dword [HighMemSize]
+ pop dword [gfx_mem_size]
+ pop ax
+ ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_set_sysconfig:
+ push ax
+ mov al,[gfx_update]
+ mov [wants_update],al
+ 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
+
+ cld
+
+ movzx ecx,word [gfx_mem_end_seg]
+ shl ecx,4
+ jz near gfx_init_80
+
+ ; define our memory area
+ ; gfx_mem _must_ be 16-byte aligned
+ mov dword [gfx_mem],10000h
+ mov dword [gfx_mem_free],10000h
+ mov dword [gfx_mem_max],ecx
+
+ call gfx_read_file
+ cmp byte [gfx_ok],0
+ jz near gfx_init_90
+
+ ; align 4
+ mov eax,[gfx_mem_free]
+ add eax,3
+ and eax,~3
+ mov [gfx_mem_free],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 eax,[gfx_mem_file]
+ mov ebx,[gfx_mem_free]
+ mov ecx,[gfx_mem_max]
+ mov edi,[gfx_mem_align]
+ mov dx,cs
+
+ mov si,gfx_sysconfig
+ call far [gfx_bc_init]
+ jc gfx_init_80
+
+ call highmemsize
+
+ mov byte [gfx_ok],1
+
+ 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:
+ cmp byte [gfx_ok],0
+ jz gfx_done_90
+ call far [gfx_bc_done]
+ mov byte [gfx_ok],0
+ call gfx_set_sysconfig
+gfx_done_90:
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_input:
+ cmp byte [gfx_ok],0
+ jz gfx_input_90
+ call gfx_get_sysconfig
+ call far [gfx_bc_input]
+ pushf
+ call gfx_set_sysconfig
+ popf
+ 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
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_setup_menu:
+ cmp byte [gfx_ok],0
+ jz gfx_setup_menu_90
+
+ push ds
+ pop es
+ mov si,default_cmd
+ mov di,gfx_menu_tmp
+ call mangle_name
+ mov si,gfx_menu_tmp
+ mov di,gfx_menu_def
+ call unmangle_name
+ mov ax,[VKernelCtr]
+ cmp ax,gfx_menu_max_entries
+ jb gfx_setup_menu_10
+ mov ax,gfx_menu_max_entries
+gfx_setup_menu_10:
+ mov [menu_desc+menu_entries],ax
+ or ax,ax
+ jz gfx_setup_menu_90
+ xor si,si
+ mov di,gfx_menu_entry
+gfx_setup_menu_20:
+ push di
+ push si
+ shl si,vk_shift
+ push ds
+ push word vk_seg
+ pop ds
+ mov bx,[si+vk_appendlen]
+ mov byte [bx+si+vk_append],0 ; make it zero terminated
+ call unmangle_name
+ pop ds
+ pop si
+ pop di
+ add di,13
+ inc si
+ cmp si,[menu_desc+menu_entries]
+ jb gfx_setup_menu_20
+
+ mov si,menu_desc
+
+ mov word [si+menu_default],gfx_menu_def
+ mov [si+menu_default+2],ds
+
+ mov word [si+menu_ent_list],gfx_menu_entry
+ mov [si+menu_ent_list+2],ds
+ mov word [si+menu_ent_size],13
+
+ mov word [si+menu_arg_list],vk_append
+ mov word [si+menu_arg_list+2],vk_seg
+ mov word [si+menu_arg_size],vk_size
+
+ push ds
+ pop es
+
+ call gfx_get_sysconfig
+ call far [gfx_bc_menu_init]
+
+gfx_setup_menu_90:
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+gfx_infobox:
+ pushad
+ cmp byte [gfx_ok],0
+ jz gfx_infobox_90
+ call far [gfx_bc_infobox_init]
+ xor di,di
+ xor ax,ax
+ 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
+ movzx eax,ax
+ 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 di,gfx_password_buf
+ mov cx,32
+ xor ax,ax
+ call far [gfx_bc_input]
+ mov si,gfx_password_buf
+ call far [gfx_bc_password_done]
+ jnc gfx_password_90
+ mov si,gfx_msg_wrong_password
+ xor di,di
+ mov al,0
+ call far [gfx_bc_infobox_init]
+ xor di,di
+ xor ax,ax
+ 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 eax,[gfx_mem_free]
+ lea eax,[eax+edx+0fh] ; add space for alignment
+ cmp eax,[gfx_mem_max] ; max. length
+ ja near gfx_read_file_90
+ mov [gfx_mem_free],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]
+ add edi,[gfx_mem_align]
+ mov [gfx_mem_file],edi
+ 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_mem_free]
+ 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
+ jnz find_file_90 ; no cpio record
+
+ movzx esi,word [es:bx+20] ; file name size
+
+ inc si
+ and si,~1 ; align
+
+ mov ecx,[es:bx+22] ; data size
+ rol ecx,16 ; get word order right
+
+ 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
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; 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],5 ; 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_mem_align]
+ neg al
+ and eax,byte 0fh
+ jz align_it_90
+ add [gfx_mem_align],eax
+ mov esi,[gfx_mem]
+ mov ebx,[gfx_mem_free]
+ 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
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+; 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
+
--- isolinux.asm
+++ isolinux.asm
@@ -20,6 +20,10 @@
; ****************************************************************************
%define IS_ISOLINUX 1
+
+%define WITH_GFX 1
+; %define DEBUG_DISKIO
+
%include "macros.inc"
%include "config.inc"
%include "kernel.inc"
@@ -58,9 +62,9 @@
;
; Note: this structure can be added to, but it must
;
-%define vk_power 6 ; log2(max number of vkernels)
+%define vk_power 5 ; log2(max number of vkernels)
%define max_vk (1 << vk_power) ; Maximum number of vkernels
-%define vk_shift (16-vk_power) ; Number of bits to shift
+%define vk_shift (15-vk_power) ; Number of bits to shift
%define vk_size (1 << vk_shift) ; Size of a vkernel buffer
struc vkernel
@@ -74,7 +78,7 @@
endstruc
%ifndef DEPEND
-%if (vk_end > vk_size) || (vk_size*max_vk > 65536)
+%if (vk_end > vk_size) || (vk_size*max_vk > 8000h)
%error "Too many vkernels defined, reduce vk_power"
%endif
%endif
@@ -83,9 +87,9 @@
; Segment assignments in the bottom 640K
; 0000h - main code/data segment (and BIOS segment)
;
-real_mode_seg equ 3000h
-vk_seg equ 2000h ; Virtual kernels
-xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
+real_mode_seg equ 7000h
+vk_seg equ 6800h ; Virtual kernels
+xfer_buf_seg equ 8000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
;
@@ -221,9 +225,21 @@
alignb 4
default_cmd resb max_cmd_len+1 ; "default" command line
+InitRDClust resw 1 ; Initrd size in clusters
+InitRDSize resd 1 ; Initrd size in bytes
+Splashat resd 1 ; Load address (linear) for splash
+SplashClust resw 1 ; Splash size in clusters
+SplashName resb FILENAME_MAX ; Mangled Splash image name
+SplashCName resb FILENAME_MAX ; Unmangled Splash image name
+
alignb open_file_t_size
Files resb MAX_OPEN*open_file_t_size
+vbe_buf resb 200h ; VBE2 buffer
+ddc_buf resb 80h ; for DDC info
+mi_buf resb 200h ; VBE mode info & disk buffer
+mi_list resb 100h ; VBE mode list
+
section .text
org 7C00h
;;
@@ -290,6 +306,21 @@
mov [ImageSectors],ax ; boot file sectors
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
@@ -298,6 +329,9 @@
call crlf
%endif
+%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
@@ -318,6 +352,8 @@
call crlf
%endif
+%endif
+
found_drive:
; Some BIOSes apparently have limitations on the size
; that may be loaded (despite the El Torito spec being very
@@ -390,6 +426,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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -571,6 +610,7 @@
call writehex2
call crlf
jmp .found_drive ; Pray that this works...
+%endif
fatal_error:
mov si,nothing_msg
@@ -630,10 +670,17 @@
;
getlinsec:
mov si,dapa ; Load up the DAPA
- mov [si+4],bx
- mov bx,es
- mov [si+6],bx
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
+ 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]
@@ -660,14 +707,72 @@
; 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
+
+ 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
+.noeject:
+
dec byte [RetryCount]
jz .real_error
push ax
@@ -716,6 +821,17 @@
mov fs,ax
mov gs,ax
sti
+
+ 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
@@ -765,6 +881,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
+
;
; El Torito spec packet
;
@@ -912,12 +1031,21 @@
inc al
loop mkkeymap
+ test byte [KbdFlags],3
+ jpe .nogfx ; left xor right shift: skip BIOS calls/no gfx
+ mov byte [do_nogfx],1
+ mov byte [no_fkeys],1 ; no special F-key processing
+.nogfx:
+
;
; Now, we need to sniff out the actual filesystem data structures.
; mkisofs gave us a pointer to the primary volume descriptor
; (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
@@ -967,6 +1095,9 @@
call crlf
%endif
.no_isolinux_dir:
+ ret
+
+get_fs_struct_done:
;
; Locate the configuration file
@@ -1562,6 +1693,10 @@
%include "strcpy.inc" ; strcpy()
%include "rawcon.inc" ; Console I/O w/o using the console functions
+%include "suse.inc" ; most of the new stuff is in suse.inc
+%include "gfxlogo.inc" ; add gfx things
+
+
; -----------------------------------------------------------------------------
; Begin data section
; -----------------------------------------------------------------------------
@@ -1581,7 +1716,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.'
@@ -1606,6 +1742,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
@@ -1672,7 +1809,6 @@
OnerrorLen dw 0 ; Bytes in onerror command
KbdTimeOut dw 0 ; Keyboard timeout (if any)
CmdLinePtr dw cmd_line_here ; Command line advancing pointer
-initrd_flag equ $
initrd_ptr dw 0 ; Initial ramdisk pointer/flag
VKernelCtr dw 0 ; Number of registered vkernels
ForcePrompt dw 0 ; Force prompt
@@ -1719,6 +1855,8 @@
end_of_code equ (ldlinux_end-bootsec)+7C00h
getcbuf equ (end_of_code + 511) & 0FE00h
+; dd getcbuf + trackbufsize
+
; VGA font buffer at the end of memory (so loading a font works even
; in graphics mode.)
vgafontbuf equ 0E000h
--- keywords
+++ keywords
@@ -29,3 +29,10 @@
f10
f11
f12
+initrdsize
+readinfo
+framebuffer
+verbose
+gfxboot
+notice
+disksize
--- keywords.inc
+++ keywords.inc
@@ -77,6 +77,17 @@
%if IS_PXELINUX || IS_ISOLINUX
keyword localboot, pc_localboot
%endif
+%ifdef WITH_GFX
+ keyword initrdsize, pc_setint16, ExpInitRDClust
+ keyword readinfo, pc_setint16, ReadInfo
+ keyword framebuffer, pc_setint16, FrameBuffer
+ keyword verbose, pc_setint16, do_write_msg
+ keyword gfxboot, pc_filecmd, get_gfx_file
+ keyword notice, pc_setint16, gfx_user_note
+%if IS_SYSLINUX
+ keyword disksize, pc_disksize, DiskSize
+%endif
+%endif
keywd_count equ ($-keywd_table)/keywd_size
--- ldlinux.asm
+++ ldlinux.asm
@@ -29,6 +29,9 @@
%ifndef IS_MDSLINUX
%define IS_SYSLINUX 1
%endif
+
+%define WITH_GFX 1
+
%include "macros.inc"
%include "config.inc"
%include "kernel.inc"
@@ -63,9 +66,9 @@
;
; Note: this structure can be added to, but it must
;
-%define vk_power 7 ; log2(max number of vkernels)
+%define vk_power 6 ; log2(max number of vkernels)
%define max_vk (1 << vk_power) ; Maximum number of vkernels
-%define vk_shift (16-vk_power) ; Number of bits to shift
+%define vk_shift (15-vk_power) ; Number of bits to shift
%define vk_size (1 << vk_shift) ; Size of a vkernel buffer
struc vkernel
@@ -79,7 +82,7 @@
endstruc
%ifndef DEPEND
-%if (vk_end > vk_size) || (vk_size*max_vk > 65536)
+%if (vk_end > vk_size) || (vk_size*max_vk > 8000h)
%error "Too many vkernels defined, reduce vk_power"
%endif
%endif
@@ -91,10 +94,10 @@
;
; 0000h - main code/data segment (and BIOS segment)
;
-real_mode_seg equ 5000h
-fat_seg equ 3000h ; 128K area for FAT (2x64K)
-vk_seg equ 2000h ; Virtual kernels
-xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
+real_mode_seg equ 7000h
+fat_seg equ 4800h ; up to 128K area for FAT (2x64K)
+vk_seg equ 6800h ; Virtual kernels
+xfer_buf_seg equ 8000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
; ---------------------------------------------------------------------------
@@ -110,6 +113,9 @@
; trackbuf ends at 5000h
+; VGA font buffer
+vgafontbuf equ 5000h
+
;
; Constants for the xfer_buf_seg
;
@@ -122,7 +128,7 @@
xbs_vgatmpbuf equ 2*trackbufsize
- absolute 5000h ; Here we keep our BSS stuff
+ absolute 7000h ; Here we keep our BSS stuff
VKernelBuf: resb vk_size ; "Current" vkernel
alignb 4
AppendBuf resb max_cmd_len+1 ; append=
@@ -219,6 +225,15 @@
alignb 4
default_cmd resb max_cmd_len+1 ; "default" command line
+InitRDClust resw 1 ; Initrd size in clusters
+InitRDSize resd 1 ; Initrd size in bytes
+Splashat resd 1 ; Load address (linear) for splash
+SplashClust resw 1 ; Splash size in clusters
+SplashName resb 11 ; Mangled Splash image name
+SplashCName resb 13 ; Unmangled Splash image name
+FATSegment resb 2 ; FAT segment
+
+
section .text
org 7C00h
;
@@ -712,6 +727,7 @@
; We can really only rely on a single sector having been loaded. Hence
; we should load the FAT into RAM and start chasing pointers...
;
+
xor ax,ax
cwd
inc dx ; DX:AX <- 64K
@@ -719,13 +735,26 @@
mov si,ax
push es
- mov bx,fat_seg ; Load into fat_seg:0000
- mov es,bx
mov eax,[bsHidden] ; Hidden sectors
add edx,[bxResSectors]
add eax,edx
mov ecx,[bxFATsecs] ; Sectors/FAT
+
+ mov bx,fat_seg ; Load into fat_seg:0000
+
+ ; calculate start of fat buffer segment
+ cmp ch,1 ; oops, > 128k?
+ jae update_fat_50
+ mov bx,cx
+ shl bx,5
+ neg bx
+ add bx,fat_seg + 2000h
+update_fat_50:
+
+ mov [FATSegment],bx
+ mov es,bx
+
fat_load_loop:
mov ebp,ecx ; Make sure high EBP = 0
cmp bp,si
@@ -869,7 +898,7 @@
mov bp,si ; Remaining sector count
jmp short .getchunk
.lastchunk: pop eax
- call getlinsec
+ call getlinsec2
pop cx
pop si
popf
@@ -881,10 +910,13 @@
; getlinsecsr: save registers, call getlinsec, restore registers
;
getlinsecsr: pushad
- call getlinsec
+ call getlinsec2
popad
ret
+getlinsec2:
+ jmp near getlinsec
+
;
; nextcluster: Advance a cluster pointer in SI to the next cluster
; pointed at in the FAT tables. CF=0 on return if end of file.
@@ -895,7 +927,7 @@
nextcluster_fat12:
push bx
push ds
- mov bx,fat_seg
+ mov bx,[FATSegment]
mov ds,bx
mov bx,si ; Multiply by 3/2
shr bx,1 ; CF now set if odd
@@ -916,10 +948,11 @@
nextcluster_fat16:
push ax
push ds
- mov ax,fat_seg
+ mov ax,[FATSegment]
shl si,1
jnc .seg0
- mov ax,fat_seg+1000h
+ mov ax,[FATSegment]
+ add ax,1000h
.seg0: mov ds,ax
mov si,[si]
cmp si,0FFF0h
@@ -1054,6 +1087,12 @@
inc al
loop mkkeymap
+ test byte [KbdFlags],3
+ jpe .no_gfx ; left xor right shift: skip BIOS calls/no gfx
+ mov byte [do_nogfx],1
+ mov byte [no_fkeys],1 ; no special F-key processing
+.no_gfx:
+
;
; Load configuration file
;
@@ -1088,6 +1127,10 @@
; abort_check: let the user abort with <ESC> or <Ctrl-C>
;
abort_check:
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ ret
+.nogfx:
call pollchar
jz ac_ret1
pusha
@@ -1173,7 +1216,7 @@
mov [EndofDirSec],ax ; End of loaded
pop eax
mov bx,trackbuf
- call getlinsecsr
+ call dir_cache
mov si,trackbuf
dir_test_name: cmp byte [si],0 ; Directory high water mark
je dir_return ; Failed
@@ -1203,6 +1246,63 @@
pop bp
ret
+; like getlinsecsr, but read from cache, if possible
+dir_cache:
+ cmp byte [UserFont],0
+ jz dir_cache_20
+ jmp getlinsecsr ; cache is shared with vgafontbuf
+dir_cache_20:
+ cmp eax,[DirCacheStart]
+ jnz dir_cache_50
+ cmp bp,[DirCacheSectors]
+ jnz dir_cache_50
+ or bp,bp
+ jz dir_cache_50
+
+ pusha
+ mov di,bx
+ mov si,vgafontbuf
+ mov ax,[bsBytesPerSec]
+ mul bp
+ xchg ax,cx
+ rep movsb
+ popa
+
+ ret
+dir_cache_50:
+ call getlinsecsr
+
+ pusha
+ xchg ax,cx
+ mov ax,[bsBytesPerSec]
+ mul bp
+ xchg ax,cx
+ or cx,cx
+ jz dir_cache_80
+ cmp cx,1000h ; smaller than vgafontbuf and trackbuf
+ ja dir_cache_80
+
+ mov [DirCacheStart],eax
+ mov [DirCacheSectors],bp
+
+ mov di,vgafontbuf
+ mov si,bx
+ push ds
+ push es
+
+ push es
+ push ds
+ pop es
+ pop ds
+ rep movsb
+
+ pop es
+ pop ds
+dir_cache_80:
+ popa
+
+ ret
+
;
; writechr: Write a single character in AL to the console without
; mangling any registers; handle video pages correctly.
@@ -1225,6 +1325,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
@@ -1358,6 +1467,9 @@
%include "highmem.inc" ; High memory sizing
%include "strcpy.inc" ; strcpy()
+%include "suse.inc" ; most of the new stuff is in suse.inc
+%include "gfxlogo.inc" ; add gfx things
+
; -----------------------------------------------------------------------------
; Begin data section
; -----------------------------------------------------------------------------
@@ -1389,7 +1501,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.'
@@ -1399,6 +1512,7 @@
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
crlfloading_msg db CR, LF
loading_msg db 'Loading ', 0
@@ -1447,7 +1561,6 @@
OnerrorLen dw 0 ; Bytes in onerror command
KbdTimeOut dw 0 ; Keyboard timeout (if any)
CmdLinePtr dw cmd_line_here ; Command line advancing pointer
-initrd_flag equ $
initrd_ptr dw 0 ; Initial ramdisk pointer/flag
VKernelCtr dw 0 ; Number of registered vkernels
ForcePrompt dw 0 ; Force prompt
@@ -1457,6 +1570,9 @@
VGAFontSize dw 16 ; Defaults to 16 byte font
UserFont db 0 ; Using a user-specified font
ScrollAttribute db 07h ; White on black (for text mode)
+DirCacheStart dd 0 ; first cached dir sector
+DirCacheSectors dw 0 ; cached sectors
+
;
; Stuff for the command line; we do some trickery here with equ to avoid
; tons of zeros appended to our file and wasting space
@@ -1473,13 +1589,15 @@
end_of_code equ (ldlinux_end-bootsec)+7C00h
getcbuf equ (end_of_code + 511) & 0FE00h
-; VGA font buffer at the end of memory (so loading a font works even
-; in graphics mode.)
-vgafontbuf equ 0E000h
+ absolute getcbuf + trackbufsize
+vbe_buf resb 200h ; VBE2 buffer
+ddc_buf resb 80h ; for DDC info
+mi_buf resb 200h ; VBE mode info & disk buffer
+mi_list resb 100h ; VBE mode list
; This is a compile-time assert that we didn't run out of space
%ifndef DEPEND
-%if (getcbuf+trackbufsize) > vgafontbuf
+%if getcbuf < 7c00h || $ > 10000h
%error "Out of memory, better reorganize something..."
%endif
%endif
--- loadhigh.inc
+++ loadhigh.inc
@@ -43,10 +43,21 @@
.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 .isgfx
+%endif
+
push si
mov si,dot_msg
call cwritestr
pop si
+
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
call abort_check
push eax ; <A> Total bytes to transfer
@@ -65,6 +76,14 @@
push edi ; <C> Target buffer
mov cx,ax
xor bx,bx ; ES:0
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ call gfx_progress_update
+.nogfx:
+%endif
+
call getfssec ; Load the data into xfer_buf_seg
pop edi ; <C> Target buffer
pop ecx ; <B> Byte count this round
--- Makefile
+++ Makefile
@@ -18,7 +18,7 @@
OSTYPE = $(shell uname -msr)
CC = gcc
INCLUDE =
-CFLAGS = -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
+CFLAGS = -W -Wall -O2 -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
PIC = -fPIC
LDFLAGS = -O2 -s
AR = ar
@@ -26,7 +26,7 @@
NASM = nasm -O99
NINCLUDE =
-BINDIR = /usr/bin
+BINDIR = /usr/sbin
LIBDIR = /usr/lib
AUXDIR = $(LIBDIR)/syslinux
INCDIR = /usr/include
@@ -55,7 +55,7 @@
# mingw suite installed
BTARGET = kwdhash.gen version.gen ldlinux.bss ldlinux.sys ldlinux.bin \
pxelinux.0 mbr.bin isolinux.bin isolinux-debug.bin \
- libsyslinux.a syslinux.exe $(LIB_SO)
+ libsyslinux.a $(LIB_SO)
ITARGET = syslinux.com syslinux syslinux-nomtools copybs.com gethostip \
mkdiskimage
DOCS = COPYING NEWS README TODO BUGS *.doc sample menu com32
@@ -68,7 +68,7 @@
INSTALL_BIN = syslinux gethostip ppmtolss16 lss16toppm
# Things to install in /usr/lib/syslinux
INSTALL_AUX = pxelinux.0 isolinux.bin isolinux-debug.bin \
- syslinux.com syslinux.exe copybs.com memdisk/memdisk
+ syslinux.com copybs.com memdisk/memdisk
# Things to install in /usr/lib
INSTALL_LIB = $(LIB_SO) libsyslinux.a
# Things to install in /usr/include
@@ -104,7 +104,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 suse.inc gfxlogo.inc
$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l ldlinux.lst -o ldlinux.bin ldlinux.asm
@@ -112,17 +112,19 @@
$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l pxelinux.lst -o pxelinux.bin pxelinux.asm
-isolinux.bin: isolinux.asm kwdhash.gen version.gen
+isolinux.bin: isolinux.asm kwdhash.gen version.gen suse.inc gfxlogo.inc
$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l isolinux.lst -o isolinux.bin isolinux.asm
+ ./add_crc $@
pxelinux.0: pxelinux.bin
cp pxelinux.bin pxelinux.0
# Special verbose version of isolinux.bin
-isolinux-debug.bin: isolinux-debug.asm kwdhash.gen
+isolinux-debug.bin: isolinux-debug.asm kwdhash.gen suse.inc gfxlogo.inc
$(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l isolinux-debug.lst -o isolinux-debug.bin isolinux-debug.asm
+ ./add_crc $@
ldlinux.bss: ldlinux.bin
dd if=ldlinux.bin of=ldlinux.bss bs=512 count=1
@@ -212,7 +214,7 @@
dist: tidy
for dir in . sample memdisk ; do \
- ( cd $$dir && rm -f *~ \#* core ) ; \
+ ( cd $$dir && rm -f *~ \#* core *.lst ) ; \
done
local-spotless:
--- memdisk/init.S16
+++ memdisk/init.S16
@@ -42,7 +42,7 @@
_start:
jmp start
- # This is the setup header, and it must start at %cs:2 (old 0x9020:2)
+/* This is the setup header, and it must start at %cs:2 (old 0x9020:2) */
.ascii "HdrS" # header signature
.word 0x0203 # header version number (>= 0x0105)
@@ -57,7 +57,7 @@
# See Documentation/i386/boot.txt for
# assigned ids
- # flags, unused bits must be zero (RFU) bit within loadflags
+/* flags, unused bits must be zero (RFU) bit within loadflags */
loadflags:
LOADED_HIGH = 1 # If set, the kernel is loaded high
CAN_USE_HEAP = 0x80 # If set, the loader also has set
--- memdisk/Makefile
+++ memdisk/Makefile
@@ -20,7 +20,7 @@
ALIGN := $(call gcc_ok,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0)
CC = gcc $(M32)
-CFLAGS = -g -W -Wall -Os -fomit-frame-pointer -march=i386 $(ALIGN) \
+CFLAGS = -g -W -Wall -O2 -fomit-frame-pointer -march=i386 $(ALIGN) \
-DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"'
LDFLAGS = -g
INCLUDE = -I../com32/include
--- parseconfig.inc
+++ parseconfig.inc
@@ -266,6 +266,20 @@
;
pc_comment equ pc_getline ; Get a line and discard
+%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 [getlinsec2 + 1], getlinsec3 - getlinsec2 - 3
+.err: ret
+%endif
+
;
; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
;
--- README.SuSE
+++ README.SuSE
@@ -0,0 +1,50 @@
+syslinux/isolinux support a graphical boot screen using VESA BIOS
+extensions. (Note that this is different from the graphics support that
+syslinux comes with which uses a 640x480, 16 colors VGA mode).
+
+To use it you have to prepare a special boot logo file and put a line like
+this into syslinux.cfg/iso.linux.cfg:
+
+ gfxboot bootscreen
+
+The tools to create 'bootscreen' 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 for the picture overlaps the comboot loading area.
+
+
+Before starting the Linux kernel syslinux will get some info from the BIOS.
+To control this, there are some new options in syslinux.cfg:
+
+ - readinfo
+
+ "readinfo 1" enables the above feature; the default is 0
+ "readinfo 2" enables even features
+
+ - framebuffer
+
+ "framebuffer 1" will get a video mode list from the VESA
+ BIOS and select an appropriate video mode for the linux kernel
+
+ - verbose
+
+ "verbose 1" enables some debug messages
+
+You can have a boot disk with a file system that spans several disks.
+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).
+
+
+To make room for the graphics the maximum number of menu entries had to be
+reduced. syslinux can have 64, isolinux 32 entries (used to be 128 and 64
+resp.). If you need more you can apply more-menu-entries.dif (included in
+the syslinux source rpm) and get the original number back.
+
--- runkernel.inc
+++ runkernel.inc
@@ -52,8 +52,20 @@
kernel_sane: push ax
push dx
push si
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jnz .isgfx
+ call hide_vmode
+%endif
+
mov si,loading_msg
call cwritestr
+
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
;
; Now start transferring the kernel
;
@@ -116,6 +128,56 @@
mov si,KernelCName ; Unmangled kernel name
mov cx,[KernelCNameLen]
rep movsb
+
+%ifdef WITH_GFX
+;
+; Insert special linuxrc data here
+;
+ cmp byte [lxrc_data1],0
+ jz .nosusedata
+ mov si,lxrc_data
+ call str_copy
+.nosusedata:
+
+ cmp byte [gfx_ok],0
+ jnz .isgfx
+
+ cmp byte [video_mode],0
+ jnz .vmode_10
+ mov si,opt_textmode
+ call str_copy
+.vmode_10:
+ cmp byte [video_mode],1
+ jnz .vmode_20
+ mov eax,640 + (480 << 16)
+ jmp .vmode_40
+.vmode_20:
+ cmp byte [video_mode],2
+ jnz .vmode_30
+ mov eax,800 + (600 << 16)
+ jmp .vmode_40
+.vmode_30:
+ cmp byte [video_mode],3
+ jnz .vmode_90
+ mov eax,1024 + (768 << 16)
+.vmode_40:
+ push di
+ call find_fb
+ pop di
+ or cx,cx
+ jz .vmode_90
+ mov si,opt_video_mode
+ xchg ax,cx
+ xchg al,ah
+ call byte_to_hex
+ mov al,ah
+ call byte_to_hex
+ mov si,opt_video
+ call str_copy
+.vmode_90:
+.isgfx:
+%endif
+
mov al,' ' ; Space
stosb
@@ -124,6 +186,18 @@
mov si,[CmdOptPtr] ; Options from user input
call strcpy
+%ifdef WITH_GFX
+; debug: print final kernel command line
+ push ds
+ push es
+ pop ds
+ mov si,cmd_line_here
+ call xwritestr
+ pop ds
+ mov si,crlf_msg
+ call xwritestr
+%endif
+
;
; Scan through the command line for anything that looks like we might be
; interested in. The original version of this code automatically assumed
@@ -144,6 +218,12 @@
je is_vga_cmd
cmp eax,'mem='
je is_mem_cmd
+
+%ifdef WITH_GFX
+ cmp eax,'SLX='
+ je is_slx_cmd
+%endif
+
%if IS_PXELINUX
cmp eax,'keep' ; Is it "keeppxe"?
jne .notkeep
@@ -199,11 +279,58 @@
%endif
mov [cs:HighMemSize],ebx
jmp short skip_this_opt
+
+%ifdef WITH_GFX
+is_slx_cmd:
+ add si,byte 4
+ call parseint
+ jc skip_this_opt ; Not an integer
+ mov [cs:SLXOption],bx
+ jmp short skip_this_opt
+%endif
+
cmdline_end:
push cs ; Restore standard DS
pop ds
sub si,cmd_line_here
mov [CmdLineLen],si ; Length including final null
+
+%ifdef WITH_GFX
+ call boot_hd
+ jnc start_hd_90
+ cmp byte [gfx_ok],0
+ jz start_hd_50
+ mov al,0
+ mov si,err_bad_mbr2
+ xor di,di
+ call gfx_infobox
+ mov si,no_msg
+ jmp abort_load
+start_hd_50:
+ mov si,err_bad_mbr1
+ call cwritestr
+ mov si,crlf_msg
+ jmp abort_load
+start_hd_90:
+
+ call lookup_initrd
+ jnc start_loading
+ cmp word [ExpInitRDClust],byte 0
+ jz near initrd_notthere
+
+start_loading:
+
+ call lookup_splash
+ cmp byte [gfx_ok],0
+ jz kernel_nogfx
+ mov ax,[KernelClust]
+ add ax,[InitRDClust]
+ add ax,[SplashClust]
+ mov si,KernelCName
+ call gfx_progress_init
+kernel_nogfx:
+%endif
+
;
; Now check if we have a large kernel, which needs to be loaded high
;
@@ -241,11 +368,21 @@
; jumping to it.
;
read_kernel:
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jnz .isgfx
+%endif
+
mov si,KernelCName ; Print kernel name part of
call cwritestr ; "Loading" message
mov si,dotdot_msg ; Print dots
call cwritestr
+%ifdef WITH_GFX
+.isgfx:
+%endif
+
mov eax,[HighMemSize]
sub eax,100000h ; Load address
cmp eax,[KernelSize]
@@ -266,8 +403,18 @@
; On exit EDI -> where to load the rest
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jnz .isgfx2
+%endif
+
mov si,dot_msg ; Progress report
call cwritestr
+
+%ifdef WITH_GFX
+.isgfx2:
+%endif
+
call abort_check
pop ecx ; Number of bytes in the initial portion
@@ -282,17 +429,75 @@
mov ax,real_mode_seg ; Set to real mode seg
mov es,ax
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jnz .isgfx3
+%endif
+
mov si,dot_msg
call cwritestr
+%ifdef WITH_GFX
+.isgfx3:
+%endif
+
+
;
; Now see if we have an initial RAMdisk; if so, do requisite computation
; We know we have a new kernel; the old_kernel code already will have objected
; if we tried to load initrd using an old kernel
;
+
+%ifdef WITH_GFX
+%if IS_SYSLINUX
+ cmp byte [InitRDMissing],0
+ jz load_initrd
+
+ ; ok, the initrd is missing, ask user to replace disk
+
+ cmp byte [gfx_ok],0
+ jz load_i_10
+ mov al,0
+ mov si,mod_disk_msga
+ xor di,di
+ call gfx_infobox
+ jmp load_i_20
+load_i_10:
+ mov si,clrln_msg
+ call cwritestr
+ mov si,mod_disk_msg
+ call cwritestr
+ call wait_for_key
+
+load_i_20:
+ call detach_cd
+ ; call reload_boot
+ ; call update_fat
+ call lookup_initrd
+ pushf
+ cmp byte [gfx_ok],0
+ jnz load_i_50
+ mov si,clrln_msg
+ call cwritestr
+load_i_50:
+ popf
+ jc initrd_notthere
+%endif
+%endif
+
load_initrd:
test byte [initrd_flag],1
jz nk_noinitrd
+
+%ifdef WITH_GFX
+ call lookup_splash ; find splash and add size
+ mov edx,[InitRDSize]
+ add edx,3
+ and edx,~3
+ push edx
+ add edx,[splashlen]
+ mov [es:su_ramdisklen],edx
+%else
push es ; ES->real_mode_seg
push ds
pop es ; We need ES==DS
@@ -307,6 +512,8 @@
jz initrd_notthere
mov [es:su_ramdisklen1],ax ; Ram disk length
mov [es:su_ramdisklen2],dx
+%endif
+
mov edx,[HighMemSize] ; End of memory
dec edx
mov eax,[RamdiskMax] ; Highest address allowed by kernel
@@ -319,10 +526,37 @@
sub edx,[es:su_ramdisklen] ; Subtract size of ramdisk
xor dx,dx ; Round down to 64K boundary
mov [es:su_ramdiskat],edx ; Load address
+
+%ifdef WITH_GFX
+ pop eax
+ add edx,eax
+ mov [Splashat],edx ; Load address for splash
+ mov si,[initrd_ptr]
+%endif
+
call loadinitrd ; Load initial ramdisk
+
+%ifdef WITH_GFX
+ cmp word [SplashClust],0
+ jz short initrd_end
+ call loadsplash
+%endif
+
jmp short initrd_end
initrd_notthere:
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ mov si,err_noinitrda
+ mov di,InitRDCName
+ mov al,1
+ call gfx_infobox
+ call do_reboot
+.nogfx:
+%endif
+
mov si,err_noinitrd
call cwritestr
mov si,InitRDCName
@@ -330,18 +564,70 @@
mov si,crlf_msg
jmp abort_load
-no_high_mem: mov si,err_nohighmem ; Error routine
- jmp abort_load
+no_high_mem:
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ mov si,err_nohighmem
+ xor di,di
+ mov al,1
+ call gfx_infobox
+ call do_reboot
+.nogfx:
+%endif
+
+ mov si,err_nohighmem ; Error routine
+ jmp abort_load
initrd_end:
nk_noinitrd:
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ call gfx_progress_done
+ call abort_check
+ jmp update_disk
+.nogfx:
+%endif
+
;
; Abandon hope, ye that enter here! We do no longer permit aborts.
;
call abort_check ; Last chance!!
+%ifdef WITH_GFX
+ mov si,clrln_msg
+%else
mov si,ready_msg
+%endif
+
+ call cwritestr
+
+%ifdef WITH_GFX
+update_disk:
+;
+; if the user has an update disk, give him a chance to insert it now
+;
+ cmp byte [wants_update],0
+ jz .update_done
+
+ cmp byte [gfx_ok],0
+ jz .update_20
+
+ mov al,0
+ mov si,upd_msg_1a
+ xor di,di
+ call gfx_infobox
+ jmp .update_done
+.update_20:
+ mov si,upd_msg_1
call cwritestr
+ call wait_for_key
+.update_done:
+ call gfx_done
+%endif
call vgaclearmode ; We can't trust ourselves after this
@@ -474,6 +760,14 @@
xor ax,ax
int 16h
%endif
+
+%if do_test
+ mov si,test_ok_msg
+ call cwritestr
+ jmp $
+test_ok_msg db 'done.', 0
+%endif
+
;
; Set up segment registers and the Linux real-mode stack
; Note: es == the real mode segment
@@ -514,7 +808,7 @@
;
; Need to be set:
; su_ramdiskat - Where in memory to load
-; su_ramdisklen - Size of file
+; su_ramdisklen - Size of file (WITH_GFX: InitRDSize)
; SI - initrd filehandle/cluster pointer
;
loadinitrd:
@@ -522,8 +816,22 @@
mov ax,real_mode_seg
mov es,ax
mov edi,[es:su_ramdiskat] ; initrd load address
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jnz .isgfx
+%endif
+
push si
+
+%ifdef WITH_GFX
+ mov si,clrln_msg
+ call cwritestr
+ mov si,loading_msg ; Write "Loading "
+%else
mov si,crlfloading_msg ; Write "Loading "
+%endif
+
call cwritestr
mov si,InitRDCName ; Write ramdisk name
call cwritestr
@@ -531,9 +839,296 @@
call cwritestr
pop si
+%ifdef WITH_GFX
+.isgfx:
+ mov eax,[InitRDSize]
+%else
mov eax,[es:su_ramdisklen]
+%endif
+
call load_high ; Load the file
+%ifndef WITH_GFX
call crlf
+%endif
+
pop es ; Restore original ES
ret
+
+
+%ifdef WITH_GFX
+
+;
+; terminate cdrom boot floppy emulation
+;
+detach_cd:
+ test byte [SLXOption],1 ; just make it configurable
+ jnz detach_cd_90
+ push es ; you never know...
+ mov si,trackbuf
+ mov ax,4b00h
+ mov byte [si],13h ; packet size
+ xor dx,dx ; dl: drive 0
+ int 13h ; terminate floppy emulation
+ pop es
+detach_cd_90:
+ ret
+
+;
+; boot mbr, if SLXOption says so
+;
+; CF = 1 if failed
+;
+boot_hd:
+ mov ax,[SLXOption]
+ test al,2 ; should we do it?
+ jz boot_hd_90
+ push es
+ shr ax,2
+%if IS_SYSLINUX
+ xchg [bsDriveNumber],al
+%endif
+ push ax
+ call detach_cd
+%if IS_SYSLINUX
+ xor eax,eax
+ mov es,ax
+ mov bx,trackbuf
+ push bx
+ call getonesec
+%elif IS_ISOLINUX
+ pop dx
+ mov ax,0201h
+ xor cx,cx
+ mov es,cx
+ inc cx
+ xor dh,dh
+ mov bx,trackbuf
+ push bx
+ int 13h
+%endif
+ pop si
+ cmp word [si+0x1fe],0aa55h
+ jnz boot_hd_80
+ cmp word [si], byte 0
+ jz boot_hd_80
+ mov di,7c00h
+ push di
+ mov cx,0x100
+ cld
+ rep movsw
+ call gfx_done
+ ret
+boot_hd_80:
+%if IS_SYSLINUX
+ pop ax
+ mov [bsDriveNumber],al
+%endif
+ pop es
+ and word [SLXOption],byte 0
+ stc
+boot_hd_90:
+ ret
+
+%if 0
+;
+; Doesn't work anyway: FAT area size has been made to fit the initial FAT.
+;
+
+;
+; reload boot block
+;
+reload_boot:
+ push es
+ xor ax,ax
+ xor dx,dx
+ mov es,ax
+ mov bx,trackbuf
+ push bx
+ call getonesec
+ pop si
+ add si,superblock-bootsec
+ mov di,superblock
+ mov cx,superblock_len
+ cld
+ rep movsb
+
+ ; we can't reuse the bootblock code, it wouldn't fit :-((
+
+ ; expand the superblock to dwords
+ xor eax,eax
+ mov si,superblock
+ mov di,SuperInfo
+ mov cx,superinfo_size
+.loop:
+ lodsw
+ dec si
+ stosd ; Store expanded word
+ xor ah,ah
+ stosd ; Store expanded byte
+ loop .loop
+
+ ; rework things below
+
+ movzx ax,[bsFATs] ; Number of FATs
+ mul word [bsFATsecs] ; Get the size of the FAT area
+ add ax,[bsHidden1] ; Add hidden sectors
+ adc dx,[bsHidden2]
+ add ax,[bsResSectors] ; And reserved sectors
+ adc dx,byte 0
+
+ mov [RootDir1],ax ; Location of root directory
+ mov [RootDir2],dx
+ mov [DataArea1],ax
+ mov [DataArea2],dx
+
+ mov ax,32 ; Size of a directory entry
+ mul word [bsRootDirEnts]
+ mov bx,[bsBytesPerSec]
+ add ax,bx ; Round up, not down
+ dec ax
+ div bx ; Now we have the size of the root dir
+ mov [RootDirSize],ax
+
+ add [DataArea1],ax
+ adc word [DataArea2],byte 0
+
+reload_boot_90:
+ pop es
+ ret
+%endif
+
+;
+; look for initrd, get its size and prepare for loading it
+; return: CF = 1 if it wasn't found
+;
+lookup_initrd:
+ and word [InitRDClust], byte 0
+ test byte [initrd_flag],1
+ jz lookup_initrd_90
+ push word [ExpInitRDClust]
+ pop word [InitRDClust]
+ push es ; ES->real_mode_seg
+ push ds
+ pop es ; We need ES==DS
+ mov si,InitRD
+ mov di,InitRDCName
+ call unmangle_name ; Create human-readable name
+ sub di,InitRDCName
+ mov [InitRDCNameLen],di
+ mov di,InitRD
+ call searchdir ; Look for it in directory
+ pop es
+ stc
+ mov byte [InitRDMissing],1 ; remember for later
+ jz lookup_initrd_90
+ mov byte [InitRDMissing],0
+ mov [initrd_ptr],si ; Save cluster pointer
+ mov [InitRDSize],ax ; Size in bytes
+ mov [InitRDSize + 2],dx
+ div word [ClustSize]
+ and dx,dx ; Round up
+ setnz dl
+ movzx dx,dl
+ add ax,dx
+ mov [InitRDClust],ax ; Ramdisk clusters
+lookup_initrd_90:
+ ret
+
+;
+; look for splash, get its size and prepare for loading it
+; return: CF = 1 if it wasn't found
+;
+lookup_splash:
+ and word [SplashClust], byte 0
+ test byte [initrd_flag],1
+ jz lookup_splash_90
+ mov ax,[es:bs_vidmode]
+ mov si,fb_mode_list
+ mov cx,fb_mode_entries
+lookup_splash_10:
+ cmp [si+fb_mode],ax
+ jz lookup_splash_20
+ add si,sizeof_fb_entry
+ loop lookup_splash_10
+ jmp lookup_splash_90
+lookup_splash_20:
+ mov ax,[si+fb_width]
+ call lookup_splash_to_dec
+ mov [SplashCName], eax
+ mov ax,[si+fb_height]
+ call lookup_splash_to_dec
+ mov [SplashCName+4], eax
+ mov [SplashCName+8], dword '.spl'
+ mov [SplashCName+12], byte 0
+ push es
+ push ds
+ pop es
+ mov si,SplashCName
+ mov di,SplashName
+ call mangle_name
+ mov di,SplashName
+ call searchdir
+ pop es
+ stc
+ jz lookup_splash_90
+ mov [splash_ptr],si ; Save cluster pointer
+ mov [splashlen],ax
+ mov [splashlen+2],dx
+ div word [ClustSize]
+ and dx,dx ; Round up
+ setnz dl
+ movzx dx,dl
+ add ax,dx
+ mov [SplashClust],ax ; Splash clusters
+lookup_splash_90:
+ ret
+
+lookup_splash_to_dec:
+ push dx
+ push bx
+ push ecx
+ xor cx,cx
+ xor dx,dx
+ mov bx,10
+ div bx
+ xchg ch,dl
+ div bx
+ xchg cl,dl
+ shl ecx,8
+ div bx
+ xchg cl,dl
+ shl ecx,8
+ mov cl,al
+ mov eax,ecx
+ pop ecx
+ pop bx
+ pop dx
+ add eax,0x30303030
+ ret
+
+
+;
+; Load Splash into high memory
+;
+loadsplash:
+ cmp byte [gfx_ok],0
+ jnz .isgfx
+
+ mov si,clrln_msg
+ call cwritestr
+ mov si,loading_msg ; Write "Loading "
+ call cwritestr
+ mov si,SplashCName ; Write splash name
+ call cwritestr
+ mov si,dotdot_msg ; Write dots
+ call cwritestr
+
+.isgfx:
+ mov si,[splash_ptr]
+ mov edi,[Splashat] ; splash load address
+ mov eax,[splashlen]
+ call load_high ; Load the file
+ ret
+
+%endif
--- suse.inc
+++ suse.inc
@@ -0,0 +1,1346 @@
+;
+; some extra functionality for syslinux
+;
+
+msg_0 db ' ', 0
+msg_1 db 10, 0
+
+vbe_msg_0 db 'looking for VBE...', 13, 10, 0
+vbe_msg_1 db 'VBE ok', 13, 10, 0
+vbe_msg_2 db 'DDC supported', 13, 10, 0
+vbe_msg_3 db 'got EDID record', 13, 10, 0
+vbe_msg_4 db 'VBE >= 2.0, looking for fb modes...', 13, 10, 0
+vbe_msg_5 db ' mode found', 13, 10, 0
+vbe_msg_6 db 'x', 0,
+vbe_msg_7 db 'fb modes broken', 13, 10, 0
+apm_msg_0 db 'looking for APM...', 13, 10, 0
+apm_msg_1 db 'APM ok', 13, 10, 0
+hd_msg_0 db 'reading mbr...', 13, 10, 0
+hd_msg_1 db 'got mbr', 13, 10, 0
+hd_msg_2 db 'edd?', 13, 10, 0
+hd_msg_3 db 'edd ok', 13, 10, 0
+hd_msg_4 db 'drive 8'
+hd_msg_4a db '0h ok', 13, 10, 0
+hd_msg_5 db 'cd type 4 boot', 13, 10, 0
+kbd_msg_0 db 'kbd id?', 13, 10, 0
+kbd_msg_1 db 'got kbd id', 13, 10, 0
+upd_msg_0 db ' Update floppy', 0
+upd_msg_1 db 13, ' '
+ db 13, 'Please insert the driver update floppy/CDROM; then press ENTER to continue.', 0
+upd_msg_1a db 'Please insert the driver update floppy/CDROM.', 0
+mod_disk_msg db 'Please insert module disk 1; then press ENTER to continue.', 0
+mod_disk_msga db 'Please insert module disk 1.', 0
+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
+%if 0
+prod_excl db 'VMware', 0
+prod_excl_end equ $-1
+%endif
+
+do_write_msg db 0, 0 ; set to get some debug messages
+wants_update db 0
+do_nogfx db 0
+no_fkeys db 0
+vmode_shown db 0
+hd_disk db 80h
+dec_buf zb 10h
+opt_textmode db ' textmode=1', 0
+opt_video db ' vga=0x'
+opt_video_mode db '0000', 0
+ddc_timings dw 0 ; standard ddc timing info
+ddc_xtimings dd 0, 0, 0, 0
+ddc_mult dd 0, 1 ; needed for ddc timing calculation
+ dd 3, 4
+ dd 4, 5
+ dd 9, 16
+video_mem dw 0 ; video memory size in 64k units
+video_mode db 1 ; mode index: 0:text, 1:640x480, 2:800x600, 3:1024x768
+video_mode_mask db 0 ; supported modes: bit 2:800x600, bit 3:1024x768
+video_mode_num dw 0 ; mode number
+xread_pack db 10h ; packet size
+ db 0 ; reserved
+ dw 1 ; sector count
+ dw mi_buf ; buffer offset
+xread_pack_seg dw 0 ; buffer segment
+ dd 0, 0 ; sector number
+
+; framebuffer mode list
+; Don't rearrange offsets, they're used in gfxboot, too!
+fb_mode equ 0 ; word
+fb_width equ 2 ; word
+fb_height equ 4 ; word, must follow fb_width
+fb_bits equ 6 ; byte
+fb_ok equ 7 ; monitor supports it
+sizeof_fb_entry equ 8
+
+fb_mode_entries equ 16
+fb_mode_list times fb_mode_entries * sizeof_fb_entry db 0
+
+lxrc_ptr dw lxrc_data1
+lxrc_data db 0
+lxrc_data1 zb 0fah
+
+splash_ptr dw 0 ; splash pointer
+splashlen dd 0 ; splash len
+FrameBuffer dw 0 ; Add an appropriate vga= line for kernel fb's
+ReadInfo dw 0 ; Get some info from BIOS
+ExpInitRDClust dw 0 ; Expected ramdisk size in clusters
+InitRDMissing db 0 ; Set if it was missig
+initrd_flag db 0 ; used to be overlayed with initrd_ptr !?
+SLXOption dw 0 ; control sysliux via cmdline
+DiskSize dw 0 ; unlimited
+CurrentDisk db 0 ; current disk
+
+err_bad_mbr1 db CR, LF,
+err_bad_mbr2 db 'Failed to start from Harddisk', 0
+load_gfx_msg db 'Loading...', 0
+no_msg db 0
+clrln_msg db 0dh, ' ', 0dh, 0
+gfx_ok db 0
+
+;
+; Read VBE info.
+;
+; es = ds!
+;
+get_vbe_info:
+ mov di,vbe_buf
+ mov dword [di],32454256h ; 'VBE2'
+ and word [di+4],byte 0 ; just in case
+ mov ax,4f00h
+ int 10h
+ cmp ax,4fh
+ jz get_vbe_info_90
+ ; no vbe support: set vbe version to 0
+ and word [di+4],byte 0
+ stc
+get_vbe_info_90:
+ ret
+;
+; Read EDID record via DDC
+;
+read_ddc:
+ pushad ; don't modify any regs
+ push es
+ push ds
+ pop es
+ mov si,vbe_msg_0
+ call xwritestr
+ call get_vbe_info
+ jc near read_ddc_done
+ mov ax,[vbe_buf+12h]
+ mov [video_mem],ax
+ mov si,vbe_msg_1
+ call xwritestr
+ xor cx,cx
+ xor dx,dx
+ mov ax,4f15h
+ mov bl,0
+ int 10h
+ cmp ax,4fh
+ jnz near read_ddc_done
+ mov si,vbe_msg_2
+ call xwritestr
+ push ds
+ pop es
+ mov di,ddc_buf
+ push di
+ mov cx,80h
+ xor ax,ax
+ rep stosb
+ pop di
+ mov ax,4f15h
+ mov bl,1
+ xor cx,cx
+ xor dx,dx
+ int 10h
+ cmp ax,4fh
+ jnz near read_ddc_done
+ mov si,vbe_msg_3
+ call xwritestr
+ mov bx,ddc_buf
+
+ mov al,[bx+23h]
+ mov [ddc_timings],al
+ mov al,[bx+24h]
+ mov [ddc_timings+1],al
+
+ mov cx,4
+ lea si,[bx+26h]
+ mov di,ddc_xtimings
+read_ddc_40:
+ lodsb
+ cmp al,1
+ jbe read_ddc_70
+
+ movzx ebp,al
+ add bp,byte 31
+ shl bp,3
+
+ mov al,[si]
+ shr al,6
+ jz read_ddc_70
+ movzx bx,al
+ shl bx,3
+
+ mov eax,ebp
+ mul dword [bx+ddc_mult]
+ div dword [bx+ddc_mult+4]
+
+ jz read_ddc_70
+
+ shl eax,16
+ add eax,ebp
+ mov [di],eax
+
+read_ddc_70:
+ inc si
+ add di,4
+ loop read_ddc_40
+
+read_ddc_done:
+ pop es
+ popad
+ ret
+
+; get apm capabilities & VBE video memory size
+read_apm:
+ pushad ; don't modify any regs
+ push es
+ push ds
+ pop es
+
+ mov si,[lxrc_ptr]
+ mov byte [si],','
+ inc word [lxrc_ptr]
+
+ mov si,apm_msg_0
+ call xwritestr
+ mov ax,5300h
+ xor bx,bx
+ int 15h
+ jc read_apm_done
+ push cx
+ push ax
+ mov si,apm_msg_1
+ call xwritestr
+ pop ax
+
+ mov si,[lxrc_ptr]
+
+ shl ah,4
+ and al,0fh
+ or al,ah
+ call byte_to_hex
+
+ pop ax
+ call byte_to_hex
+
+ ; add VBE version info
+
+ mov ax,[vbe_buf+4]
+ shl ah,4
+ and al,0fh
+ or al,ah
+ call byte_to_hex
+
+ ; add video mem size
+
+ mov ax,[vbe_buf+12h]
+ xchg al,ah
+ call byte_to_hex
+ xchg al,ah
+ call byte_to_hex
+
+ mov [lxrc_ptr],si
+ mov byte [si],0
+
+read_apm_done:
+ pop es
+ popad
+ ret
+
+; read 1st hd sector & compute crc
+read_hd:
+ pushad ; don't modify any regs
+ push es
+ push ds
+ pop es
+
+ mov si,[lxrc_ptr]
+ mov byte [si],','
+ inc word [lxrc_ptr]
+ mov byte [si + 1],0
+
+ ; maybe we booted from cdrom with an hd image
+ ; (special magic from our mbr loader)
+ cmp byte [7c03h],19
+ jnz read_hd_03
+ mov byte [hd_disk],81h
+ mov byte [hd_msg_4a],'1'
+ mov si,hd_msg_5
+ call xwritestr
+read_hd_03:
+
+ mov si,hd_msg_2
+ call xwritestr
+
+ mov ah,41h
+ mov bx,55aah
+ mov dl,[hd_disk]
+ int 13h
+ mov bp,0
+ jc read_hd_05
+ cmp bx,0aa55h
+ jnz read_hd_05
+ test cl,1
+ jz read_hd_05
+
+ inc bp
+
+ mov si,hd_msg_3
+ call xwritestr
+
+read_hd_05:
+ mov si,hd_msg_0
+ call xwritestr
+
+ mov ah,10h
+ mov dl,[hd_disk]
+ push bp
+ int 13h
+ pop bp
+ jc near read_hd_done
+ cmp ah,0
+ jnz near read_hd_done
+
+ mov si,hd_msg_4
+ call xwritestr
+
+ mov ax,0201h
+ mov cx,1
+ mov dh,ch ; dh = 0
+ mov dl,[hd_disk]
+ mov bx,mi_buf
+ push bp
+ int 13h
+ pop bp
+ jc near read_hd_done
+
+ mov si,hd_msg_1
+ call xwritestr
+
+ mov si,mi_buf
+ xor ebx,ebx
+ mov cx,200h
+ mov edi,57
+ stc
+ sbb eax,eax
+read_hd_20:
+ mov bl,[si]
+ inc si
+ add eax,ebx
+ mul edi
+ dec cx
+ jnz read_hd_20
+
+ mov si,[lxrc_ptr]
+
+ mov bx,4
+read_hd_40:
+ rol eax,8
+ call byte_to_hex
+ dec bx
+ jnz read_hd_40
+
+ or bp,bp
+ jz read_hd_90
+ mov byte [si],'.'
+ inc si
+
+
+ ; get device path info
+
+ push si
+ mov ax,4800h
+ mov dl,[hd_disk]
+ mov si,mi_buf
+ mov di,si
+ push ds
+ pop es
+ mov cx,100h
+ rep stosb
+ ; some BIOSes use only one byte as buffer len
+ mov word [si],0ffh
+ int 13h
+ pop si
+ jc read_hd_90
+
+ mov bx,mi_buf
+ cmp word [bx],38h
+ jb read_hd_90
+
+ cmp word [bx+1eh],0beddh
+ jnz read_hd_90
+
+ cmp dword [bx+24h],20494350h ; 'PCI '
+ jnz read_hd_90
+
+ mov al,[bx+30h]
+ call byte_to_hex
+ mov al,[bx+31h]
+ call byte_to_hex
+ mov al,[bx+32h]
+ call byte_to_hex
+
+read_hd_90:
+ mov [lxrc_ptr],si
+ mov byte [si],0
+
+read_hd_done:
+ pop es
+ popad
+ ret
+
+; read keyboard id
+read_kbd:
+ pushad ; don't modify any regs
+ push es
+ push ds
+ pop es
+
+ mov si,[lxrc_ptr]
+ mov byte [si],','
+ inc word [lxrc_ptr]
+
+ mov si,kbd_msg_0
+ call xwritestr
+ mov ax,900h
+ int 16h
+ test al,10h
+ jz read_kbd_done
+
+ mov si,kbd_msg_1
+ call xwritestr
+ mov ah,0ah
+ xor bx,bx
+ int 16h
+
+ mov si,[lxrc_ptr]
+ mov al,bh
+ call byte_to_hex
+ mov al,bl
+ call byte_to_hex
+
+ mov [lxrc_ptr],si
+ mov byte [si],0
+
+read_kbd_done:
+ pop es
+ popad
+ ret
+
+;
+; Read VBE2 mode info
+;
+; We use the VBE record returned earlier by the DDC calls.
+;
+; Go through the mode list and look for a video mode with frame buffer
+; support.
+;
+read_vbe_modes:
+ pushad ; don't modify any regs
+ push es
+ push gs
+ push ds
+ pop es
+
+ ; always support this mode
+ mov eax,640 + (480 << 16)
+ xor cx,cx
+ mov dh,4
+ call add_fb_to_list2
+ call enable_fb
+
+ cmp word [FrameBuffer],byte 0
+ jz near read_vbe_done
+ cmp word [vbe_buf+4],200h
+ jb near read_vbe_done
+ mov si,vbe_msg_4
+ call xwritestr
+ ; do it again, data structures may have been overwritten
+ ; by ddc call
+ call get_vbe_info
+ jc near read_vbe_done
+
+%if 0
+ xor ebx,ebx
+ lgs bx,[vbe_buf+1ah]
+ mov eax,gs
+ shl eax,4
+ add eax,ebx
+ or eax,eax
+ jz read_vbe_10
+ cmp eax,100000h
+ jae read_vbe_10
+ call check_prod_excl
+ jc read_vbe_10
+ mov si,vbe_msg_7
+ call xwritestr
+ jmp near read_vbe_done
+read_vbe_10:
+%endif
+
+ ; copy the list
+ lgs si,[vbe_buf+0eh]
+ mov cx,127 ; buffer has 128 entries
+ push ds
+ pop es
+ mov di,mi_list
+ mov bx,di
+ cld
+read_vbe_15:
+ gs lodsw
+ stosw
+ cmp ax,0xffff
+ jz read_vbe_17
+ loop read_vbe_15
+read_vbe_17:
+ mov word [di],0xffff
+read_vbe_20:
+ mov cx,[bx]
+ inc bx
+ inc bx
+ cmp cx,0xffff
+ jz read_vbe_50
+
+ mov ax,4f01h
+ mov di,mi_buf
+ push cx
+ int 10h
+ pop cx
+ cmp ax,4fh
+ jnz read_vbe_20
+
+ test byte [mi_buf],1 ; mode supported?
+ jz read_vbe_20
+ cmp dword [mi_buf+28h],byte 0 ; frame buffer start
+ jz read_vbe_20
+
+ mov eax,[mi_buf+12h] ; size
+ mov dl,[mi_buf+1bh] ; color mode (aka memory model)
+ mov dh,[mi_buf+19h] ; color depth
+ cmp dl,6 ; direct color
+ jnz read_vbe_30
+ sub dh,[mi_buf+25h] ; reserved color bits
+ jmp read_vbe_40
+read_vbe_30:
+ cmp dl,4 ; PL8
+ jnz read_vbe_20
+ mov dh,8
+read_vbe_40:
+
+ ; cx mode
+ ; eax resolution
+ ; dh color bits
+
+ call add_fb_to_list
+ jmp read_vbe_20
+
+read_vbe_50:
+ mov eax,640 + (480 << 16)
+ call enable_fb
+
+ test word [ddc_timings],0ef03h
+ jnz read_vbe_51
+ cmp word [video_mem],0x3e ; at least 4MB-128k
+ jb read_vbe_52
+read_vbe_51:
+ mov eax,800 + (600 << 16)
+ call enable_fb
+
+read_vbe_52:
+ test word [ddc_timings],0f00h
+ jnz read_vbe_53
+ cmp word [video_mem],0x200 ; at least 32MB
+ jb read_vbe_54
+read_vbe_53:
+ mov eax,1024 + (768 << 16)
+ call enable_fb
+
+read_vbe_54:
+ test word [ddc_timings],0100h
+ jz read_vbe_56
+ mov eax,1280 + (1024 << 16)
+ call enable_fb
+
+read_vbe_56:
+ mov cx,4
+ mov si,ddc_xtimings
+read_vbe_58:
+ lodsd
+ push si
+ push cx
+ call enable_fb
+ pop cx
+ pop si
+ loop read_vbe_58
+
+ ; preselect mode for text interface
+
+ mov eax,800 + (600 << 16)
+ call find_fb
+ cmp dl,1
+ jb read_vbe_60
+ or byte [video_mode_mask],1 << 2
+ cmp dl,2
+ jb read_vbe_60
+ mov byte [video_mode],2
+read_vbe_60:
+
+ mov eax,1024 + (768 << 16)
+ call find_fb
+ cmp dl,1
+ jb read_vbe_62
+ or byte [video_mode_mask],1 << 3
+ cmp dl,2
+ jb read_vbe_62
+ mov byte [video_mode],3
+read_vbe_62:
+
+read_vbe_done:
+ pop gs
+ pop es
+ popad
+ ret
+
+
+%if 0
+; go through exclude list
+;
+; in: gs:bx product string
+; out: CF 0/1 found/not found
+;
+check_prod_excl:
+ cld
+ mov si,prod_excl
+check_prod_excl_20:
+ mov di,bx
+ dec di
+check_prod_excl_30:
+ inc di
+ lodsb
+ or al,al
+ jz check_prod_excl_90
+ cmp al,[gs:di]
+ jz check_prod_excl_30
+check_prod_excl_40:
+ lodsb
+ or al,al
+ jnz check_prod_excl_40
+ cmp si,prod_excl_end
+ jb check_prod_excl_20
+ stc
+check_prod_excl_90:
+ ret
+%endif
+
+
+; add fb mode to mode list
+;
+; cx mode
+; eax resolution
+; dh color bits
+;
+; only added if color bits are 8 or 16 and resolution is at least 640x480
+;
+; must not change bx & eax
+;
+add_fb_to_list:
+ cmp dh,8
+ jz add_fb_10
+ cmp dh,16
+ jnz add_fb_90
+add_fb_to_list2:
+add_fb_10:
+ cmp ax,640
+ jb add_fb_90
+ mov esi,eax
+ shr esi,16
+ cmp si,480
+ jb add_fb_90
+ mov si,fb_mode_list
+ mov bp,fb_mode_entries
+add_fb_20:
+ cmp eax,[si+fb_width]
+ jz add_fb_40
+ cmp byte [si+fb_bits],0
+ jz add_fb_40
+ add si,sizeof_fb_entry
+ dec bp
+ jnz add_fb_20
+ jmp add_fb_90
+add_fb_40:
+ cmp [si+fb_bits],dh
+ jae add_fb_90
+ mov [si+fb_mode],cx
+ or cx,cx
+ jz add_fb_50
+ add byte [si+fb_mode+1],2 ; for linux kernel
+add_fb_50:
+ mov [si+fb_width],eax
+ mov [si+fb_bits],dh
+add_fb_90:
+ ret
+
+
+; tag fb mode as supported
+;
+; eax resolution
+;
+enable_fb:
+ mov si,fb_mode_list
+ mov bp,fb_mode_entries
+ mov edx,eax
+ shr edx,16
+enable_fb_10:
+ cmp byte [si+fb_bits],0
+ jz enable_fb_90
+ cmp [si+fb_width],ax
+ ja enable_fb_50
+ cmp [si+fb_height],dx
+ ja enable_fb_50
+ mov byte [si+fb_ok],1
+enable_fb_50:
+ add si,sizeof_fb_entry
+ dec bp
+ jnz enable_fb_10
+enable_fb_90:
+ ret
+
+
+; find fb mode
+;
+; eax resolution
+;
+; return:
+; dl 0: not found, 1: found but not supp, 2: ok
+; cx mode number
+;
+find_fb:
+ mov si,fb_mode_list
+ mov bp,fb_mode_entries
+ xor dl,dl
+ xor cx,cx
+find_fb_10:
+ cmp byte [si+fb_bits],0
+ jz find_fb_90
+ cmp [si+fb_width],eax
+ jnz find_fb_50
+ mov dl,[si+fb_ok]
+ inc dx
+ mov cx,[si+fb_mode]
+find_fb_50:
+ add si,sizeof_fb_entry
+ dec bp
+ jnz find_fb_10
+find_fb_90:
+ ret
+
+
+; unpack EISA ID
+; ax -> [si]
+;
+unpack_eisa:
+ mov cx,ax
+ shr cx,10
+ and cl,1fh
+ add cl,'A'-1
+ mov [si],cl
+ mov cx,ax
+ shr cx,5
+ and cl,1fh
+ add cl,'A'-1
+ mov [si+1],cl
+ mov cx,ax
+ and cl,1fh
+ add cl,'A'-1
+ mov [si+2],cl
+ add si,3
+ ret
+
+; al -> to hex
+;
+byte_to_hex:
+ mov cl,al
+ shr cl,4
+ call byte_to_hex_10
+ mov cl,al
+ and cl,0fh
+byte_to_hex_10:
+ cmp cl,10
+ jb byte_to_hex_20
+ add cl,7
+byte_to_hex_20:
+ add cl,'0'
+ mov [si],cl
+ inc si
+ ret
+
+;
+; write function
+;
+xwritestr:
+ cmp byte [cs:do_write_msg],0
+ jz xwritestr_10
+ call cwritestr
+xwritestr_10:
+ ret
+
+;
+; ax: Number
+;
+xwritedec:
+ pusha
+ mov si,dec_buf+0fh
+ mov byte [si],0
+xwritedec_20:
+ xor dx,dx
+ mov cx,10
+ div cx
+ add dl,'0'
+ dec si
+ mov [si],dl
+ or ax,ax
+ jnz xwritedec_20
+ call xwritestr
+ popa
+ ret
+
+;
+; see if user wants to use an update disk
+;
+chk_update:
+ cmp byte [gfx_ok],0
+ jz chk_update_nogfx
+ ret
+chk_update_nogfx:
+ pusha
+ clc
+ mov ah,12h
+ int 16h
+ jc chk_update_90
+
+ cmp byte [wants_update],0
+ jnz chk_update_90
+ test ah,0ah ; left or right ALT key
+ jz chk_update_90
+ mov byte [wants_update],1
+ mov cx,183bh
+ mov si,upd_msg_0
+ push ax
+ call cwritestr_xy
+ pop ax
+
+chk_update_90:
+ popa
+ ret
+
+;
+; cl, ch: x,y
+; si: text
+;
+cwritestr_xy:
+ push ds
+ pusha
+ push cx
+ mov ah,3
+ mov bh,0
+ int 10h
+ pop cx
+ push dx
+ mov dx,cx
+ mov ah,2
+ mov bh,0
+ int 10h
+ call cwritestr
+cwritestr_xy_80:
+ pop dx
+ mov ah,2
+ mov bh,0
+ int 10h
+cwritestr_xy_90:
+ popa
+ pop ds
+ ret
+
+;
+; 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
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+vmode_msg_0 db 'F2=Text mode'
+vmode_msg_1 db 'F3=640x480'
+vmode_msg_2 db 'F4=800x600'
+vmode_msg_3 db 'F5=1024x768'
+vmode_msg_clr times vmode_msg_clr - vmode_msg_0 + 3 * 3 db ' '
+vmode_msg_end equ $
+
+show_vmode:
+ push es
+ pusha
+
+ cmp byte [no_fkeys],0
+ jnz near show_vmode_95
+
+ mov ah,3
+ mov bh,0
+ int 10h
+ push dx
+
+ mov byte [vmode_shown],1
+
+ push ds
+ pop es
+
+ mov dx,1800h
+ mov cx,vmode_msg_1 - vmode_msg_0
+ mov bp,vmode_msg_0
+ mov bx,07h
+ cmp byte [video_mode],0
+ jnz show_vmode_10
+ mov bl,70h
+show_vmode_10:
+ mov ax,1300h
+ int 10h
+
+ mov dh,18h
+ mov dl,vmode_msg_1 - vmode_msg_0 + 3
+ mov cx,vmode_msg_2 - vmode_msg_1
+ mov bp,vmode_msg_1
+ mov bx,07h
+ cmp byte [video_mode],1
+ jnz show_vmode_20
+ mov bl,70h
+show_vmode_20:
+ mov ax,1300h
+ int 10h
+
+
+ test byte [video_mode_mask],1 << 2
+ jz show_vmode_40
+
+ mov dh,18h
+ mov dl,vmode_msg_2 - vmode_msg_0 + 2 * 3
+ mov cx,vmode_msg_3 - vmode_msg_2
+ mov bp,vmode_msg_2
+ mov bx,07h
+ cmp byte [video_mode],2
+ jnz show_vmode_30
+ mov bl,70h
+show_vmode_30:
+ mov ax,1300h
+ int 10h
+show_vmode_40:
+
+ test byte [video_mode_mask],1 << 3
+ jz show_vmode_60
+
+ mov dh,18h
+ mov dl,vmode_msg_3 - vmode_msg_0 + 3 * 3
+ mov cx,vmode_msg_clr - vmode_msg_3
+ mov bp,vmode_msg_3
+ mov bx,07h
+ cmp byte [video_mode],3
+ jnz show_vmode_50
+ mov bl,70h
+show_vmode_50:
+ mov ax,1300h
+ int 10h
+show_vmode_60:
+
+
+show_vmode_90:
+ pop dx
+ mov ah,2
+ mov bh,0
+ int 10h
+
+show_vmode_95:
+
+ popa
+ pop es
+ ret
+
+hide_vmode:
+ pusha
+ cmp byte [vmode_shown],0
+ jz hide_vmode_90
+
+ mov ah,3
+ mov bh,0
+ int 10h
+ push dx
+
+ mov dx,1800h
+ mov cx,vmode_msg_end - vmode_msg_clr
+ mov bp,vmode_msg_clr
+ mov bx,07h
+ mov ax,1300h
+ int 10h
+
+ pop dx
+ mov ah,2
+ mov bh,0
+ int 10h
+
+hide_vmode_90:
+ popa
+ ret
+
+process_fkeys:
+ cmp al,1
+ jb process_fkeys_90
+ cmp al,5
+ cmc
+ jc process_fkeys_90
+
+ cmp al,3
+ jnz process_fkeys_20
+ test byte [video_mode_mask],1 << 2
+ jz process_fkeys_90
+process_fkeys_20:
+ cmp al,4
+ jnz process_fkeys_30
+ test byte [video_mode_mask],1 << 3
+ jz process_fkeys_90
+process_fkeys_30:
+
+ mov [video_mode],al
+ sub byte [video_mode],1
+ call show_vmode
+ clc
+process_fkeys_90:
+ ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; string copy
+;
+; ds:si -> es:di
+;
+str_copy:
+ lodsb
+ stosb
+ or al,al
+ jnz str_copy
+ dec di
+ ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; do a reboot
+;
+do_reboot:
+ call gfx_done
+ mov word [472h],1234h
+ push word 0ffffh
+ push word 0
+ retf
+ int 19h
+ jmp $
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; look for a fsc notebook lcd panel and set ddc_timings
+read_fsc:
+ pushad
+ push es
+ push ds
+ cmp word [ddc_timings],byte 0
+ jnz read_fsc_90
+
+ push word 0xf000
+ pop ds
+ xor di,di
+read_fsc_10:
+ cmp dword [di],0x696a7546
+ jnz read_fsc_30
+ cmp dword [di+4],0x20757374
+ jnz read_fsc_30
+ mov cx,0x20
+ xor bx,bx
+ mov si,di
+read_fsc_20:
+ lodsb
+ add bl,al
+ dec cx
+ jnz read_fsc_20
+ or bl,bl
+ jnz read_fsc_30
+ mov al,[di+23]
+ and al,0xf0
+ jnz read_fsc_90
+ mov bl,[di+21]
+ and bx,0xf0
+ shr bx,3
+ mov ax,[cs:bx+fsc_bits]
+ mov [cs:ddc_timings],ax
+ jmp read_fsc_90
+read_fsc_30:
+ add di,0x10
+ jnz read_fsc_10
+read_fsc_90:
+ pop ds
+ pop es
+ popad
+ ret
+
+fsc_bits:
+ dw 0, 0x0004, 0x4000, 0x0200, 0x0100, 0x0200, 0, 0x4000
+ dw 0x0200, 0, 0, 0, 0, 0, 0, 0
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; read gfx data
+get_gfx_file:
+ cmp byte [do_nogfx],0
+ jnz .done
+ push si
+ mov si,load_gfx_msg
+ call cwritestr
+ pop si
+%if IS_SYSLINUX
+ push word [FATSegment]
+ pop word [gfx_mem_end_seg]
+%elif IS_ISOLINUX
+ mov word [gfx_mem_end_seg],vk_seg
+%endif
+ call gfx_init ; Load and display file
+ cmp byte [gfx_ok],0
+ jz .done
+ mov si,crlf_msg
+ call cwritestr
+.done:
+ ret
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Use VESA 2.0 calls to read the EDID monitor record. The Data will
+; later be appended to the kernel command line.
+;
+; Get the APM status from the BIOS.
+;
+get_bios_info:
+ inc byte [no_fkeys]
+ cmp word [ReadInfo],0
+ jz .done
+ dec byte [no_fkeys]
+ mov al,[KbdFlags]
+ and al,3
+ jpo .done ; left xor right shift: skip BIOS calls
+ jz .not_verbose ; !(left and right shift)
+ mov byte [do_write_msg],1
+.not_verbose:
+ call read_ddc ; read Display Data Channel
+ call read_fsc
+ call read_apm ; get APM status
+ cmp word [ReadInfo],1
+ jb .no_disk_read
+ call read_hd ; get crc of 1st hd block
+.no_disk_read:
+ call read_kbd
+ call read_vbe_modes ; get VBE2 mode support
+ mov si,lxrc_data + 1
+ call xwritestr
+ mov si,crlf_msg
+ call xwritestr
+.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
+ call getlinsec
+ 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
+
+boot_disk_msg1 db ''
+
+; 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
+ call getlinsec
+ pop bx
+ mov eax,[es:bx+27h]
+ sub eax,[bxVolumeID]
+ 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
+
+%endif
+
--- ui.inc
+++ ui.inc
@@ -16,6 +16,15 @@
;
call parse_config ; Parse configuration file
no_config_file:
+
+%ifdef WITH_GFX
+ ; vbe things and such
+ call get_bios_info
+
+ ; build gfx menu
+ call gfx_setup_menu
+%endif
+
;
; Check whether or not we are supposed to display the boot prompt.
;
@@ -26,9 +35,27 @@
jz auto_boot ; If neither, default boot
enter_command:
+
+%ifdef WITH_GFX
+ cmp byte [gfx_ok],0
+ jz .nogfx
+ mov di,command_line
+ mov cx,max_cmd_len
+ xor ax,ax
+ xchg ax,[KbdTimeOut] ; only the first time
+ call gfx_input
+ cmp ax,1
+ jnz load_kernel
+.nogfx:
+%endif
+
mov si,boot_prompt
call cwritestr
+%ifdef WITH_GFX
+ call show_vmode
+%endif
+
mov byte [FuncFlag],0 ; <Ctrl-F> not pressed
mov di,command_line
;
@@ -53,6 +80,11 @@
; know the appropriate DX value
time_loop: push cx
tick_loop: push dx
+
+%ifdef WITH_GFX
+ call chk_update
+%endif
+
call pollchar
jnz get_char_pop
mov dx,[BIOS_timer] ; Get time "of day"
@@ -139,6 +171,12 @@
sub al,59 ; F1
jb short get_char_2
show_help: ; AX = func key # (0 = F1, 9 = F10)
+
+%ifdef WITH_GFX
+ call process_fkeys
+ jnc get_char_2
+%endif
+
push di ; Save end-of-cmdline pointer
shl ax,FILENAME_MAX_LG2 ; Convert to pointer
add ax,FKeyName
@@ -190,6 +228,17 @@
stosb
load_kernel: ; Load the kernel now
+
+%if IS_ISOLINUX
+ test byte [gfx_user_note],1
+ jz .noreload
+ pushad
+ ; Maybe clear Files, too?
+ call get_fs_structures
+ popad
+.noreload:
+%endif
+
;
; First we need to mangle the kernel name the way DOS would...
;
@@ -309,6 +358,18 @@
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 di
+ mov al,2
+ call gfx_infobox
+ mov si,no_msg
+ jmp abort_load
+.nogfx:
+%endif
+
call cwritestr
pop si ; KernelCName
call cwritestr
@@ -359,9 +420,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
pop di ; DI -> KernelName