[SeaBIOS] [PATCH 10/10] memmap: Introduce SYMBOL() macro to access linker script symbols

Kevin O'Connor kevin at koconnor.net
Fri Oct 9 19:53:38 CEST 2015


Use a macro to define and obtain the value of a symbol introduced by
the linker scripts (scripts/layoutrom.py).

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/biosvar.h       |  6 +++---
 src/fw/biostables.c | 10 +++++-----
 src/fw/csm.c        |  4 ++--
 src/fw/shadow.c     | 10 ++++------
 src/malloc.c        | 25 ++++++++++++-------------
 src/memmap.h        |  4 ++++
 src/post.c          | 35 ++++++++++++++++-------------------
 7 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/src/biosvar.h b/src/biosvar.h
index 3b40957..f61fb6a 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -8,6 +8,7 @@
 
 #include "config.h" // SEG_BDA
 #include "farptr.h" // GET_FARVAR
+#include "memmap.h" // SYMBOL
 #include "std/bda.h" // struct bios_data_area_s
 
 
@@ -112,13 +113,12 @@ static inline u16 get_global_seg(void) {
  * "Low" memory variables
  ****************************************************************/
 
-extern u8 _zonelow_seg, zonelow_base[];
-#define SEG_LOW ((u32)&_zonelow_seg)
+#define SEG_LOW SYMBOL(_zonelow_seg)
 
 #if MODESEGMENT
 #define GET_LOW(var)            GET_FARVAR(SEG_LOW, (var))
 #define SET_LOW(var, val)       SET_FARVAR(SEG_LOW, (var), (val))
-#define LOWFLAT2LOW(var) ((typeof(var))((void*)(var) - (u32)zonelow_base))
+#define LOWFLAT2LOW(var) ((typeof(var))((void*)(var) - SYMBOL(zonelow_base)))
 #else
 #define GET_LOW(var)            (var)
 #define SET_LOW(var, val)       do { (var) = (val); } while (0)
diff --git a/src/fw/biostables.c b/src/fw/biostables.c
index 71a1a0d..cc7a730 100644
--- a/src/fw/biostables.c
+++ b/src/fw/biostables.c
@@ -6,14 +6,15 @@
 
 #include "byteorder.h" // le32_to_cpu
 #include "config.h" // CONFIG_*
+#include "hw/pci.h" // pci_config_writeb
 #include "malloc.h" // malloc_fseg
+#include "memmap.h" // SYMBOL
 #include "output.h" // dprintf
-#include "hw/pci.h" // pci_config_writeb
+#include "romfile.h" // romfile_find
 #include "std/acpi.h" // struct rsdp_descriptor
 #include "std/mptable.h" // MPTABLE_SIGNATURE
 #include "std/pirtable.h" // struct pir_header
 #include "std/smbios.h" // struct smbios_entry_point
-#include "romfile.h"
 #include "string.h" // memcpy
 #include "util.h" // copy_table
 #include "x86.h" // outb
@@ -122,9 +123,8 @@ copy_acpi_rsdp(void *pos)
 
 void *find_acpi_rsdp(void)
 {
-    extern u8 zonefseg_start[], zonefseg_end[];
-    unsigned long start = (unsigned long)zonefseg_start;
-    unsigned long end = (unsigned long)zonefseg_end;
+    unsigned long start = SYMBOL(zonefseg_start);
+    unsigned long end = SYMBOL(zonefseg_end);
     unsigned long pos;
 
     for (pos = ALIGN(start, 0x10); pos <= ALIGN_DOWN(end, 0x10); pos += 0x10)
diff --git a/src/fw/csm.c b/src/fw/csm.c
index 0467560..c837d17 100644
--- a/src/fw/csm.c
+++ b/src/fw/csm.c
@@ -11,6 +11,7 @@
 #include "hw/pci.h" // pci_probe_devices
 #include "hw/pic.h" // pic_irqmask_read
 #include "malloc.h" // csm_malloc_preinit
+#include "memmap.h" // SYMBOL
 #include "output.h" // dprintf
 #include "paravirt.h" // qemu_preinit
 #include "stacks.h" // wait_threads
@@ -47,12 +48,11 @@ static void
 csm_return(struct bregs *regs)
 {
     u32 rommax = rom_get_max();
-    extern u8 final_readonly_start[];
 
     dprintf(3, "handle_csm returning AX=%04x\n", regs->ax);
 
     csm_compat_table.UmaAddress = rommax;
-    csm_compat_table.UmaSize = (u32)final_readonly_start - rommax;
+    csm_compat_table.UmaSize = SYMBOL(final_readonly_start) - rommax;
 
     PICMask = pic_irqmask_read();
     __csm_return(regs);
diff --git a/src/fw/shadow.c b/src/fw/shadow.c
index 936ae28..ee87d36 100644
--- a/src/fw/shadow.c
+++ b/src/fw/shadow.c
@@ -53,9 +53,8 @@ __make_bios_writable_intel(u16 bdf, u32 pam0)
         return;
 
     // Copy bios.
-    extern u8 code32flat_start[], code32flat_end[];
-    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
-           , code32flat_end - code32flat_start);
+    memcpy(VSYMBOL(code32flat_start), VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET
+           , SYMBOL(code32flat_end) - SYMBOL(code32flat_start));
 }
 
 static void
@@ -165,7 +164,6 @@ qemu_prep_reset(void)
     // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
     // reset, so do that manually before invoking a hard reset.
     make_bios_writable();
-    extern u8 code32flat_start[], code32flat_end[];
-    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
-           , code32flat_end - code32flat_start);
+    memcpy(VSYMBOL(code32flat_start), VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET
+           , SYMBOL(code32flat_end) - SYMBOL(code32flat_start));
 }
