mirror of
https://github.com/ipxe/ipxe
synced 2025-12-16 09:32:33 +03:00
[i386] Free allocated base memory on exit, if possible
Code paths that automatically allocate memory from the FBMS at 40:13 should also free it, if possible. Freeing this memory will not be possible if either 1. The FBMS has been modified since our allocation, or 2. We have not been able to unhook one or more BIOS interrupt vectors.
This commit is contained in:
@@ -353,6 +353,7 @@ msg1end:
|
||||
.word 0xAA55
|
||||
|
||||
start_runtime:
|
||||
/* Install gPXE */
|
||||
call install
|
||||
|
||||
/* Set up real-mode stack */
|
||||
@@ -368,7 +369,10 @@ start_runtime:
|
||||
pushl $main
|
||||
pushw %cs
|
||||
call prot_call
|
||||
popl %eax /* discard */
|
||||
popl %ecx /* discard */
|
||||
|
||||
/* Uninstall gPXE */
|
||||
call uninstall
|
||||
|
||||
/* Boot next device */
|
||||
int $0x18
|
||||
|
||||
@@ -82,6 +82,7 @@ load_failed:
|
||||
.byte 0x55, 0xaa
|
||||
|
||||
start_image:
|
||||
/* Install gPXE */
|
||||
call install
|
||||
|
||||
/* Set up real-mode stack */
|
||||
@@ -97,7 +98,10 @@ start_image:
|
||||
pushl $main
|
||||
pushw %cs
|
||||
call prot_call
|
||||
popl %eax /* discard */
|
||||
popl %ecx /* discard */
|
||||
|
||||
/* Uninstall gPXE */
|
||||
call uninstall
|
||||
|
||||
/* Boot next device */
|
||||
int $0x18
|
||||
|
||||
@@ -537,17 +537,20 @@ install_block:
|
||||
.code16
|
||||
.globl alloc_basemem
|
||||
alloc_basemem:
|
||||
/* Preserve registers */
|
||||
pushw %fs
|
||||
|
||||
/* FBMS => %ax as segment address */
|
||||
movw $0x40, %ax
|
||||
movw %ax, %fs
|
||||
pushw $0x40
|
||||
popw %fs
|
||||
movw %fs:0x13, %ax
|
||||
shlw $6, %ax
|
||||
|
||||
/* .data16 segment address */
|
||||
/* Calculate .data16 segment address */
|
||||
subw $_data16_memsz_pgh, %ax
|
||||
pushw %ax
|
||||
|
||||
/* .text16 segment address */
|
||||
/* Calculate .text16 segment address */
|
||||
subw $_text16_memsz_pgh, %ax
|
||||
pushw %ax
|
||||
|
||||
@@ -555,12 +558,67 @@ alloc_basemem:
|
||||
shrw $6, %ax
|
||||
movw %ax, %fs:0x13
|
||||
|
||||
/* Return */
|
||||
/* Retrieve .text16 and .data16 segment addresses */
|
||||
popw %ax
|
||||
popw %bx
|
||||
|
||||
/* Restore registers and return */
|
||||
popw %fs
|
||||
ret
|
||||
.size alloc_basemem, . - alloc_basemem
|
||||
|
||||
/****************************************************************************
|
||||
* free_basemem (real-mode near call)
|
||||
*
|
||||
* Free space allocated with alloc_basemem.
|
||||
*
|
||||
* Parameters:
|
||||
* %ax : .text16 segment address
|
||||
* %bx : .data16 segment address
|
||||
* Returns:
|
||||
* %ax : 0 if successfully freed
|
||||
* Corrupts:
|
||||
* none
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".text16"
|
||||
.code16
|
||||
.globl free_basemem
|
||||
free_basemem:
|
||||
/* Preserve registers */
|
||||
pushw %fs
|
||||
|
||||
/* Check FBMS counter */
|
||||
pushw %ax
|
||||
shrw $6, %ax
|
||||
pushw $0x40
|
||||
popw %fs
|
||||
cmpw %ax, %fs:0x13
|
||||
popw %ax
|
||||
jne 1f
|
||||
|
||||
/* Check hooked interrupt count */
|
||||
cmpw $0, %cs:hooked_bios_interrupts
|
||||
jne 1f
|
||||
|
||||
/* OK to free memory */
|
||||
addw $_text16_memsz_pgh, %ax
|
||||
addw $_data16_memsz_pgh, %ax
|
||||
shrw $6, %ax
|
||||
movw %ax, %fs:0x13
|
||||
xorw %ax, %ax
|
||||
|
||||
1: /* Restore registers and return */
|
||||
popw %fs
|
||||
ret
|
||||
.size free_basemem, . - free_basemem
|
||||
|
||||
.section ".text16.data"
|
||||
.globl hooked_bios_interrupts
|
||||
hooked_bios_interrupts:
|
||||
.word 0
|
||||
.size hooked_bios_interrupts, . - hooked_bios_interrupts
|
||||
|
||||
/****************************************************************************
|
||||
* install (real-mode near call)
|
||||
*
|
||||
@@ -709,6 +767,29 @@ prot_call_vector:
|
||||
.size prot_call_vector, . - prot_call_vector
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* uninstall (real-mode near call)
|
||||
*
|
||||
* Uninstall all text and data segments.
|
||||
*
|
||||
* Parameters:
|
||||
* %ax : .text16 segment address
|
||||
* %bx : .data16 segment address
|
||||
* Returns:
|
||||
* none
|
||||
* Corrupts:
|
||||
* none
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".text16"
|
||||
.code16
|
||||
.globl uninstall
|
||||
uninstall:
|
||||
call free_basemem
|
||||
ret
|
||||
.size uninstall, . - uninstall
|
||||
|
||||
|
||||
|
||||
/* File split information for the compressor */
|
||||
#if COMPRESS
|
||||
|
||||
@@ -189,6 +189,7 @@ run_gpxe:
|
||||
movw %ax, %ss
|
||||
movw $0x7c00, %sp
|
||||
|
||||
/* Install gPXE */
|
||||
call install
|
||||
|
||||
/* Set up real-mode stack */
|
||||
@@ -204,7 +205,10 @@ run_gpxe:
|
||||
pushl $main
|
||||
pushw %cs
|
||||
call prot_call
|
||||
popl %eax /* discard */
|
||||
popl %ecx /* discard */
|
||||
|
||||
/* Uninstall gPXE */
|
||||
call uninstall
|
||||
|
||||
/* Boot next device */
|
||||
int $0x18
|
||||
|
||||
@@ -52,7 +52,7 @@ memlen: .long _filesz - 512
|
||||
*****************************************************************************
|
||||
*/
|
||||
entry:
|
||||
/* Install low and high memory regions */
|
||||
/* Install gPXE */
|
||||
call install
|
||||
|
||||
/* Jump to .text16 segment */
|
||||
@@ -64,7 +64,10 @@ entry:
|
||||
pushl $main
|
||||
pushw %cs
|
||||
call prot_call
|
||||
popl %eax /* discard */
|
||||
popl %ecx /* discard */
|
||||
|
||||
/* Uninstall gPXE */
|
||||
call uninstall
|
||||
|
||||
/* Reboot system */
|
||||
int $0x19
|
||||
|
||||
@@ -318,7 +318,7 @@ print_free_basemem:
|
||||
*****************************************************************************
|
||||
*/
|
||||
finished:
|
||||
jmp run_etherboot
|
||||
jmp run_gpxe
|
||||
|
||||
/*****************************************************************************
|
||||
* Subroutine: print segment:offset address
|
||||
@@ -554,11 +554,11 @@ flags: .word UNDI_FL_STARTED
|
||||
.equ undi_device_size, ( . - undi_device )
|
||||
|
||||
/*****************************************************************************
|
||||
* Run Etherboot main code
|
||||
* Run gPXE main code
|
||||
*****************************************************************************
|
||||
*/
|
||||
run_etherboot:
|
||||
/* Install Etherboot */
|
||||
run_gpxe:
|
||||
/* Install gPXE */
|
||||
call install
|
||||
|
||||
/* Set up real-mode stack */
|
||||
@@ -585,7 +585,10 @@ run_etherboot:
|
||||
pushl $main
|
||||
pushw %cs
|
||||
call prot_call
|
||||
popl %eax /* discard */
|
||||
popl %ecx /* discard */
|
||||
|
||||
/* Uninstall gPXE */
|
||||
call uninstall
|
||||
|
||||
/* Boot next device */
|
||||
int $0x18
|
||||
|
||||
@@ -591,8 +591,11 @@ exec: /* Set %ds = %cs */
|
||||
pushl $main
|
||||
pushw %cs
|
||||
call prot_call
|
||||
/* No need to clean up stack; we are about to reload %ss:sp */
|
||||
|
||||
popl %ecx /* discard */
|
||||
|
||||
/* Uninstall gPXE */
|
||||
call uninstall
|
||||
|
||||
/* Restore BIOS stack */
|
||||
movw %dx, %ss
|
||||
movw %bp, %sp
|
||||
|
||||
Reference in New Issue
Block a user