diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2014-02-13 10:07:44 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-02-13 15:40:02 -0800 |
commit | 8c11d9231fa234ff30477ba9c958c9d3645abfa2 (patch) | |
tree | e94fb78753a0993bb2844734167be29ff3f03daa | |
parent | e6374f1c88f925bd01212a783680eda928ecfff9 (diff) | |
download | syslinux-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.h | 4 | ||||
-rw-r--r-- | com32/modules/pxechn.c | 32 | ||||
-rw-r--r-- | core/fs/pxe/bios.c | 19 | ||||
-rw-r--r-- | core/pxelinux-c.c | 11 | ||||
-rw-r--r-- | 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 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, ®s, ®s); 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 |