Preserve ES:DI instead of probing for $PnP syslinux-3.53-pre5
authorH. Peter Anvin <hpa@zytor.com>
Thu, 15 Nov 2007 04:51:23 +0000 (20:51 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 15 Nov 2007 04:51:23 +0000 (20:51 -0800)
The $PnP probe has been found to lock up at least one machine for
reasons unknown.  Drop it; instead, burn the extra few bytes in the
bootsector to save away ES:DI for later restore.

bootsect.inc
com32/include/syslinux/config.h
comboot.doc
comboot.inc
extlinux.asm
isolinux.asm
ldlinux.asm
stack.inc

index 78ad12a..0060517 100644 (file)
@@ -142,38 +142,14 @@ replace_bootstrap:
                ; For PXE, ES:BX -> PXENV+, and this would corrupt
                ; that use.
 
-               ; Hunt for $PnP header if one exists
-               mov ax,0F000h
-               mov fs,ax
-               xor bx,bx
-.findpnp:
-               cmp dword [fs:bx], "$PnP"
-               jz .foundpnp
-.againpnp:
-               inc bx
-               cmp bx,-21h             ; Don't get a segment overflow error!
-               jbe .findpnp
-               jmp .donepnp            ; No $PnP header found
-.foundpnp:
-               movzx cx,byte [fs:bx+5] ; Size of $PnP header
-               cmp cl,21h
-               jb .againpnp            ; Invalid $PnP header (too short)
-               push bx
-               xor ax,ax
-.checkpnp:
-               add al,byte [fs:bx]
-               inc bx
-               loop .checkpnp
-               pop bx
-               and al,al
-               jnz .findpnp
-
-               ; Found a valid $PnP header, point ES:DI to it
-               mov [es:di+8], bx       ; New DI
-               mov [es:di+4], fs       ; New ES
-%endif
+               ; Restore ES:DI -> $PnP (if we were ourselves called
+               ; that way...)
+               mov ax,[OrigESDI]
+               mov bx,[OrigESDI+2]
 
-.donepnp:
+               mov [es:di+8],ax        ; New DI
+               mov [es:di+4],bx        ; New ES
+%endif
                pop bx                  ; Copy from...
                pop ax                  ; Copy list count
 
index d0cb4c2..8b2ed4c 100644 (file)
@@ -68,6 +68,7 @@ union syslinux_derivative_info {
     uint16_t ax;
     uint16_t cx;
     uint16_t dx;
+    uint16_t _pad;
     const void *esbx;
     const void *fssi;
     const void *gsdi;
@@ -79,13 +80,16 @@ union syslinux_derivative_info {
     uint8_t ch;
     uint8_t drive_number;
     uint8_t dh;
+    uint16_t _pad;
     const void *ptab_ptr;
+    const uint32_t *esdi_ptr;
   } disk;                      /* syslinux/extlinux */
   struct {
     uint8_t filesystem;
     uint8_t ah;
     uint16_t cx;
     uint16_t apiver;
+    uint16_t _pad;
     const void *pxenvptr;
     const void *stack;
   } pxe;                       /* pxelinux */
@@ -96,7 +100,9 @@ union syslinux_derivative_info {
     uint8_t ch;
     uint8_t drive_number;
     uint8_t dh;
+    uint16_t _pad;
     const void *spec_packet;
+    const uint32_t *esdi_ptr;
   } iso;                       /* isolinux */
 };
 
index c8546b2..3c806c3 100644 (file)
@@ -367,9 +367,19 @@ AX=000Ah [2.00]    Get Derivative-Specific Information
                DL      drive number
                CL      sector size as a power of 2 (9 = 512 bytes) [3.35]
                ES:BX   pointer to partition table entry (if DL >= 80h)
+               FS:SI   pointer to initial ES:DI value [3.53]
 
                Note: This function was broken in EXTLINUX 3.00-3.02.
 
+               On boot, ES:DI is supposed to point to the BIOS $PnP
+               structure, although in practice most operating systems
+               will search for it in memory.  However, preserving
+               this while chainloading is probably a good idea.
+
+               Note that FS:SI is a pointer to a memory location
+               containing the original ES:DI value, not the value
+               itself.
+
 
        [PXELINUX]
        Input:  AX      000Ah
@@ -417,6 +427,7 @@ AX=000Ah [2.00]     Get Derivative-Specific Information
                DL      drive number
                CL      11 (sector size as a power of 2) [3.35]
                ES:BX   pointer to El Torito spec packet
+               FS:SI   pointer to initial ES:DI value [3.53]
 
                Note: Some very broken El Torito implementations do
                not provide the spec packet information.  If so, ES:BX
index 33414bc..2c1c882 100644 (file)
@@ -460,13 +460,7 @@ comapi_pxecall     equ comapi_err                  ; Not available
 ;
 comapi_derinfo:
                mov P_AL,my_id
-%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
-               mov al,[DriveNumber]
-               mov P_DL,al
-               mov P_ES,cs
-               mov P_BX,PartInfo
-               mov P_CL,SECTOR_SHIFT
-%elif IS_PXELINUX
+%if IS_PXELINUX
                mov ax,[APIVer]
                mov P_DX,ax
                mov ax,[StrucPtr]
@@ -477,12 +471,21 @@ comapi_derinfo:
                mov P_SI,ax
                mov ax,[InitStack+2]
                mov P_FS,ax
-%elif IS_ISOLINUX
+%else
+               ; Physical medium...
+
+               mov P_CL,SECTOR_SHIFT
                mov al,[DriveNumber]
                mov P_DL,al
+               mov P_FS,cs
+               mov P_SI,OrigESDI
+%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
+               mov P_ES,cs
+               mov P_BX,PartInfo
+%elif IS_ISOLINUX
                mov P_ES,cs
                mov P_BX,spec_packet
-               mov P_CL,SECTOR_SHIFT
+%endif
 %endif
                clc
                ret
index 54fda21..6666f79 100644 (file)
@@ -148,7 +148,8 @@ xbs_vgatmpbuf       equ 2*trackbufsize
 StackBuf       equ $-44-32             ; Start the stack here (grow down - 4K)
 PartInfo       equ StackBuf            ; Saved partition table entry
 FloppyTable    equ PartInfo+16         ; Floppy info table (must follow PartInfo)
-OrigFDCTabPtr  equ StackBuf-4          ; The high dword on the stack
+OrigFDCTabPtr  equ StackBuf-8          ; The 2nd high dword on the stack
+OrigESDI       equ StackBuf-4          ; The high dword on the stack
 
 ;
 ; Primary entry point.  Tempting as though it may be, we can't put the
@@ -217,12 +218,14 @@ start:
                xor ax,ax
                mov ss,ax
                mov sp,StackBuf         ; Just below BSS
+               push es                 ; Save initial ES:DI -> $PnP pointer
+               push di
                mov es,ax
 ;
 ; DS:SI may contain a partition table entry.  Preserve it for us.
 ;
                mov cx,8                ; Save partition info
-               mov di,sp
+               mov di,PartInfo
                rep movsw
 
                mov ds,ax               ; Now we can initialize DS...
index 4fbb772..ba7a6a6 100644 (file)
@@ -215,9 +215,10 @@ xbs_vgatmpbuf      equ 2*trackbufsize
 ;; CD-ROM sector (2K) of the file, so the number one priority is actually
 ;; loading the rest.
 ;;
-StackBuf       equ $-44                        ; 44 bytes needed for
-                                               ; the bootsector chainloading
-                                               ; code!
+StackBuf       equ $-44                ; 44 bytes needed for
+                                       ; the bootsector chainloading
+                                       ; code!
+OrigESDI       equ StackBuf-4          ; The high dword on the stack
 
 bootsec                equ $
 
@@ -241,6 +242,8 @@ _start1:    mov [cs:InitStack],sp           ; Save initial stack pointer
                xor ax,ax
                mov ss,ax
                mov sp,StackBuf                 ; Set up stack
+               push es                 ; Save initial ES:DI -> $PnP pointer
+               push di
                mov ds,ax
                mov es,ax
                mov fs,ax
@@ -828,7 +831,6 @@ crlf_msg    db CR, LF
 null_msg       db 0
 
                alignb 4, db 0
-StackPtr       dw StackBuf, 0                  ; SS:SP for stack reset
 MaxTransfer    dw 32                           ; Max sectors per transfer
 
 rl_checkpt     equ $                           ; Must be <= 800h
index 48c9cd0..ff90043 100644 (file)
@@ -154,7 +154,8 @@ xbs_vgatmpbuf       equ 2*trackbufsize
 StackBuf       equ $-44-32             ; Start the stack here (grow down - 4K)
 PartInfo       equ StackBuf            ; Saved partition table entry
 FloppyTable    equ PartInfo+16         ; Floppy info table (must follow PartInfo)
-OrigFDCTabPtr  equ StackBuf-4          ; The high dword on the stack
+OrigFDCTabPtr  equ StackBuf-8          ; The 2nd high dword on the stack
+OrigESDI       equ StackBuf-4          ; The high dword on the stack
 
 ;
 ; Primary entry point.  Tempting as though it may be, we can't put the
@@ -224,12 +225,14 @@ start:
                xor ax,ax
                mov ss,ax
                mov sp,StackBuf         ; Just below BSS
+               push es                 ; Save initial ES:DI -> $PnP pointer
+               push di
                mov es,ax
 ;
 ; DS:SI may contain a partition table entry.  Preserve it for us.
 ;
                mov cx,8                ; Save partition info
-               mov di,sp
+               mov di,PartInfo
                rep movsw
 
                mov ds,ax               ; Now we can initialize DS...
index 0e39b6e..4b9fbc6 100644 (file)
--- a/stack.inc
+++ b/stack.inc
                mov es,%1
 %if IS_SYSLINUX || IS_EXTLINUX
                 mov ss,%1                       ; Just in case...
-                mov sp,StackBuf-2*3            ; Reset stack
+                mov sp,StackBuf-2*5            ; Reset stack
 %elif IS_PXELINUX
                lss esp,[BaseStack]
 %elif IS_ISOLINUX
-               lss sp,[StackPtr]
+               mov ss,%1
+               mov sp,StackBuf-2*2
 %else
                NEED TO KNOW HOW TO RESET STACK
 %endif