From f06e8c9707ed93d9dd98bdbfc498ddf86d8d13c8 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 10 Apr 2005 18:18:37 +0000 Subject: [PATCH] Added post-relocation function table. --- src/arch/i386/core/relocate.c | 25 ++++++++++++++++++++----- src/arch/i386/include/relocate.h | 20 +++++++++++++++----- src/arch/i386/scripts/i386.lds | 5 +++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/arch/i386/core/relocate.c b/src/arch/i386/core/relocate.c index 98734535..3a2702a1 100644 --- a/src/arch/i386/core/relocate.c +++ b/src/arch/i386/core/relocate.c @@ -2,6 +2,7 @@ #include "memsizes.h" #include "osdep.h" #include "etherboot.h" +#include "init.h" #include "relocate.h" #ifndef KEEP_IT_REAL @@ -38,6 +39,8 @@ extern char _max_align[]; /* Linker symbols */ extern char _text[]; extern char _end[]; +extern struct post_reloc_fn post_reloc_fns[]; +extern struct post_reloc_fn post_reloc_fns_end[]; #undef DBG #ifdef DEBUG_RELOCATE @@ -46,9 +49,10 @@ extern char _end[]; #define DBG(...) #endif -void relocate ( void ) { +static void relocate ( void ) { unsigned long addr, eaddr, size; unsigned i; + struct post_reloc_fn *post_reloc_fn; /* Walk through the memory map and find the highest address * below 4GB that etherboot will fit into. Ensure etherboot @@ -186,12 +190,23 @@ void relocate ( void ) { relocate_to ( addr ); /* Note that we cannot make real-mode calls - * (e.g. printf) at this point, because the pointer - * installed_librm uses a virtual address (in order - * that it can have a valid initialiser) and so is - * currently invalid. + * (e.g. printf) at this point, because librm has just + * been moved to high memory. */ + + /* Call any registered post-relocation functions. + * librm has a post-relocation function to install a + * new librm into base memory. + */ + for ( post_reloc_fn = post_reloc_fns; + post_reloc_fn < post_reloc_fns_end ; post_reloc_fn++ ) { + if ( post_reloc_fn->post_reloc ) + post_reloc_fn->post_reloc (); + } + } } +INIT_FN ( INIT_RELOCATE, relocate, NULL, NULL ); + #endif /* ! KEEP_IT_REAL */ diff --git a/src/arch/i386/include/relocate.h b/src/arch/i386/include/relocate.h index 4aec54e4..31965d4f 100644 --- a/src/arch/i386/include/relocate.h +++ b/src/arch/i386/include/relocate.h @@ -1,14 +1,24 @@ #ifndef RELOCATE_H #define RELOCATE_H -#ifdef KEEP_IT_REAL - /* relocate() is conceptually impossible with KEEP_IT_REAL */ -#define relocate() +#ifndef KEEP_IT_REAL -#else +/* An entry in the post-relocation function table */ +struct post_reloc_fn { + void ( *post_reloc ) ( void ); +}; -extern void relocate ( void ); +/* Use double digits to avoid problems with "10" < "9" on alphabetic sort */ +#define POST_RELOC_LIBRM "00" + +/* Macro for creating a post-relocation function table entry */ +#define POST_RELOC_FN( post_reloc_order, post_reloc_func ) \ + static struct post_reloc_fn post_reloc_functions \ + __attribute__ (( used, __section__( ".post_reloc_fns." \ + post_reloc_order ) )) = { \ + .post_reloc = post_reloc_func, \ + }; #endif diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds index 4f9df561..6888da36 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -140,6 +140,8 @@ SECTIONS { __data = .; *(.data) *(.data.*) + + /* Various tables */ pci_drivers = .; *(.drivers.pci) pci_drivers_end = .; @@ -149,6 +151,9 @@ SECTIONS { console_drivers = .; *(.drivers.console) console_drivers_end = .; + post_reloc_fns = .; + *(SORT(.post_reloc_fns.*)) + post_reloc_fns_end = .; init_fns = .; *(SORT(.init_fns.*)) init_fns_end = .;