summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-11-14 20:51:23 -0800
committerH. Peter Anvin <hpa@zytor.com>2007-11-14 20:51:23 -0800
commit2c2fed8305e2cf52c27d8a5c1fd5b5982f541711 (patch)
treeed39fedc95bdb7f26b748ed1d1d7943465de4665
parentd2520f1b46d08fe2879a93c81973df67834fea17 (diff)
downloadsyslinux-2c2fed8305e2cf52c27d8a5c1fd5b5982f541711.tar.gz
Preserve ES:DI instead of probing for $PnPsyslinux-3.53-pre5
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.
-rw-r--r--bootsect.inc38
-rw-r--r--com32/include/syslinux/config.h6
-rw-r--r--comboot.doc11
-rw-r--r--comboot.inc21
-rw-r--r--extlinux.asm7
-rw-r--r--isolinux.asm10
-rw-r--r--ldlinux.asm7
-rw-r--r--stack.inc5
8 files changed, 55 insertions, 50 deletions
diff --git a/bootsect.inc b/bootsect.inc
index 78ad12af..00605171 100644
--- a/bootsect.inc
+++ b/bootsect.inc
@@ -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
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index d0cb4c26..8b2ed4c9 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -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 */
};
diff --git a/comboot.doc b/comboot.doc
index c8546b25..3c806c3b 100644
--- a/comboot.doc
+++ b/comboot.doc
@@ -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
diff --git a/comboot.inc b/comboot.inc
index 33414bc4..2c1c8826 100644
--- a/comboot.inc
+++ b/comboot.inc
@@ -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
diff --git a/extlinux.asm b/extlinux.asm
index 54fda21e..6666f794 100644
--- a/extlinux.asm
+++ b/extlinux.asm
@@ -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...
diff --git a/isolinux.asm b/isolinux.asm
index 4fbb7724..ba7a6a66 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -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
diff --git a/ldlinux.asm b/ldlinux.asm
index 48c9cd0b..ff900435 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -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...
diff --git a/stack.inc b/stack.inc
index 0e39b6ea..4b9fbc64 100644
--- a/stack.inc
+++ b/stack.inc
@@ -31,11 +31,12 @@
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