; 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
uint16_t ax;
uint16_t cx;
uint16_t dx;
+ uint16_t _pad;
const void *esbx;
const void *fssi;
const void *gsdi;
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 */
uint8_t ch;
uint8_t drive_number;
uint8_t dh;
+ uint16_t _pad;
const void *spec_packet;
+ const uint32_t *esdi_ptr;
} iso; /* isolinux */
};
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
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
;
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]
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
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
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...
;; 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 $
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
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
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
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...
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