aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2001-12-16 00:03:28 +0000
committerhpa <hpa>2001-12-16 00:03:28 +0000
commit9d0869d27f663580d408e76cb2ea210714dea553 (patch)
tree4106606ef55794780784a35af434a42eb1bcc94b
parentb9f4a599f1bd31369f3f3f49e05d2102ceb295fd (diff)
downloadsyslinux-9d0869d27f663580d408e76cb2ea210714dea553.tar.gz
syslinux-9d0869d27f663580d408e76cb2ea210714dea553.tar.xz
syslinux-9d0869d27f663580d408e76cb2ea210714dea553.zip
Make a valiant, and probably futile, attempt to free memory aftersyslinux-1.65
running the PXE stack.
-rw-r--r--NEWS3
-rw-r--r--memdisk/setup.c3
-rw-r--r--pxe.inc78
-rw-r--r--pxelinux.asm115
4 files changed, 194 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index e55e28c5..e290fe8b 100644
--- 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
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;
diff --git a/pxe.inc b/pxe.inc
index 31dbdcb8..0cbb72bc 100644
--- a/pxe.inc
+++ b/pxe.inc
@@ -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