diff --git a/src/malloc.c b/src/malloc.c
index 106c7ea..5113bb6 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -366,8 +366,7 @@ rom_get_max(void)
     if (CONFIG_MALLOC_UPPERMEMORY)
         return ALIGN_DOWN(RomBase->range_end - OPROM_HEADER_RESERVE
                           , OPTION_ROM_ALIGN);
-    extern u8 final_readonly_start[];
-    return (u32)final_readonly_start;
+    return SYMBOL(final_readonly_start);
 }
 
 // Return the end of the last deployed option rom.
@@ -385,8 +384,8 @@ rom_reserve(u32 size)
     if (newend > rom_get_max())
         return NULL;
     if (CONFIG_MALLOC_UPPERMEMORY) {
-        if (newend < (u32)zonelow_base)
-            newend = (u32)zonelow_base;
+        if (newend < SYMBOL(zonelow_base))
+            newend = SYMBOL(zonelow_base);
         RomBase->range_start = newend + OPROM_HEADER_RESERVE;
     }
     return (void*)RomEnd;
@@ -504,21 +503,21 @@ malloc_init(void)
     }
 
     // Initialize low-memory region
-    extern u8 varlow_start[], varlow_end[], final_varlow_start[];
-    memmove(final_varlow_start, varlow_start, varlow_end - varlow_start);
+    memmove(VSYMBOL(final_varlow_start), VSYMBOL(varlow_start)
+            , SYMBOL(varlow_end) - SYMBOL(varlow_start));
     if (CONFIG_MALLOC_UPPERMEMORY) {
-        alloc_add(&ZoneLow, (u32)zonelow_base + OPROM_HEADER_RESERVE
-                  , (u32)final_varlow_start);
+        alloc_add(&ZoneLow, SYMBOL(zonelow_base) + OPROM_HEADER_RESERVE
+                  , SYMBOL(final_varlow_start));
         RomBase = alloc_find_lowest(&ZoneLow);
     } else {
-        alloc_add(&ZoneLow, ALIGN_DOWN((u32)final_varlow_start, 1024)
-                  , (u32)final_varlow_start);
+        alloc_add(&ZoneLow, ALIGN_DOWN(SYMBOL(final_varlow_start), 1024)
+                  , SYMBOL(final_varlow_start));
     }
 
     // Add space available in f-segment to ZoneFSeg
-    extern u8 zonefseg_start[], zonefseg_end[];
-    memset(zonefseg_start, 0, zonefseg_end - zonefseg_start);
-    alloc_add(&ZoneFSeg, (u32)zonefseg_start, (u32)zonefseg_end);
+    memset(VSYMBOL(zonefseg_start), 0
+           , SYMBOL(zonefseg_end) - SYMBOL(zonefseg_start));
+    alloc_add(&ZoneFSeg, SYMBOL(zonefseg_start), SYMBOL(zonefseg_end));
 
     calcRamSize();
 }
