Wednesday, January 19, 2011

Using LD, the GNU Linker, to create a relocatable section of code or data

Relocatable sections are used when you cant load a section of code/data directly where you want. This may be for many reasons for example the memory where the code is supposed to go needs to be initialized first as is the case in ROM images.

For a relocatable section you need two addresses:
1. Relocation Address
2. Load Address

Relocation Address is the address for which the section is linked. Whereas Load Address is the address where the section will get loaded. Confusing? Lets try an example:

Consider an embedded system with 64MB ROM memory mapped at address 0x1E000000 and 256 MB DRAM mapped at 0x00000000. Your code will reside in ROM but when the system starts, it will copy it self from ROM into DRAM and continue execution from there.

To create a relocatable section we use AT keyword in section definition as follows
section_name startaddr : AT( loadaddr)
{
    /*section contents*/
    ...
}
 This will create a section which is linked for address startaddr but which is loaded in memory at loadaddr. Going back to above example embedded system, you will need at least two sections, one will contain the actual code and the other will contain the relocation/copying logic. This is required because the code for copying will get executed from ROM, so it needs to be linked for that address. So the GNU ld script will look something like following:

.init 0x1E000000 :
{
    *(.init)
}
.text 0x00000000 : AT ( ADDR(.init) + SIZEOF(.init) )
{
    *(.text)
}
the expression ADDR(.init) + SIZEOF(.init) will give us the address of first byte just after .init section. So .text section will get loaded just after the .init section. Upon reset, the code in .init section will copy the text section to DRAM i.e address 0x00000000 and pass control to it.

No comments: