From a3d199a03daed80e40b4eb1ca14ba232c91dc720 Mon Sep 17 00:00:00 2001 From: hpa Date: Sat, 5 Apr 2003 06:26:06 +0000 Subject: Encapsulate calls to the PXE stack into a single function; Restore error codes (BX) when we have memory freeing failures; Make sure DS and ES are consistent in unload_pxe --- NEWS | 3 +++ comboot.inc | 2 +- pxelinux.asm | 62 ++++++++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index 733987d1..2a75166d 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,9 @@ them. Changes in 2.03: * Actually support comment lines in the configuration file. * PXELINUX: Try to resolve some problems with stack switches. + This is a workaround for what appears to be a fairly common + PXE stack bug, including in the remote install PXE boot + floppy (rbfg.exe) from Argon Technologies. Changes in 2.02: * SYSLINUX: Security flaws have been found in the SYSLINUX diff --git a/comboot.inc b/comboot.inc index c7efe824..2388ad17 100644 --- a/comboot.inc +++ b/comboot.inc @@ -436,7 +436,7 @@ comapi_pxecall: mov bx,P_BX mov es,P_ES mov di,P_DI - call far [PXENVEntry] + call pxenv mov P_AX,ax clc ret diff --git a/pxelinux.asm b/pxelinux.asm index 2c25b012..b436891c 100644 --- a/pxelinux.asm +++ b/pxelinux.asm @@ -54,13 +54,6 @@ TFTP_ACK equ htons(4) ; ACK packet TFTP_ERROR equ htons(5) ; ERROR packet TFTP_OACK equ htons(6) ; OACK packet -; -; Should be updated with every release to avoid bootsector/SYS file mismatch -; -%define version_str VERSION ; Must be 4 characters long! -%define date DATE_STR ; Defined from the Makefile -%define year '2002' - ; ; The following structure is used for "virtual kernels"; i.e. LILO-style ; option labels. The options we permit here are `kernel' and `append @@ -540,7 +533,7 @@ query_bootp: mov di,pxe_bootp_query_pkt_2 mov bx,PXENV_GET_CACHED_INFO - call far [PXENVEntry] + call pxenv push word [pxe_bootp_query_pkt_2.status] jc .pxe_err1 cmp ax,byte 0 @@ -549,7 +542,7 @@ query_bootp: mov di,pxe_bootp_size_query_pkt mov bx,PXENV_GET_CACHED_INFO - call far [PXENVEntry] + call pxenv jc .pxe_err .pxe_size: mov ax,[pxe_bootp_size_query_pkt.buffersize] @@ -581,7 +574,7 @@ query_bootp: mov di,pxe_bootp_query_pkt_3 mov bx,PXENV_GET_CACHED_INFO - call far [PXENVEntry] + call pxenv push word [pxe_bootp_query_pkt_3.status] jc .pxe_err1 cmp ax,byte 0 @@ -640,7 +633,7 @@ udp_init: mov [pxe_udp_open_pkt.sip],eax mov di,pxe_udp_open_pkt mov bx,PXENV_UDP_OPEN - call far [PXENVEntry] + call pxenv jc .failed cmp word [pxe_udp_open_pkt.status], byte 0 je .success @@ -1104,7 +1097,7 @@ searchdir: mov di,pxe_udp_write_pkt mov bx,PXENV_UDP_WRITE - call far [PXENVEntry] + call pxenv jc .failure cmp word [pxe_udp_write_pkt.status],byte 0 jne .failure @@ -1128,7 +1121,7 @@ searchdir: mov [pxe_udp_read_pkt.lport],bx mov di,pxe_udp_read_pkt mov bx,PXENV_UDP_READ - call far [PXENVEntry] + call pxenv and ax,ax jz .got_packet ; Wait for packet .no_packet: @@ -1239,7 +1232,7 @@ searchdir: mov word [pxe_udp_write_pkt.buffersize],tftp_opt_err_len mov di,pxe_udp_write_pkt mov bx,PXENV_UDP_WRITE - call far [PXENVEntry] + call pxenv .no_tsize: mov si,err_oldtftp call writestr @@ -1417,6 +1410,17 @@ unmangle_name: call strcpy dec di ; Point to final null byte ret +; +; pxenv +; +; This is the main PXENV+/!PXE entry point, using the PXENV+ +; calling convention. This is a separate local routine so +; we can hook special things from it if necessary. +; +pxenv: + call far [cs:PXENVEntry] + ret + ; ; pxe_thunk ; @@ -1496,7 +1500,7 @@ getfssec: mov di,pxe_udp_read_pkt mov bx,PXENV_UDP_READ push si ; - call far [PXENVEntry] + call pxenv pop si ; cmp ax,byte 0 je .recv_ok @@ -1619,7 +1623,7 @@ ack_packet: mov [pxe_udp_write_pkt.buffersize], word 4 mov di,pxe_udp_write_pkt mov bx,PXENV_UDP_WRITE - call far [PXENVEntry] + call pxenv cmp ax,byte 0 ; ZF = 1 if write OK popad ret @@ -1628,12 +1632,19 @@ ack_packet: ; unload_pxe: ; ; This function unloads the PXE and UNDI stacks and unclaims -; the memory. Assumes CS == DS == ES. +; the memory. ; unload_pxe: test byte [KeepPXE],01h ; Should we keep PXE around? jnz reset_pxe + push ds + push es + + mov ax,cs + mov ds,ax + mov es,ax + mov si,new_api_unload cmp byte [APIVer+1],2 ; Major API version >= 2? jae .new_api @@ -1651,7 +1662,7 @@ unload_pxe: mov cx,pxe_unload_stack_pkt_len >> 1 rep stosw pop di - call far [PXENVEntry] + call pxenv jc .cant_free cmp word [pxe_unload_stack_pkt.status],PXENV_STATUS_SUCCESS jne .cant_free @@ -1695,10 +1706,12 @@ unload_pxe: popf popa %endif + mov bx,0FF00h mov dx,[RealBaseMem] cmp dx,[BIOS_fbm] ; Sanity check jna .cant_free + inc bx ; Check that PXE actually unhooked the INT 1Ah chain movzx eax,word [4*0x1a] @@ -1710,9 +1723,13 @@ unload_pxe: jae .ok cmp ax,[BIOS_fbm] jae .cant_free + ; inc bx .ok: mov [BIOS_fbm],dx +.pop_ret: + pop es + pop ds ret .cant_free: @@ -1724,14 +1741,19 @@ unload_pxe: call writechr mov eax,[4*0x1a] call writehex8 - jmp crlf + call crlf + jmp .pop_ret ; We want to keep PXE around, but still we should reset ; it to the standard bootup configuration reset_pxe: + push es + push cs + pop es mov bx,PXENV_UDP_CLOSE mov di,pxe_udp_close_pkt - call far [PXENVEntry] + call pxenv + pop es ret ; -- cgit v1.2.1