summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/include/biosint.h15
-rw-r--r--src/arch/i386/interface/pcbios/biosint.c11
-rw-r--r--src/arch/i386/prefix/dskprefix.S6
-rw-r--r--src/arch/i386/prefix/hdprefix.S6
-rw-r--r--src/arch/i386/prefix/libprefix.S91
-rw-r--r--src/arch/i386/prefix/lkrnprefix.S6
-rw-r--r--src/arch/i386/prefix/nbiprefix.S7
-rw-r--r--src/arch/i386/prefix/pxeprefix.S13
-rw-r--r--src/arch/i386/prefix/romprefix.S7
9 files changed, 133 insertions, 29 deletions
diff --git a/src/arch/i386/include/biosint.h b/src/arch/i386/include/biosint.h
index d4e34963..d365cf01 100644
--- a/src/arch/i386/include/biosint.h
+++ b/src/arch/i386/include/biosint.h
@@ -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,
diff --git a/src/arch/i386/interface/pcbios/biosint.c b/src/arch/i386/interface/pcbios/biosint.c
index 8ef2d7ab..1306f918 100644
--- a/src/arch/i386/interface/pcbios/biosint.c
+++ b/src/arch/i386/interface/pcbios/biosint.c
@@ -8,17 +8,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
*
* @v interrupt INT number
diff --git a/src/arch/i386/prefix/dskprefix.S b/src/arch/i386/prefix/dskprefix.S
index e3a39cce..0156812a 100644
--- a/src/arch/i386/prefix/dskprefix.S
+++ b/src/arch/i386/prefix/dskprefix.S
@@ -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
diff --git a/src/arch/i386/prefix/hdprefix.S b/src/arch/i386/prefix/hdprefix.S
index ffe1ee57..086d7f45 100644
--- a/src/arch/i386/prefix/hdprefix.S
+++ b/src/arch/i386/prefix/hdprefix.S
@@ -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
diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S
index 61549618..56ca64d9 100644
--- a/src/arch/i386/prefix/libprefix.S
+++ b/src/arch/i386/prefix/libprefix.S
@@ -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,13 +558,68 @@ 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)
*
* Install all text and data segments.
@@ -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
diff --git a/src/arch/i386/prefix/lkrnprefix.S b/src/arch/i386/prefix/lkrnprefix.S
index f23e4076..094263d2 100644
--- a/src/arch/i386/prefix/lkrnprefix.S
+++ b/src/arch/i386/prefix/lkrnprefix.S
@@ -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
diff --git a/src/arch/i386/prefix/nbiprefix.S b/src/arch/i386/prefix/nbiprefix.S
index ec210094..d1753e30 100644
--- a/src/arch/i386/prefix/nbiprefix.S
+++ b/src/arch/i386/prefix/nbiprefix.S
@@ -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
diff --git a/src/arch/i386/prefix/pxeprefix.S b/src/arch/i386/prefix/pxeprefix.S
index 32ff2961..d1eb962f 100644
--- a/src/arch/i386/prefix/pxeprefix.S
+++ b/src/arch/i386/prefix/pxeprefix.S
@@ -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
diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S
index 7b545f4b..a6431cd9 100644
--- a/src/arch/i386/prefix/romprefix.S
+++ b/src/arch/i386/prefix/romprefix.S
@@ -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