]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
Added post-relocation function table.
authorMichael Brown <mcb30@etherboot.org>
Sun, 10 Apr 2005 18:18:37 +0000 (18:18 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sun, 10 Apr 2005 18:18:37 +0000 (18:18 +0000)
src/arch/i386/core/relocate.c
src/arch/i386/include/relocate.h
src/arch/i386/scripts/i386.lds

index 98734535affbdfff154d658ad3c09f40d34c3371..3a2702a1f3c7eeeafbdaf0039ff6e90c8f994ad4 100644 (file)
@@ -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 */
index 4aec54e48339e401c7e755aba16a68c715c2e62a..31965d4fb716bdf3973596015888eaff919ff070 100644 (file)
@@ -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
+
+/* An entry in the post-relocation function table */
+struct post_reloc_fn {
+       void ( *post_reloc ) ( void );
+};
 
-#else
+/* Use double digits to avoid problems with "10" < "9" on alphabetic sort */
+#define POST_RELOC_LIBRM       "00"
 
-extern void relocate ( void );
+/* 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
 
index 4f9df56196cd33fb0c0163dad880c5790b9e676b..6888da364a910464299c04204813ec21e9d28c31 100644 (file)
@@ -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 = .;