Add support for moving the 32bit init code out of the e/f-segments and into temporary ram. Update the relocations in the code so that it can live at its new address.
This frees up memory for other uses in the e/f segments. --- src/config.h | 2 ++ src/post.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/src/config.h b/src/config.h index 4572ee5..f9bf3b8 100644 --- a/src/config.h +++ b/src/config.h @@ -26,6 +26,8 @@ #define CONFIG_THREADS 1 // Allow hardware init to run in parallel with optionrom execution #define CONFIG_THREAD_OPTIONROMS 0 +// Support relocating the one time initialization code to high memory +#define CONFIG_RELOCATE_INIT 1 // Support int13 disk/floppy drive functions #define CONFIG_DRIVES 1 // Support floppy drive access diff --git a/src/post.c b/src/post.c index 4d99935..a93affc 100644 --- a/src/post.c +++ b/src/post.c @@ -183,7 +183,7 @@ init_hw(void) }
// Begin the boot process by invoking an int0x19 in 16bit mode. -static void +void VISIBLE32FLAT startBoot(void) { // Clear low-memory allocations (required by PMM spec). @@ -268,9 +268,57 @@ maininit(void) startBoot(); }
+ +/**************************************************************** + * Code relocation + ****************************************************************/ + +static void +updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) +{ + u32 *reloc; + for (reloc = rstart; reloc < rend; reloc++) + *((u32*)(dest + *reloc)) += delta; +} + +// Start of Power On Self Test - the BIOS initilization. This +// function sets up for and attempts relocation of the init code. +static void +reloc_init(void) +{ + if (!CONFIG_RELOCATE_INIT) { + maininit(); + return; + } + extern u8 code32flat_start[]; + extern u8 _reloc_min_align[]; + extern u32 _reloc_abs_start[], _reloc_abs_end[]; + extern u32 _reloc_rel_start[], _reloc_rel_end[]; + extern u32 _reloc_init_start[], _reloc_init_end[]; + extern u8 code32init_start[], code32init_end[]; + + u32 initsize = code32init_end - code32init_start; + u32 align = (u32)&_reloc_min_align; + void *dest = memalign_tmp(align, initsize); + if (!dest) + panic("No space for init relocation.\n"); + + dprintf(1, "Relocating init from %p to %p (size %d)\n" + , code32init_start, dest, initsize); + s32 delta = dest - (void*)code32init_start; + memcpy(dest, code32init_start, initsize); + updateRelocs(dest, _reloc_abs_start, _reloc_abs_end, delta); + updateRelocs(dest, _reloc_rel_start, _reloc_rel_end, -delta); + updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta); + void (*func)(void) = (void*)maininit + delta; + barrier(); + func(); +} + static int HaveRunPost;
// Start of Power On Self Test (POST) - the BIOS initilization phase. +// This function sets up for and attempts relocation of the init code. void VISIBLE32INIT post(void) { @@ -285,7 +333,7 @@ post(void) ram_probe(); malloc_setup();
- maininit(); + reloc_init(); }