Make a valiant, and probably futile, attempt to free memory after
authorhpa <hpa>
Sun, 16 Dec 2001 00:03:28 +0000 (00:03 +0000)
committerhpa <hpa>
Sun, 16 Dec 2001 00:03:28 +0000 (00:03 +0000)
running the PXE stack.

NEWS
memdisk/setup.c
pxe.inc
pxelinux.asm

diff --git a/NEWS b/NEWS
index e55e28c..e290fe8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,9 @@ Changes in 1.65:
          See memdisk/memdisk.doc for more info.
        * PXELINUX, ISOLINUX: Correctly handle files larger than 65535
          blocks (32 MB for PXELINUX, 128 MB for ISOLINUX.)
+       * PXELINUX: Make a best-effort attempt at freeing all memory
+         claimed.  From the looks of it, it will fail on most PXE
+         stacks.
 
 Changes in 1.64:
        * Limited support for hardware flow control when using a
index e75bcb4..2ab5b98 100644 (file)
@@ -473,6 +473,9 @@ uint32_t setup(void)
   dosmem_k = rdz_16(BIOS_BASEMEM);
   pptr->olddosmem = dosmem_k;
   stddosmem = dosmem_k << 10;
+  /* If INT 15 E820 and INT 12 disagree, go with the most conservative */
+  if ( stddosmem > dos_mem )
+    stddosmem = dos_mem;
 
   pptr->driveno   = geometry->driveno;
   pptr->drivetype = geometry->type;
diff --git a/pxe.inc b/pxe.inc
index 31dbdcb..0cbb72b 100644 (file)
--- a/pxe.inc
+++ b/pxe.inc
 %define PXENV_RESTART_TFTP             0073h
 %define PXENV_MODE_SWITCH              0074h
 
+%define PXENV_EXIT_SUCCESS 0x0000 
+%define PXENV_EXIT_FAILURE 0x0001  
+
+%define PXENV_STATUS_SUCCESS 0x00 
+%define PXENV_STATUS_FAILURE 0x01  
+%define PXENV_STATUS_BAD_FUNC 0x02  
+%define PXENV_STATUS_UNSUPPORTED 0x03  
+%define PXENV_STATUS_KEEP_UNDI 0x04  
+%define PXENV_STATUS_KEEP_ALL 0x05 
+%define PXENV_STATUS_OUT_OF_RESOURCES 0x06  
+%define PXENV_STATUS_ARP_TIMEOUT 0x11  
+%define PXENV_STATUS_UDP_CLOSED 0x18 
+%define PXENV_STATUS_UDP_OPEN 0x19 
+%define PXENV_STATUS_TFTP_CLOSED 0x1A 
+%define PXENV_STATUS_TFTP_OPEN 0x1B  
+%define PXENV_STATUS_MCOPY_PROBLEM 0x20 
+%define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21 
+%define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22 
+%define PXENV_STATUS_BIS_INIT_FAILURE 0x23 
+%define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24 
+%define PXENV_STATUS_BIS_GBOA_FAILURE 0x25 
+%define PXENV_STATUS_BIS_FREE_FAILURE 0x26 
+%define PXENV_STATUS_BIS_GSI_FAILURE 0x27 
+%define PXENV_STATUS_BIS_BAD_CKSUM 0x28  
+%define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30 
+%define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32
+
+%define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 
+%define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 
+%define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 
+%define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38 
+%define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39 
+%define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3A 
+%define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B 
+%define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C 
+%define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D 
+%define PXENV_STATUS_TFTP_NO_FILESIZE 0x3E 
+%define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3F  
+%define PXENV_STATUS_DHCP_TIMEOUT 0x51 
+%define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 
+%define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 
+%define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54  
+%define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 
+%define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 
+%define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62 
+%define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63 
+%define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64 
+%define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65 
+%define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66 
+%define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 
+%define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68 
+%define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69 
+%define PXENV_STATUS_UNDI_INVALID_STATE 0x6A 
+%define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6B 
+%define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6C  
+%define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 
+%define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 
+%define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 
+%define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 
+%define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79  
+%define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xA0 
+%define PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1 
+%define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xA2 
+%define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xA3  
+%define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xB0  
+%define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xC0 
+%define PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1 
+%define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2 
+%define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xC3 
+%define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4 
+%define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5 
+%define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xC6 
+%define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8 
+%define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xC9 
+%define PXENV_STATUS_LOADER_UNDI_START 0xCA 
+%define PXENV_STATUS_LOADER_BC_START 0xCB 
+
 %endif ; _PXE_INC
+
index 4f5e806..6df269e 100644 (file)
@@ -376,6 +376,7 @@ PktTimeout  resw 1                  ; Timeout for current packet
 KernelExtPtr   resw 1                  ; During search, final null pointer
 IPOptionLen    resw 1                  ; Length of IPOption
 LocalBootType  resw 1                  ; Local boot return code
+RealBaseMem    resw 1                  ; Amount of DOS memory after freeing
 TextAttrBX      equ $
 TextAttribute   resb 1                 ; Text attribute for message file
 TextPage        resb 1                 ; Active display page
@@ -476,7 +477,7 @@ _start1:
 
                ; Nothing there either.  Last-ditch: scan memory
                call memory_scan_for_pxe_struct         ; !PXE scan
-               jnc have_pxe
+               jnc near have_pxe
                call memory_scan_for_pxenv_struct       ; PXENV+ scan
                jnc have_pxenv
 
@@ -500,12 +501,12 @@ have_pxenv:
                mov ax,es
                les bx,[es:bx+28h]              ; !PXE structure pointer
                cmp dword [es:bx],'!PXE'
