[U-Boot] Quick linker script questions - Assigning Values to Symbols outside the script

Hi All,
I'm messing around with consolidating the linker scripts for x86 so I have a common platform script in the arch directory. x86 uses some fancy offset calculations to place the Reset Vector and Reset Handler code at the end of the Boot ROM. Currently this is done on a per-board basis.
Currently I have in the linker script:
. = 0xfffffe00; .start32 : AT (TEXT_BASE + 0x3fe00) { KEEP(*(.start32)); }
. = 0xf800; .start16 : AT (TEXT_BASE + 0x3f800) { KEEP(*(.start16)); }
. = 0xfff0; .resetvec : AT (TEXT_BASE + 0x3fff0) { KEEP(*(.resetvec)); }
I want to replace this with:
FLASH_SIZE = 0x40000; START_32 = 0xfe00; START_16 = 0xf800; RESET_SEG_START = 0xffff0000; RESET_SEG_SIZE = 0x10000; RESET_VEC_LOC = 0xfff0;
. = RESET_SEG_START + START_32; .start32 : AT (TEXT_BASE + (FLASH_SIZE - RESET_SEG_SIZE + START_32)) {KEEP(*(.start32)); }
. = START_16; .start16 : AT (TEXT_BASE + (FLASH_SIZE - RESET_SEG_SIZE + START_16)) {KEEP(*(.start16)); }
. = RESET_VEC_LOC; .resetvec : AT (TEXT_BASE + (FLASH_SIZE - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); }
Now that looks far more complicated, but it allows the Boot ROM size to be defined without having to calculate, by hand, where these sections need to be placed. It also allows the location of (and therefore the size allocated to) the 16-bit and 32-bit boot-strap code (which always runs from the Boot ROM) to be adjusted to maximise that amount of space for the main U-Boot binary.
FLASH_SIZE, START_32, and START_16 are really the only board specific definitions (and even then, for the majority of use-cases only FLASH_SIZE would need adjusting). So I would like to move the bulk of the linker script to $(SRCTREE)/arch/x86/cpu/u-boot.lds and have these three defined in something like $(SRCTREE)/board/$(BOARDDIR)/board_defs.lds
But things are not working the way I want them to. The following works...
$(SRCTREE)/board/$(BOARDDIR)/board_defs.lds FLASH_SIZE = 0x40000; START_32 = 0xfa00; START_16 = 0xff00;
$(SRCTREE)/arch/x86/cpu/u-boot.lds RESET_SEG_START = 0xffff0000; RESET_SEG_SIZE = 0x10000; RESET_VEC_LOC = 0xfff0;
INCLUDE /home/graeme/Source/U-Boot/x86/board/eNET/board_defs.lds SECTIONS { . = TEXT_BASE; /* Location of bootcode in flash */ _i386boot_text_start = .; .text : { *(.text); } etc...
But the following will not...
$(SRCTREE)/board/$(BOARDDIR)/board_defs.lds FLASH_SIZE = 0x40000; START_32 = 0xfa00; START_16 = 0xff00;
$(SRCTREE)/board/$(BOARDDIR)/config.mk PLATFORM_LIBS += -L $(SRCTREE)/board/$(BOARDDIR)
$(SRCTREE)/arch/x86/cpu/u-boot.lds RESET_SEG_START = 0xffff0000; RESET_SEG_SIZE = 0x10000; RESET_VEC_LOC = 0xfff0;
INCLUDE board_defs.lds SECTIONS { . = TEXT_BASE; /* Location of bootcode in flash */ _i386boot_text_start = .; .text : { *(.text); } etc...
From the binutils documentation:
INCLUDE filename Include the linker script filename at this point. The file will be searched for in the current directory, and in any directory specified with the -L option. You can nest calls to INCLUDE up to 10 levels deep.
and the additional PLATFORM_LIBS does add -L /home/graeme/Source/U-Boot/x86/board/eNET to the link command. I even tried PLATFORM_LDFLAGS += -L $(SRCTREE)/board/$(BOARDDIR) which changes the location of the addition -L in the link command with no luck.
Back to binutils documentation:
-T scriptfile --script=scriptfile Use scriptfile as the linker script. This script replaces ld's default linker script (rather than adding to it), so commandfile must specify everything necessary to describe the output file. See Scripts. If scriptfile does not exist in the current directory, ld looks for it in the directories specified by any preceding `-L' options. Multiple `-T' options accumulate.
Note the last sentence "Multiple `-T' options accumulate."
Now if I change $(SRCTREE)/config.mk slightly at around line 205 to add an Implicit Linker Script...
AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS) LDFLAGS += -T $(SRCTREE)/board/$(BOARDDIR)/board_defs.lds LDFLAGS += -Bstatic -T $(obj)u-boot.lds $(PLATFORM_LDFLAGS) ifneq ($(TEXT_BASE),) LDFLAGS += -Ttext $(TEXT_BASE) endif
Everything works perfectly fine. But this is a horrible hack. Alas, there is no mechanism right now to add ld flags before the ones explicitly defined in config.mk.
Unless I can find out why -L is not working, I'm thinking of adding a new $(PLATFORM_PRE_LDFLAGS) and changing $(SRCTREE)/config.mk to:
LDFLAGS += $(PLATFORM_PRE_LDFLAGS) -Bstatic -T $(obj)u-boot.lds $(PLATFORM_LDFLAGS)
I could also but some hacks into the $(BOARD)_config in the Makefile to patch the linker script but I think that is a bad idea.
Or maybe there is an easier way?
Anyone have any thoughts on this?
Regards,
Graeme
participants (1)
-
Graeme Russ