summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-08-08 18:48:35 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-08-08 18:51:30 -0700
commitc8893ccbdbafec7776dc0c190609590a6b30f11c (patch)
treeb9de59c82734bbaf74e84bdb067a613302986ada
parentbf9f683dbef47a44dee4da1607d99a25976560e3 (diff)
parent8e01231be41fd889bcb71604dbda511688ed0f38 (diff)
downloadsyslinux-c8893ccbdbafec7776dc0c190609590a6b30f11c.tar.gz
Merge branch 'master' into core32
-rw-r--r--NEWS5
-rw-r--r--com32/modules/chain.c3
-rw-r--r--core/graphics.inc71
-rw-r--r--core/parsecmd.inc4
-rw-r--r--core/pxelinux.asm2
-rw-r--r--memdisk/memdisk.inc119
-rw-r--r--memdisk/setup.c56
-rw-r--r--modules/gfxboot.asm149
-rw-r--r--utils/isohybrid.in2
9 files changed, 331 insertions, 80 deletions
diff --git a/NEWS b/NEWS
index b6c37f1c..735bed73 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,11 @@ Changes in 3.83:
NBP. This may help avoid a bug in Windows RIS.
* PXELINUX: fix localboot after NBP chainloading on certain
BIOSes (including ASUS A8N-E, but possibly others.)
+ * chain.c32: support chainloaded bootloaders on ISOLINUX.
+ * PXELINUX: allow filenames up to 251 characters.
+ * MEMDISK: fix problems booting from USB on Thinkpads, and
+ possibly other machines or hardware combinations.
+ * isohybrid: fix the -id option.
Changes in 3.82:
* isohybrid: fix the -partok logic for loading from a partition.
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index ceb5470a..bdeb82d5 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -676,8 +676,7 @@ int main(int argc, char *argv[])
} else if (!strcmp(drivename, "boot")) {
const union syslinux_derivative_info *sdi;
sdi = syslinux_derivative_info();
- if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX ||
- sdi->c.filesystem == SYSLINUX_FS_ISOLINUX)
+ if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX)
drive = 0x80; /* Boot drive not available */
else
drive = sdi->disk.drive_number;
diff --git a/core/graphics.inc b/core/graphics.inc
index d530193f..a8d28515 100644
--- a/core/graphics.inc
+++ b/core/graphics.inc
@@ -75,22 +75,26 @@ vgadisplayfile:
mov di,VGARowBuffer
; Pre-clear the row buffer
push di
+ push di
mov cx,640/4
xor eax,eax
rep stosd
pop di
- push di
mov cx,[GraphXSize]
call rledecode ; Decode one row
pop si
+ mov di,VGAPlaneBuffer
+ push di
+ mov bp,640
+ call packedpixel2vga
+ pop si
push es
mov di,0A000h ; VGA segment
mov es,di
mov di,[VGAPos]
- mov bp,640
- call packedpixel2vga
- add word [VGAPos],80
+ call outputvga
pop es
+ add word [VGAPos],640/8
pop cx
loop .drawpixelrow
@@ -160,39 +164,57 @@ rledecode:
;
; DS:SI -> packed pixel string
; BP -> pixel count (multiple of 8)
-; ES:DI -> output
+; DS:DI -> output (four planes)
;
packedpixel2vga:
- mov dx,3C4h ; VGA Sequencer Register select port
- mov al,2 ; Sequencer mask
- out dx,al ; Select the sequencer mask
- inc dx ; VGA Sequencer Register data port
- mov al,1
- mov bl,al
+ xor cx,cx
.planeloop:
- pusha
- out dx,al
+ inc cx
+ push si
+ push bp
.loop1:
- mov cx,8
+ mov bx,8
.loop2:
- xchg cx,bx
lodsb
shr al,cl
- rcl ch,1 ; VGA is bigendian. Sigh.
- xchg cx,bx
- loop .loop2
- mov al,bh
- stosb
+ rcl dl,1 ; VGA is bigendian. Sigh.
+ dec bx
+ jnz .loop2
+ mov [di],dl
+ inc di
sub bp,byte 8
ja .loop1
- popa
- inc bl
- shl al,1
- cmp bl,4
+ pop bp
+ pop si
+ cmp cl,3
jbe .planeloop
ret
;
+; outputvga:
+; Output four subsequent lines of VGA data
+;
+; DS:SI -> four planes @ 640/8=80 bytes
+; ES:DI -> pointer into VGA memory
+;
+outputvga:
+ mov dx,3C4h ; VGA Sequencer Register select port
+ mov al,2 ; Sequencer mask
+ out dx,al ; Select the sequencer mask
+ inc dx ; VGA Sequencer Register data port
+ dec ax ; AL <- 1
+.loop1:
+ out dx,al ; Select the bit plane to write
+ push di
+ mov cx,640/32
+ rep movsd
+ pop di
+ add ax,ax
+ cmp al,8
+ jbe .loop1
+ ret
+
+;
; vgasetmode:
; Enable VGA graphics, if possible; return ZF=1 on success
; DS must be set to the base segment; ES is set to DS.
@@ -328,3 +350,4 @@ VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name
alignb 4
VGARowBuffer resb 640+80 ; Decompression buffer
+VGAPlaneBuffer resb (640/8)*4 ; Plane buffers
diff --git a/core/parsecmd.inc b/core/parsecmd.inc
index 94627b8c..7dfe1eb6 100644
--- a/core/parsecmd.inc
+++ b/core/parsecmd.inc
@@ -117,6 +117,8 @@ VKernelBuf: resb vk_size ; "Current" vkernel
AppendBuf resb max_cmd_len+1 ; append=
Ontimeout resb max_cmd_len+1 ; ontimeout
Onerror resb max_cmd_len+1 ; onerror
+ ; This could be in .uibss but that makes PXELINUX overflow
+ section .bss16
KbdMap resb 256 ; Keyboard map
FKeyName resb MAX_FKEYS*FILENAME_MAX ; File names for F-key help
KernelCNameLen resw 1 ; Length of unmangled kernel name
@@ -132,3 +134,5 @@ InitRDCName resb FILENAME_MAX ; Unmangled initrd name
%endif
MNameBuf resb FILENAME_MAX
InitRD resb FILENAME_MAX
+
+ section .text16
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 3f7cb8c6..f51e7cd6 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -29,7 +29,7 @@
; Some semi-configurable constants... change on your own risk.
;
my_id equ pxelinux_id
-FILENAME_MAX_LG2 equ 7 ; log2(Max filename size Including final null)
+FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null)
FILENAME_MAX equ (1 << FILENAME_MAX_LG2)
NULLFILE equ 0 ; Zero byte == null file name
NULLOFFSET equ 4 ; Position in which to look
diff --git a/memdisk/memdisk.inc b/memdisk/memdisk.inc
index 00537a83..3c79b624 100644
--- a/memdisk/memdisk.inc
+++ b/memdisk/memdisk.inc
@@ -27,11 +27,47 @@
call debug_tracer
db %1
%endmacro
+%macro WRITEHEX2 0-1 al
+%ifnidni %1,al
+ push ax
+ mov al,%1
+ call writehex2
+ pop ax
+%else
+ call writehex2
+%endif
+%endmacro
+%macro WRITEHEX4 0-1 ax
+%ifnidni %1,ax
+ push ax
+ mov ax,%1
+ call writehex4
+ pop ax
+%else
+ call writehex4
+%endif
+%endmacro
+%macro WRITEHEX8 0-1 eax
+%ifnidni %1,eax
+ push eax
+ mov eax,%1
+ call writehex8
+ pop eax
+%else
+ call writehex8
+%endif
+%endmacro
%else ; DEBUG_TRACERS
%macro TRACER 1
%endmacro
+%macro WRITEHEX2 0-1
+%endmacro
+%macro WRITEHEX4 0-1
+%endmacro
+%macro WRITEHEX8 0-1
+%endmacro
%endif ; DEBUG_TRACERS
@@ -89,11 +125,13 @@ Pointers: dw Int13Start
IretPtr equ Int13Start.iret
Int13Start:
+ cmp word [cs:Recursive],0
+ jne recursive
+
; Swap stack
mov [cs:Stack],esp
+ mov [cs:Stack+4],ss
mov [cs:SavedAX],ax
- mov ax,ss
- mov [cs:Stack+4],ax
mov ax,cs
mov ss,ax
mov sp,[cs:MyStack]
@@ -106,24 +144,28 @@ Int13Start:
js .nomatch ; If SF=0, we have a class match here
; 0x00 the sign bit for FD
; 0x80 the sign bit for HD
- jz .our_drive ; If ZF=1, we have an exact match
+ jz our_drive ; If ZF=1, we have an exact match
cmp dl,[cs:DriveNo]
jb .nomatch ; Drive < Our drive
dec dl ; Drive > Our drive, adjust drive #
.nomatch:
+ TRACER '!'
+ WRITEHEX2 dl
+ TRACER ','
mov ax,[cs:SavedAX]
+ WRITEHEX4
+ inc word [cs:Recursive]
pushf
call far [cs:OldInt13]
pushf
+ dec word [cs:Recursive]
push bp
mov bp,sp
cmp byte [cs:SavedAX+1],08h ; Get drive params function?
- je .norestoredl
+ je .norestoredl ; DL = number of drives
cmp byte [cs:SavedAX+1],15h ; Get disk type function?
- jne .restoredl
- test byte [bp+4],80h ; Hard disk?
- jnz .norestoredl
-.restoredl: ; DL should have number of drives
+ je .norestoredl ; CX:DX = size of device
+.restoredl:
mov dl,[bp+4]
.norestoredl:
push ax
@@ -139,7 +181,12 @@ Int13Start:
lss esp,[cs:Stack]
.iret: iret
-.our_drive:
+recursive:
+ TRACER '@'
+jmp_oldint13:
+ jmp far [cs:OldInt13]
+
+our_drive:
; Set up standard entry frame
push ds
push es
@@ -149,7 +196,8 @@ Int13Start:
pushad
mov bp,sp ; Point BP to the entry stack frame
TRACER 'F'
- ; Note: AH == P_AH here
+ WRITEHEX4
+ ; Note: AX == P_AX here
cmp ah,Int13FuncsCnt-1
ja Invalid_jump
xor al,al ; AL = 0 is standard entry condition
@@ -208,7 +256,7 @@ Reset:
pop ds
lss esp,[cs:Stack] ; Restore the stack
and dl,80h ; Clear all but the type bit
- jmp far [cs:OldInt13]
+ jmp jmp_oldint13
Invalid:
@@ -222,7 +270,9 @@ GetDriveType:
test byte [DriveNo],80h
mov bl,02h ; Type 02h = floppy with changeline
jz .floppy
- ; Hard disks only...
+ ; Hard disks only! DO NOT set CX:DX for floppies...
+ ; it apparently causes Win98SE DOS to go into an loop
+ ; resetting the drive over and over. Sigh.
inc bx ; Type = 03h
mov dx,[DiskSize] ; Return the disk size in sectors
mov P_DX,dx
@@ -792,6 +842,39 @@ debug_tracer: pushad
popfd
popad
ret
+
+writehex2: pushad
+ pushfd
+ mov cx,2
+ ror eax,4
+ jmp writehex_common
+writehex4: pushad
+ pushfd
+ mov cx,4
+ ror eax,12
+ jmp writehex_common
+writehex8: pushad
+ pushfd
+ mov cx,8
+ ror eax,28
+writehex_common:
+.loop: push cx
+ push eax
+ and al,0Fh
+ cmp al,10
+ jb .isdec
+ add al,'a'-'0'-10
+.isdec: add al,'0'
+ mov ah,0Eh
+ mov bx,7
+ int 10h
+ pop eax
+ rol eax,4
+ pop cx
+ loop .loop
+ popfd
+ popad
+ ret
%endif
section .data
@@ -964,13 +1047,25 @@ EDD_DPT:
.totalsize dd 0, 0 ; Filled in by installer
.bytespersec dw SECTORSIZE
.eddtable dw -1, -1 ; Invalid DPTE pointer
+.dpikey dw 0BEDDh ; Device Path Info magic
+.dpilen db 2ch ; DPI len
+.res1 db 0 ; Reserved
+.res2 dw 0 ; Reserved
+.bustype dd 'MEM ' ; Host bus type (4 bytes, space padded)
+.inttype dd 'MEMORY ' ; Interface type (8 bytes, spc. padded)
+.intpath dd 0, 0 ; Interface path
+.devpath dd 0, 0, 0, 0 ; Device path
+.res3 db 0 ; Reserved
+.chksum db 0 ; DPI checksum
%endif
; End patch area
+ alignb 4, db 0
Stack dd 0 ; Saved SS:ESP on invocation
dw 0
SavedAX dw 0 ; AX saved on invocation
+Recursive dw 0 ; Recursion counter
alignb 4, db 0 ; We *MUST* end on a dword boundary
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 98c4b69d..caee377a 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -80,7 +80,17 @@ struct edd_dpt {
uint64_t sectors; /* Total sectors */
uint16_t bytespersec; /* Bytes/sector */
uint16_t dpte_off, dpte_seg; /* DPTE pointer */
-};
+ uint16_t dpikey; /* Device Path Info magic */
+ uint8_t dpilen; /* Device Path Info length */
+ uint8_t res1; /* Reserved */
+ uint16_t res2; /* Reserved */
+ uint8_t bustype[4]; /* Host bus type */
+ uint8_t inttype[8]; /* Interface type */
+ uint64_t intpath; /* Interface path */
+ uint64_t devpath[2]; /* Device path (double QuadWord!) */
+ uint8_t res3; /* Reserved */
+ uint8_t chksum; /* DPI checksum */
+} __attribute__((packed));
struct patch_area {
uint32_t diskbuf;
@@ -121,7 +131,7 @@ struct patch_area {
dpt_t dpt;
struct edd_dpt edd_dpt;
-};
+} __attribute__((packed));
/* Access to high memory */
@@ -708,6 +718,17 @@ static void relocate_rm_code(uint32_t newbase)
sti();
}
+static uint8_t checksum_buf(const void *buf, int count)
+{
+ const uint8_t *p = buf;
+ uint8_t c;
+
+ while (count--)
+ c += *p++;
+
+ return c;
+}
+
#define STACK_NEEDED 512 /* Number of bytes of stack */
struct real_mode_args rm_args;
@@ -886,19 +907,24 @@ void setup(const struct real_mode_args *rm_args_ptr)
}
/* Set up an EDD drive parameter table */
- pptr->edd_dpt.sectors = geometry->sectors;
- /* The EDD spec has this as <= 15482880 sectors (1024x240x63);
- this seems to make very little sense. Try for something saner. */
- if (geometry->c <= 1024 && geometry->h <= 255 && geometry->s <= 63) {
- pptr->edd_dpt.c = geometry->c;
- pptr->edd_dpt.h = geometry->h;
- pptr->edd_dpt.s = geometry->s;
- pptr->edd_dpt.flags |= 0x0002; /* Geometry valid */
- }
- if (!(geometry->driveno & 0x80)) {
- /* Floppy drive. Mark it as a removable device with
- media change notification; media is present. */
- pptr->edd_dpt.flags |= 0x0014;
+ if (do_edd) {
+ pptr->edd_dpt.sectors = geometry->sectors;
+ /* The EDD spec has this as <= 15482880 sectors (1024x240x63);
+ this seems to make very little sense. Try for something saner. */
+ if (geometry->c <= 1024 && geometry->h <= 255 && geometry->s <= 63) {
+ pptr->edd_dpt.c = geometry->c;
+ pptr->edd_dpt.h = geometry->h;
+ pptr->edd_dpt.s = geometry->s;
+ pptr->edd_dpt.flags |= 0x0002; /* Geometry valid */
+ }
+ if (!(geometry->driveno & 0x80)) {
+ /* Floppy drive. Mark it as a removable device with
+ media change notification; media is present. */
+ pptr->edd_dpt.flags |= 0x0014;
+ }
+
+ pptr->edd_dpt.devpath[0] = pptr->diskbuf;
+ pptr->edd_dpt.chksum = -checksum_buf(&pptr->edd_dpt.dpikey, 73-30);
}
/* The size is given by hptr->total_size plus the size of the E820
diff --git a/modules/gfxboot.asm b/modules/gfxboot.asm
index c9fdd1b6..5c7b118b 100644
--- a/modules/gfxboot.asm
+++ b/modules/gfxboot.asm
@@ -144,7 +144,15 @@ got_config_file:
push cs
pop es
call parse_config
+ cmp word [label_cnt],0
+ ja labels_defined
+ mov bx,msg_no_labels_defined
+ mov ax,2
+ int 22h
+ ret
+
+labels_defined:
; get_gfx_file
mov ax,cs
add ax,2000h
@@ -417,6 +425,14 @@ gfx_read_file:
mov si,pspCmdArg+1
int 22h
jnc gfx_file_read
+
+ mov ax,2
+ mov bx,pspCmdArg+1
+ int 22h
+
+ mov ax,2
+ mov bx,msg_not_found
+ int 22h
stc
ret
@@ -641,8 +657,7 @@ gfx_input:
shl edi,4
add edi, command_line ; buffer (0: no buffer)
mov ecx, max_cmd_len ; buffer size
-; xor eax,eax ; timeout value (0: no timeout)
- mov eax,100 ; timeout value (0: no timeout)
+ mov eax,[menu_timeout] ; timeout value (0: no timeout)
call far [gfx_bc_input]
ret
@@ -699,33 +714,39 @@ parse_config:
mov bx, msg_crlf
int 22h
%endif
+ mov bx,keywords
+ mov cx,[keyword_cnt]
+.keywords_loop:
+ push cx
push si
push di
- xor ecx,ecx
+ xor cx,cx
mov si,configbuf
- mov di,label_keyword+1
- mov cl, byte [label_keyword]
+ mov di,[bx]
+ mov cl,byte [di]
+ inc di
call memcmp
pop di
pop si
- jz .do_label
+ jnz .not_found
+ pop cx
+ call [bx+2] ; call keyword handler
+ jmp .read
- push si
- push di
- xor ecx,ecx
- mov si,configbuf
- mov di,default_keyword+1
- mov cl, byte [default_keyword]
- call memcmp
- pop di
- pop si
- jz .do_default
+.not_found:
+ add bx,4
+ pop cx
+ loop .keywords_loop
.nextline:
call skipline
jmp .read
-.do_label:
+.eof:
+.noparm:
+ ret
+
+do_label:
call skipspace
jz .eof
jc .noparm
@@ -742,10 +763,11 @@ parse_config:
pop di
pop es
inc word [label_cnt]
+.eof:
+.noparm:
+ ret
- jmp .read
-
-.do_default:
+do_default:
call skipspace
jz .eof
jc .noparm
@@ -759,8 +781,42 @@ parse_config:
pop di
pop es
- jmp .read
+.eof:
+.noparm:
+ ret
+do_timeout:
+ call skipspace
+ jz .eof
+ jc .noparm
+ call ungetc
+ push es
+ push di
+ push cs
+ pop es
+ mov di,NumBuf
+.getnum:
+ cmp di,NumBufEnd
+ jae .loaded
+ call getc
+ stosb
+ cmp al,'-'
+ jnb .getnum
+ call ungetc
+ dec di
+.loaded:
+ mov byte [di],0
+ pop di
+ pop es
+ push cs
+ pop ds
+ mov si,NumBuf
+ push ebx
+ call parseint
+ jc .err
+ mov [menu_timeout],ebx
+.err:
+ pop ebx
.eof:
.noparm:
ret
@@ -876,23 +932,63 @@ memcmp:
pop si
ret
- section .data
-label_keyword db 6,'label',0
-default_keyword db 7,'default',0
+parseint:
+ push eax
+ push ecx
+ xor eax,eax
+ xor ebx,ebx
+ xor ecx,ecx
+ mov cl,10
+.loop:
+ lodsb
+ and al,al
+ jz .done
+ cmp al,'0'
+ jb .err
+ cmp al,'9'
+ ja .err
+ sub al,'0'
+ imul ebx,ecx
+ add ebx,eax
+ jmp short .loop
+.done:
+ clc
+.ret:
+ pop ecx
+ pop eax
+ ret
+.err:
+ stc
+ jmp short .ret
+ section .data
msg_progname db 'gfxboot: ',0
msg_config_file db 'Configuration file',0
msg_missing db 'missing',0
msg_usage db 'Usage: gfxboot.com <bootlogo>',0dh,0ah,0
msg_memory db 'Could not detect available memory size',0dh,0ah,0
msg_bootlogo_toobig db 'bootlogo file too big',0dh,0ah,0
-msg_pxelinux db 'pxelinux is not supported',0dh,0ah,0
msg_unknown_file_size db 'unknown file size',0dh,0ah,0
+msg_not_found db ' not found',0dh,0ah,0
+msg_no_labels_defined db 'No labels defined in config file',0dh,0ah,0
msg_space db ' ',0
msg_crlf db 0dh,0ah,0
gfx_slash db '/', 0
db0 db 0
+menu_timeout dd 100
+
+keyword_text_label db 6,'label',0
+keyword_text_default db 7,'default',0
+keyword_text_timeout db 7,'timeout',0
+keywords equ $
+ dw keyword_text_label
+ dw do_label
+ dw keyword_text_default
+ dw do_default
+ dw keyword_text_timeout
+ dw do_timeout
+keyword_cnt dw ($-keywords)/4
; menu entry descriptor
menu_entries equ 0
@@ -942,6 +1038,9 @@ dentry_buf_len equ $ - dentry_buf
max_cmd_len equ 2047
command_line resb max_cmd_len+2
+NumBuf resb 15
+NumBufEnd resb 1
+
alignb 4
derivative_id resb 1
drivenumber resb 1
diff --git a/utils/isohybrid.in b/utils/isohybrid.in
index a92b5726..0726bed9 100644
--- a/utils/isohybrid.in
+++ b/utils/isohybrid.in
@@ -194,7 +194,7 @@ if ($c > 1024) {
# Preserve id when run again
if (defined($opt{'id'})) {
- $id = $opt{'id'};
+ $id = pack("V", doh($opt{'id'}));
} else {
seek(FILE, 440, SEEK_SET) or die "$0: $file: $!\n";
read(FILE, $id, 4);