memmap: Introduce SYMBOL() macro to access linker script symbols

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@koconnor.net>
This commit is contained in:
Kevin O'Connor 2015-10-08 11:18:17 -04:00
parent fe6682da0b
commit 5d91226e89
7 changed files with 47 additions and 49 deletions

View File

@ -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)

View File

@ -6,14 +6,15 @@
#include "byteorder.h" // le32_to_cpu
#include "config.h" // CONFIG_*
#include "malloc.h" // malloc_fseg
#include "output.h" // dprintf
#include "hw/pci.h" // pci_config_writeb
#include "malloc.h" // malloc_fseg
#include "memmap.h" // SYMBOL
#include "output.h" // dprintf
#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)

View File

@ -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);

View File

@ -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));
}

View File

@ -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();
}

View File

@ -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

View File

@ -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.