diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-08-08 18:48:35 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-08-08 18:51:30 -0700 |
commit | c8893ccbdbafec7776dc0c190609590a6b30f11c (patch) | |
tree | b9de59c82734bbaf74e84bdb067a613302986ada | |
parent | bf9f683dbef47a44dee4da1607d99a25976560e3 (diff) | |
parent | 8e01231be41fd889bcb71604dbda511688ed0f38 (diff) | |
download | syslinux-c8893ccbdbafec7776dc0c190609590a6b30f11c.tar.gz |
Merge branch 'master' into core32
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | com32/modules/chain.c | 3 | ||||
-rw-r--r-- | core/graphics.inc | 71 | ||||
-rw-r--r-- | core/parsecmd.inc | 4 | ||||
-rw-r--r-- | core/pxelinux.asm | 2 | ||||
-rw-r--r-- | memdisk/memdisk.inc | 119 | ||||
-rw-r--r-- | memdisk/setup.c | 56 | ||||
-rw-r--r-- | modules/gfxboot.asm | 149 | ||||
-rw-r--r-- | utils/isohybrid.in | 2 |
9 files changed, 331 insertions, 80 deletions
@@ -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); |