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