diff --git a/src/memmap.h b/src/memmap.h
index 092e2ad..22bd4bc 100644
--- a/src/memmap.h
+++ b/src/memmap.h
@@ -14,4 +14,8 @@ static inline void *memremap(u32 addr, u32 len) {
     return (void*)addr;
 }
 
+// Return the value of a linker script symbol (see scripts/layoutrom.py)
+#define SYMBOL(SYM) ({ extern char SYM; (u32)&SYM; })
+#define VSYMBOL(SYM) ((void*)SYMBOL(SYM))
+
 #endif // memmap.h
diff --git a/src/post.c b/src/post.c
index 89e6eff..49c22b8 100644
--- a/src/post.c
+++ b/src/post.c
@@ -25,6 +25,7 @@
 #include "hw/virtio-blk.h" // virtio_blk_setup
 #include "hw/virtio-scsi.h" // virtio_scsi_setup
 #include "malloc.h" // malloc_init
+#include "memmap.h" // SYMBOL
 #include "output.h" // dprintf
 #include "string.h" // memset
 #include "util.h" // kbd_init
@@ -89,9 +90,8 @@ bda_init(void)
 
     int esize = EBDA_SIZE_START;
     u16 ebda_seg = EBDA_SEGMENT_START;
-    extern u8 final_varlow_start[];
     if (!CONFIG_MALLOC_UPPERMEMORY)
-        ebda_seg = FLATPTR_TO_SEG(ALIGN_DOWN((u32)final_varlow_start, 1024)
+        ebda_seg = FLATPTR_TO_SEG(ALIGN_DOWN(SYMBOL(final_varlow_start), 1024)
                                   - EBDA_SIZE_START*1024);
     SET_BDA(ebda_seg, ebda_seg);
 
@@ -105,7 +105,7 @@ bda_init(void)
     e820_add((u32)ebda, BUILD_LOWRAM_END-(u32)ebda, E820_RESERVED);
 
     // Init extra stack
-    StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - zonelow_base);
+    StackPos = &ExtraStack[BUILD_EXTRA_STACK_SIZE] - SYMBOL(zonelow_base);
 }
 
 void
@@ -276,30 +276,27 @@ reloc_preinit(void *f, void *arg)
     void (*func)(void *) __noreturn = f;
     if (!CONFIG_RELOCATE_INIT)
         func(arg);
-    // Symbols populated by the build.
-    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[];
 
     // Allocate space for init code.
-    u32 initsize = code32init_end - code32init_start;
-    u32 codealign = (u32)&_reloc_min_align;
+    u32 initsize = SYMBOL(code32init_end) - SYMBOL(code32init_start);
+    u32 codealign = SYMBOL(_reloc_min_align);
     void *codedest = memalign_tmp(codealign, initsize);
+    void *codesrc = VSYMBOL(code32init_start);
     if (!codedest)
         panic("No space for init relocation.\n");
 
     // Copy code and update relocs (init absolute, init relative, and runtime)
     dprintf(1, "Relocating init from %p to %p (size %d)\n"
-            , code32init_start, codedest, initsize);
-    s32 delta = codedest - (void*)code32init_start;
-    memcpy(codedest, code32init_start, initsize);
-    updateRelocs(codedest, _reloc_abs_start, _reloc_abs_end, delta);
-    updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta);
-    updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
-    if (f >= (void*)code32init_start && f < (void*)code32init_end)
+            , codesrc, codedest, initsize);
+    s32 delta = codedest - codesrc;
+    memcpy(codedest, codesrc, initsize);
+    updateRelocs(codedest, VSYMBOL(_reloc_abs_start), VSYMBOL(_reloc_abs_end)
+                 , delta);
+    updateRelocs(codedest, VSYMBOL(_reloc_rel_start), VSYMBOL(_reloc_rel_end)
+                 , -delta);
+    updateRelocs(VSYMBOL(code32flat_start), VSYMBOL(_reloc_init_start)
+                 , VSYMBOL(_reloc_init_end), delta);
+    if (f >= codesrc && f < VSYMBOL(code32init_end))
         func = f + delta;
 
     // Call function in relocated code.
-- 
2.4.3




More information about the SeaBIOS mailing list