[SeaBIOS] [PATCH v2 01/19] post: Avoid calling maininit() from init reloc_init().

David Woodhouse dwmw2 at infradead.org
Tue Feb 5 17:47:40 CET 2013


From: Kevin O'Connor <kevin at koconnor.net>

Call maininit() and startBoot() from handle_post().  This reduces the
chaining of calls during the relocation phase, and allows maininit()
to return (which may be useful when using SeaBIOS as a CSM).

This change relies on reloc_init() modifying the maininit() call in
handle_post() when relocations are enabled.  It technically may not be
safe to modify gcc generated code when in that gcc code, but it should
be safe in practice.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/pmm.c  |  5 +++++
 src/post.c | 46 ++++++++++++++++------------------------------
 2 files changed, 21 insertions(+), 30 deletions(-)

diff --git a/src/pmm.c b/src/pmm.c
index 653c9e2..77138dc 100644
--- a/src/pmm.c
+++ b/src/pmm.c
@@ -265,6 +265,11 @@ malloc_fixupreloc(void)
         return;
     dprintf(3, "malloc fixup reloc\n");
 
+    // Move low-memory initial variable content to new location.
+    extern u8 datalow_start[], datalow_end[], final_datalow_start[];
+    memmove(final_datalow_start, datalow_start, datalow_end - datalow_start);
+
+    // Fixup pointers back to ZoneX globals.
     int i;
     for (i=0; i<ARRAY_SIZE(Zones); i++) {
         struct zone_s *zone = Zones[i];
diff --git a/src/post.c b/src/post.c
index f3b56b8..6a91f81 100644
--- a/src/post.c
+++ b/src/post.c
@@ -200,7 +200,7 @@ init_hw(void)
 }
 
 // Begin the boot process by invoking an int0x19 in 16bit mode.
-void VISIBLE32FLAT
+static void
 startBoot(void)
 {
     // Clear low-memory allocations (required by PMM spec).
@@ -214,9 +214,12 @@ startBoot(void)
 }
 
 // Main setup code.
-static void
+void VISIBLE32INIT
 maininit(void)
 {
+    // Running at new code address - do code relocation fixups
+    malloc_fixupreloc();
+
     // Setup romfile items.
     qemu_cfg_romfile_setup();
     coreboot_cbfs_setup();
@@ -287,9 +290,6 @@ maininit(void)
 
     // Write protect bios memory.
     make_bios_readonly();
-
-    // Invoke int 19 to start boot process.
-    startBoot();
 }
 
 
@@ -297,21 +297,6 @@ maininit(void)
  * POST entry and code relocation
  ****************************************************************/
 
-// Relocation fixup code that runs at new address after relocation complete.
-static void
-afterReloc(void)
-{
-    // Running at new code address - do code relocation fixups
-    malloc_fixupreloc();
-
-    // Move low-memory initial variable content to new location.
-    extern u8 datalow_start[], datalow_end[], final_datalow_start[];
-    memmove(final_datalow_start, datalow_start, datalow_end - datalow_start);
-
-    // Run main code
-    maininit();
-}
-
 // Update given relocs for the code at 'dest' with a given 'delta'
 static void
 updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta)
@@ -325,10 +310,8 @@ updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta)
 static void
 reloc_init(void)
 {
-    if (!CONFIG_RELOCATE_INIT) {
-        maininit();
+    if (!CONFIG_RELOCATE_INIT)
         return;
-    }
     // Symbols populated by the build.
     extern u8 code32flat_start[];
     extern u8 _reloc_min_align;
@@ -359,15 +342,12 @@ reloc_init(void)
     updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta);
     updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
 
-    // Call maininit() in relocated code.
-    void (*func)(void) = (void*)afterReloc + delta;
     barrier();
-    func();
 }
 
 // Setup for code relocation and then call reloc_init
 void VISIBLE32INIT
-dopost(void)
+doreloc(void)
 {
     HaveRunPost = 1;
 
@@ -376,7 +356,7 @@ dopost(void)
     ram_probe();
     malloc_setup();
 
-    // Relocate initialization code and call maininit().
+    // Relocate initialization code.
     reloc_init();
 }
 
@@ -404,6 +384,12 @@ handle_post(void)
     // Allow writes to modify bios area (0xf0000)
     make_bios_writable();
 
-    // Now that memory is read/writable - start post process.
-    dopost();
+    // Do pre-relocation setup and then relocate initialization code.
+    doreloc();
+
+    // Run main code
+    maininit();
+
+    // Invoke int 19 to start boot process.
+    startBoot();
 }
-- 
1.8.1




More information about the SeaBIOS mailing list