Some linking questions

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm
Contact:

Some linking questions

Post by Jamie »

I'm linking together several object files into an executable, which may contain their own constant and data sections. These sections are grouped together contiguously in memory by the linker, but I'm just wondering:

- Is there any way that one particular constant section can always be located at the start of the constant pool (i.e. at _cp)? This is so I can use BLACP.
- And, is there any way that you can calculate the extent of the data region? So for example to be able to use this top area of memory at run time.

Also, when linking with -nostlib there are still a whole load of functions included in the final executable such as getAllChannels, freeAllChannels, skipFree, programScratch, waitForScratchTop. Are these necessary? Are they used in the initialisation/boot process?


m_y
Experienced Member
Posts: 69
Joined: Mon May 17, 2010 10:19 am

Post by m_y »

Jamie wrote: - Is there any way that one particular constant section can always be located at the start of the constant pool (i.e. at _cp)? This is so I can use BLACP.
There's no general mechanism. In practice object files are placed in the order they're encounted on the command line but the linker doesn't guarantee this so it's not impossible it would stop working in a furture tools release (but this is unlikely).

There's a --first option to xmap which places an object file before other object files. This is normally used to ensure that _start ends up at the start of memory but you can use it to promote your own object files. The relative ordering of all object files specified with --first is subject to the same not-guaranteed ordering as normal object files.
Jamie wrote: - And, is there any way that you can calculate the extent of the data region? So for example to be able to use this top area of memory at run time.
The data region runs between then end of the text and the start of the bss section. The bss section ends at "_edp.bss". The space between the end of bss and the bottom of the stack is used as the heap (if you use it). If you do use this area yourself then make sure you steer clear of malloc/free and friends.
Jamie wrote:Also, when linking with -nostlib there are still a whole load of functions included in the final executable such as getAllChannels, freeAllChannels, skipFree, programScratch, waitForScratchTop. Are these necessary? Are they used in the initialisation/boot process?
That's the start up, sanitation and synchronisation code (so yes, they're part of initialisation/boot). They're necessary if you want to use the standard runtime environment and provide some immunity against vagaries of the boot mode. If you're implementing everything yourself you can cause them to be omitted by passing "--nochaninit" to the linker.
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm
Contact:

Post by Jamie »

That's the start up, sanitation and synchronisation code (so yes, they're part of initialisation/boot). They're necessary if you want to use the standard runtime environment and provide some immunity against vagaries of the boot mode. If you're implementing everything yourself you can cause them to be omitted by passing "--nochaninit" to the linker.
Okay, but I'm still not sure what you mean by the startup and initialisation code. As far as I understand there are two levels of initialisation. With a single chip, such as the XC-1 board, there is initialisation of memory, threads, channels etc. as part of the runtime, (which I guess is primarily designed to support XC). On multi-chip boards, such as the XMP-64, the system is initialised with a seperate binary that is loaded and executed before the main program one is, and so before the runtime initialisation. This seems to boot the cores and initialise the routing and is still included when --nochaninit is passed to the linker.

You warned me before that it would be best to avoid using --nochaninit, which is probably the best thing to do, but I'm just curious about what's actually going on during the initialisation.
m_y
Experienced Member
Posts: 69
Joined: Mon May 17, 2010 10:19 am

Post by m_y »

You've got it pretty much right.

There are essentially three parts to the boot:

1: Network bringup. The gets the system into a state where each node has the correct node id, xlinks and routing tables are set up and thus a message from one node is correctly to its destination. The correct application binaries are loaded onto each core.

2: C/XC runtime startup. The canonical CRT stuff: constructors, bss initialisation, etc etc.

3: Synchronisation. Channels, possibly over xlinks, are used to ensure that all nodes and cores are ready and are all in a known state. Some additional cleanup is performed. The top-level channel ends are allocated and the values communicated between cores. On each core the correct top-level functions are called.


Part 2 can be removed with the "--nostdlib" flag.

Part 3 (minus the code needed to arrange for the right threads to run on the right cores) can be removed by passing "--nochaninit" to the linker.

Part 1 is generated as a separate program which is included in the XE. When booting over JTAG the debugger arranges for this program to be run prior to the actual application and the loading is done directly by the debugger. When booting from flash (using xflash) the automatically generated second stage loader performs the tasks from part 1 (including loading).

There isn't a flag to turn off generation of part 1 however xobjdump can be used to separately extract part 1 from the rest.
Post Reply