-               je have_pxe
+               je near have_pxe
 
                ; Nope, !PXE structure missing despite API 2.1+, or at least
                ; the pointer is missing.  Do a last-ditch attempt to find it.
                call memory_scan_for_pxe_struct
-               jnc have_pxe
+               jnc near have_pxe
 
                ; Otherwise, no dice, use PXENV+ structure
                mov bx,si
@@ -518,6 +519,43 @@ old_api:   ; Need to use a PXENV+ structure
                mov eax,[es:bx+0Ah]             ; PXE RM API
                mov [PXENVEntry],eax
 
+               mov si,undi_data_msg            ; ***
+               call writestr
+               mov ax,[es:bx+20h]
+               call writehex4
+               call crlf
+               mov si,undi_data_len_msg
+               call writestr
+               mov ax,[es:bx+22h]
+               call writehex4
+               call crlf
+               mov si,undi_code_msg
+               call writestr
+               mov ax,[es:bx+24h]
+               call writehex4
+               call crlf
+               mov si,undi_code_len_msg
+               call writestr
+               mov ax,[es:bx+26h]
+               call writehex4
+               call crlf
+
+               ; Compute base memory size from PXENV+ structure
+               xor esi,esi
+               movzx eax,word [es:bx+20h]      ; UNDI data seg
+               cmp ax,[es:bx+24h]              ; UNDI code seg
+               ja .use_data
+               mov ax,[es:bx+24h]
+               mov si,[es:bx+26h]
+               jmp short .combine
+.use_data:
+               mov si,[es:bx+22h]
+.combine:
+               shl eax,4
+               add eax,esi
+               shr eax,10                      ; Convert to kilobytes
+               mov [RealBaseMem],ax
+
                mov si,pxenventry_msg
                call writestr
                mov ax,[PXENVEntry+2]
@@ -527,12 +565,48 @@ old_api:  ; Need to use a PXENV+ structure
                mov ax,[PXENVEntry]
                call writehex4
                call crlf
-               jmp short have_entrypoint
+               jmp near have_entrypoint
 
 have_pxe:
                mov eax,[es:bx+10h]
                mov [PXEEntry],eax
 
+               mov si,undi_data_msg            ; ***
+               call writestr
+               mov eax,[es:bx+2Ah]
+               call writehex8
+               call crlf
+               mov si,undi_data_len_msg
+               call writestr
+               mov ax,[es:bx+2Eh]
+               call writehex4
+               call crlf
+               mov si,undi_code_msg
+               call writestr
+               mov ax,[es:bx+32h]
+               call writehex8
+               call crlf
+               mov si,undi_code_len_msg
+               call writestr
+               mov ax,[es:bx+36h]
+               call writehex4
+               call crlf
+
+               ; Compute base memory size from !PXE structure
+               xor esi,esi
+               mov eax,[es:bx+2Ah]
+               cmp eax,[es:bx+32h]
+               ja .use_data
+               mov eax,[es:bx+32h]
+               mov si,[es:bx+36h]
+               jmp short .combine
+.use_data:
+               mov si,[es:bx+2Eh]
+.combine:
+               add eax,esi
+               shr eax,10
+               mov [RealBaseMem],ax
+
                mov si,pxeentry_msg
                call writestr
                mov ax,[PXEEntry+2]
@@ -4161,7 +4235,8 @@ ack_packet:
 ;
 ; unload_pxe:
 ;
-; This function unloads the PXE and UNDI stacks.
+; This function unloads the PXE and UNDI stacks and unclaims
+; the memory.
 ;
 unload_pxe:
                mov di,pxe_udp_close_pkt
@@ -4173,7 +4248,32 @@ unload_pxe:
                mov di,pxe_unload_stack_pkt
                mov bx,PXENV_UNLOAD_STACK
                call far [PXENVEntry]
+               jc .cant_free
+               cmp word [pxe_unload_stack_pkt.status],byte PXENV_STATUS_SUCCESS
+               jne .cant_free
+
+               mov ax,[RealBaseMem]
+               cmp ax,[BIOS_fbm]               ; Sanity check
+               jna .cant_free
+
+               ; Check that PXE actually unhooked the INT 1Ah chain
+               movzx ebx,word [4*0x1a]
+               movzx ecx,word [4*0x1a+2]
+               shl ecx,4
+               add ebx,ecx
+               shr ebx,10
+               cmp bx,ax                       ; Not in range
+               jae .ok
+               cmp bx,[BIOS_fbm]
+               jae .cant_free          
+
+.ok:
+               mov [BIOS_fbm],ax
                ret
+               
+.cant_free:
+               mov si,cant_free_msg
+               jmp writestr
 
 ;
 ; gendotquad
@@ -4786,6 +4886,11 @@ pxeentry_msg     db 'PXE entry point found (we hope) at ', 0
 pxenventry_msg db 'PXENV entry point found (we hope) at ', 0
 trymempxe_msg  db 'Scanning memory for !PXE structure... ', 0
 trymempxenv_msg        db 'Scanning memory for PXENV+ structure... ', 0
+undi_data_msg    db 'UNDI data segment at:   ',0
+undi_data_len_msg db 'UNDI data segment size: ',0 
+undi_code_msg    db 'UNDI code segment at:   ',0
+undi_code_len_msg db 'UNDI code segment size: ',0 
+cant_free_msg  db 'Failed to free base memory, sorry...', CR, LF, 0
 notfound_msg   db 'not found', CR, LF, 0
 myipaddr_msg   db 'My IP address seems to be ',0
 tftpprefix_msg db 'TFTP prefix: ', 0