Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
Michael Brown committed Nov 18, 2008
1 parent 85f82f0 commit 0a8a17e
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 29 deletions.
15 changes: 14 additions & 1 deletion src/arch/i386/include/biosint.h
Expand Up @@ -6,9 +6,22 @@
*
*/

#include <realmode.h>

struct segoff;

extern int hooked_bios_interrupts;
/**
* Hooked interrupt count
*
* At exit, after unhooking all possible interrupts, this counter
* should be examined. If it is non-zero, it means that we failed to
* unhook at least one interrupt vector, and so must not free up the
* memory we are using. (Note that this also implies that we should
* re-hook INT 15 in order to hide ourselves from the memory map).
*/
extern uint16_t __text16 ( hooked_bios_interrupts );
#define hooked_bios_interrupts __use_text16 ( hooked_bios_interrupts )

extern void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
struct segoff *chain_vector );
extern int unhook_bios_interrupt ( unsigned int interrupt,
Expand Down
11 changes: 0 additions & 11 deletions src/arch/i386/interface/pcbios/biosint.c
Expand Up @@ -7,17 +7,6 @@
*
*/

/**
* Hooked interrupt count
*
* At exit, after unhooking all possible interrupts, this counter
* should be examined. If it is non-zero, it means that we failed to
* unhook at least one interrupt vector, and so must not free up the
* memory we are using. (Note that this also implies that we should
* re-hook INT 15 in order to hide ourselves from the memory map).
*/
int hooked_bios_interrupts = 0;

/**
* Hook INT vector
*
Expand Down
6 changes: 5 additions & 1 deletion src/arch/i386/prefix/dskprefix.S
Expand Up @@ -353,6 +353,7 @@ msg1end:
.word 0xAA55

start_runtime:
/* Install gPXE */
call install

/* Set up real-mode stack */
Expand All @@ -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
Expand Down
6 changes: 5 additions & 1 deletion src/arch/i386/prefix/hdprefix.S
Expand Up @@ -82,6 +82,7 @@ load_failed:
.byte 0x55, 0xaa

start_image:
/* Install gPXE */
call install

/* Set up real-mode stack */
Expand All @@ -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
91 changes: 86 additions & 5 deletions src/arch/i386/prefix/libprefix.S
Expand Up @@ -537,30 +537,88 @@ 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

/* Update FBMS */
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)
*
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion src/arch/i386/prefix/lkrnprefix.S
Expand Up @@ -189,6 +189,7 @@ run_gpxe:
movw %ax, %ss
movw $0x7c00, %sp

/* Install gPXE */
call install

/* Set up real-mode stack */
Expand All @@ -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
7 changes: 5 additions & 2 deletions src/arch/i386/prefix/nbiprefix.S
Expand Up @@ -52,7 +52,7 @@ memlen: .long _filesz - 512
*****************************************************************************
*/
entry:
/* Install low and high memory regions */
/* Install gPXE */
call install

/* Jump to .text16 segment */
Expand All @@ -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
Expand Down
13 changes: 8 additions & 5 deletions src/arch/i386/prefix/pxeprefix.S
Expand Up @@ -318,7 +318,7 @@ print_free_basemem:
*****************************************************************************
*/
finished:
jmp run_etherboot
jmp run_gpxe

/*****************************************************************************
* Subroutine: print segment:offset address
Expand Down Expand Up @@ -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 */
Expand All @@ -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
Expand Down
7 changes: 5 additions & 2 deletions src/arch/i386/prefix/romprefix.S
Expand Up @@ -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
Expand Down

0 comments on commit 0a8a17e

Please sign in to comment.