diff options
author | hpa <hpa> | 2001-12-16 00:03:28 +0000 |
---|---|---|
committer | hpa <hpa> | 2001-12-16 00:03:28 +0000 |
commit | 9d0869d27f663580d408e76cb2ea210714dea553 (patch) | |
tree | 4106606ef55794780784a35af434a42eb1bcc94b | |
parent | b9f4a599f1bd31369f3f3f49e05d2102ceb295fd (diff) | |
download | syslinux-9d0869d27f663580d408e76cb2ea210714dea553.tar.gz |
Make a valiant, and probably futile, attempt to free memory aftersyslinux-1.65
running the PXE stack.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | memdisk/setup.c | 3 | ||||
-rw-r--r-- | pxe.inc | 78 | ||||
-rw-r--r-- | pxelinux.asm | 115 |
4 files changed, 194 insertions, 5 deletions
@@ -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 diff --git a/memdisk/setup.c b/memdisk/setup.c index e75bcb40..2ab5b98d 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -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; @@ -56,4 +56,82 @@ %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 + diff --git a/pxelinux.asm b/pxelinux.asm index 4f5e806a..6df269e6 100644 --- a/pxelinux.asm +++ b/pxelinux.asm @@ -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 |