[syslinux:master] pxe: Export the initial stack and PXE(NV) structure, fix pxechn

syslinux-bot for H. Peter Anvin hpa at linux.intel.com
Thu Feb 13 15:42:05 PST 2014


Commit-ID:  8c11d9231fa234ff30477ba9c958c9d3645abfa2
Gitweb:     http://www.syslinux.org/commit/8c11d9231fa234ff30477ba9c958c9d3645abfa2
Author:     H. Peter Anvin <hpa at linux.intel.com>
AuthorDate: Thu, 13 Feb 2014 10:07:44 -0800
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Thu, 13 Feb 2014 15:40:02 -0800

pxe: Export the initial stack and PXE(NV) structure, fix pxechn

Export the initial stack and PXE(NV) structure pointers properly, even
for users which need seg:offs.  Use this in pxechn.c rather than the
already-removed INT 22h AX=000Ah call.

Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>
Cc: Gene Cumm <gene.cumm at gmail.com>


---
 com32/include/syslinux/config.h |  4 ++--
 com32/modules/pxechn.c          | 32 +++++++++++++++++---------------
 core/fs/pxe/bios.c              | 19 ++++++++++++++++---
 core/pxelinux-c.c               | 11 +++++++----
 core/pxelinux.asm               |  3 +--
 5 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index 45a0ac7..131d7c8 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -115,8 +115,8 @@ union syslinux_derivative_info {
 	const uint64_t *partoffset;
     } disk;			/* syslinux/extlinux */
     struct {
-	uint16_t _gs, _fs, _es, _ds;
-	uint32_t _edi, _esi, _ebp, _esp, _ebx;
+	uint16_t _gs, stack_seg, pxenv_seg, _ds;
+	uint32_t _edi, stack_offs, _ebp, _esp, pxenv_offs;
 	uint16_t apiver;
 	uint16_t _dxh;
 	uint32_t myip;
diff --git a/com32/modules/pxechn.c b/com32/modules/pxechn.c
index bd614aa..e4e21e8 100644
--- a/com32/modules/pxechn.c
+++ b/com32/modules/pxechn.c
@@ -326,25 +326,27 @@ void print_pxe_bootp_t(pxe_bootp_t *p, size_t len)
 
 void pxe_set_regs(struct syslinux_rm_regs *regs)
 {
-    com32sys_t tregs;
+    const union syslinux_derivative_info *sdi;
+    const com32sys_t *pxe_regs;
+
+    sdi = syslinux_derivative_info();
+    pxe_regs = sdi->pxe.stack;	/* Original register values */
+
+    /* Just to be sure... */
+    memset(regs, 0, sizeof *regs);
 
-    memset(&tregs,0,sizeof(tregs));
     regs->ip = 0x7C00;
-    /* Plan A uses SS:[SP + 4] */
-    /* sdi->pxe.stack is a usable pointer, not something that can be nicely
-       and reliably split to SS:SP without causing issues */
-    tregs.eax.l = 0x000A;
-    __intcall(0x22, &tregs, &tregs);
-    regs->ss = tregs.fs;
-    regs->esp.l = tregs.esi.w[0] + sizeof(tregs);
-    /* Plan B uses [ES:BX] */
-    regs->es = tregs.es;
-    regs->ebx = tregs.ebx;
+
+    /* Point to the original stack */
+    regs->ss    = sdi->pxe.stack_seg;
+    regs->esp.l = sdi->pxe.stack_offs + sizeof(com32sys_t);
+
+    /* Point to the PXENV+ address */
+    regs->es    = pxe_regs->es;
+    regs->ebx.l = pxe_regs->ebx.l;
+
     dprintf("\nsp:%04x    ss:%04x    es:%04x    bx:%04x\n", regs->esp.w[0],
 	regs->ss, regs->es, regs->ebx.w[0]);
-    /* Zero out everything else just to be sure */
-    regs->cs = regs->ds = regs->fs = regs->gs = 0;
-    regs->eax.l = regs->ecx.l = regs->edx.l = 0;
 }
 
 int hostlen_limit(int len)
diff --git a/core/fs/pxe/bios.c b/core/fs/pxe/bios.c
index e3d9adc..6d514df 100644
--- a/core/fs/pxe/bios.c
+++ b/core/fs/pxe/bios.c
@@ -11,6 +11,8 @@ static uint16_t real_base_mem;	   /* Amount of DOS memory after freeing */
 static bool has_gpxe;
 static uint32_t gpxe_funcs;
 
+far_ptr_t StrucPtr;
+
 /*
  * Validity check on possible !PXE structure in buf
  * return 1 for success, 0 for failure.
@@ -162,20 +164,28 @@ int pxe_init(bool quiet)
     regs.eax.w[0] = 0x5650;
     call16(pxe_int1a, &regs, &regs);
     if (!(regs.eflags.l & EFLAGS_CF) && (regs.eax.w[0] == 0x564e)) {
-	pxenv = MK_PTR(regs.es, regs.ebx.w[0]);
+	off = regs.ebx.w[0];
+	seg = regs.es;
+	pxenv = MK_PTR(seg, off);
         if (is_pxenv(pxenv))
             goto have_pxenv;
     }
 
     /* Plan D: !PXE memory scan */
     plan++;
-    if ((pxe = memory_scan_for_pxe_struct()))
+    if ((pxe = memory_scan_for_pxe_struct())) {
+	off = OFFS(pxe);
+	seg = SEG(pxe);
         goto have_pxe;
+    }
 
     /* Plan E: PXENV+ memory scan */
     plan++;
-    if ((pxenv = memory_scan_for_pxenv_struct()))
+    if ((pxenv = memory_scan_for_pxenv_struct())) {
+	off = OFFS(pxenv);
+	seg = SEG(pxenv);
         goto have_pxenv;
+    }
 
     /* Found nothing at all !! */
     if (!quiet)
@@ -222,6 +232,9 @@ int pxe_init(bool quiet)
     type = "!PXE";
 
  have_entrypoint:
+    StrucPtr.offs = off;
+    StrucPtr.seg  = seg;
+
     if (!quiet) {
 	ddprintf("%s entry point found (we hope) at %04X:%04X via plan %c\n",
 	       type, PXEEntry.seg, PXEEntry.offs, plan);
diff --git a/core/pxelinux-c.c b/core/pxelinux-c.c
index 3683189..ac23d82 100644
--- a/core/pxelinux-c.c
+++ b/core/pxelinux-c.c
@@ -1,8 +1,7 @@
 #include <syslinux/config.h>
 #include <com32.h>
 
-extern void *StrucPtr;
-extern void *InitStack;
+extern far_ptr_t InitStack, StrucPtr;
 
 /*
  * IP information.  Note that the field are in the same order as the
@@ -15,8 +14,12 @@ __export void get_derivative_info(union syslinux_derivative_info *di)
 {
 	di->pxe.filesystem = SYSLINUX_FS_PXELINUX;
 	di->pxe.apiver = APIVer;
-	di->pxe.pxenvptr = &StrucPtr;
-	di->pxe.stack = &InitStack;
+	di->pxe.pxenvptr = GET_PTR(StrucPtr);
+	di->pxe.pxenv_offs = StrucPtr.offs;
+	di->pxe.pxenv_seg = StrucPtr.seg;
+	di->pxe.stack = GET_PTR(InitStack);
+	di->pxe.stack_offs = InitStack.offs;
+	di->pxe.stack_seg = InitStack.seg;
 	di->pxe.ipinfo = &IPInfo;
 	di->pxe.myip = IPInfo.myip;
 }
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 64194d3..f4c52c2 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -62,9 +62,8 @@ InitStack	resd 1
 PXEStack	resd 1			; Saved stack during PXE call
 
 		alignb 4
-                global DHCPMagic, RebootTime, StrucPtr, BIOSName
+                global DHCPMagic, RebootTime, BIOSName
 RebootTime	resd 1			; Reboot timeout, if set by option
-StrucPtr	resw 2			; Pointer to PXENV+ or !PXE structure
 LocalBootType	resw 1			; Local boot return code
 DHCPMagic	resb 1			; PXELINUX magic flags
 BIOSName	resw 1			; Dummy variable - always 0


More information about the Syslinux-commits mailing list