Linking images at one address, but loading them at another.
Richard Earnshaw
rearnsha@arm.com
Thu Oct 25 10:27:00 GMT 2001
I have an ELF image (an OS kernel) that I want to link to run at address
0xa0110000. This address is virtual, and will only become valid when the
MMU on the processor is enabled. However, when I am loading the program
the MMU is disabled and the addresses at 0xa0110000 are invalid: the first
task of the image is to build the page tables for the MMU and re-position
the image for correct execution.
This sounds like the perfect task for a linker script; unfortunately, I
can't get it to work.
Problem number 1:
=================
I can get the text segment correctly located and loaded with
ENTRY(os_start)
PHDRS
{
headers PT_PHDR PHDRS ;
text PT_LOAD AT (0x10000) ;
...
}
SECTIONS
{
.lotext 0x10000 : { intmmu.o(.text) } :text
.text (0xa0110000 + SIZEOF (.lotext)) :
AT ( LOADADDR(.lotext) + SIZEOF ( .lotext ) )
{
*(.text)
*(.glue_7t) *(.glue_7)
} :text =0
...
}
This will link the text of the image such that most of it will run at
address 0xa0110000; but will be physically located at 0x10000 onwards (the
code in .lotext is the bootstrap code and contains the entry point
os_start).
However, this image contains symbols, if I try to strip the image (eg to
remove debug data):
arm-elf-strip -g -o os os.gdb
BFD: netbsd: warning: allocated section `.text' not in segment
and the image seems to be corrupted (at least, the loader I have refuses
to load it (though it will load os.gdb).
Problem number 2:
=================
While I can get the text segment to load at the correct address, there
appears to be no way to override the load-address of the data segment in a
meaningful way. Adding
SECTIONS
{
...
.data : AT ( LOADADDR(.text) + SIZEOF ( .text ) )
{
*(.data)
}
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
__bss_start__ = .;
.bss :
... etc
}
will link the data section correctly, but in the program header the
p_vaddr field (which is the one the loader uses for loading the image)
will be set to the virtual address of the data segment.
What I would like to do is to force the PHDR entry to the correct load
address, but there seems to be no way of doing this symbolically. Adding:
PHDRS
{
...
data PT_LOAD AT (LOADADDR(.text) + SIZEOF ( .text ) )
}
just gives me errors about forward references or other similar problems,
and I can't see any way of expressing an address in this field that isn't
an absolute number.
Is there some other way of setting the load address of a segment
symbolically?
R.
More information about the Binutils
mailing list