aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2014-02-13 10:07:44 -0800
committerH. Peter Anvin <hpa@linux.intel.com>2014-02-13 15:40:02 -0800
commit8c11d9231fa234ff30477ba9c958c9d3645abfa2 (patch)
treee94fb78753a0993bb2844734167be29ff3f03daa
parente6374f1c88f925bd01212a783680eda928ecfff9 (diff)
downloadsyslinux-8c11d9231fa234ff30477ba9c958c9d3645abfa2.tar.gz
syslinux-8c11d9231fa234ff30477ba9c958c9d3645abfa2.tar.xz
syslinux-8c11d9231fa234ff30477ba9c958c9d3645abfa2.zip
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@linux.intel.com> Cc: Gene Cumm <gene.cumm@gmail.com>
-rw-r--r--com32/include/syslinux/config.h4
-rw-r--r--com32/modules/pxechn.c32
-rw-r--r--core/fs/pxe/bios.c19
-rw-r--r--core/pxelinux-c.c11
-rw-r--r--core/pxelinux.asm3
5 files changed, 43 insertions, 26 deletions
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index 45a0ac77..131d7c8e 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 bd614aa9..e4e21e88 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 e3d9adc8..6d514df2 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 36831894..ac23d822 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 64194d38..f4c52c2b 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