Place a function at very start of binary - c

I'm working on a toy operating system and bootloader. I'm trying to write the kernel in C, and then convert it to binary for direct jumping to from the bootloader (i.e., I'm not loading an ELF or anything like that).
I've got the linker file setup with the proper origin (I'm loading the kernel to address 0xC0000000) and confirm with objdump that it's using it correctly. However, it's not placing my entry point at the start (0xC0000000) like I wanted. I guess that's not what the ENTRY directive is for.
My problem is simply that I want to place a particular function, kernel_main at address 0xC0000000. Is there a way I can accomplish this using gcc for compiling and linking?
Here is what the relevant parts of my linker file look like:
ENTRY(kernel_main)
SECTIONS
{
/* Origin */
. = 0xC0000000;
.text BLOCK(4K) : ALIGN(4K)
{
*(.text)
}
/* etc. */
}

The ENTRY linker command tells the linker which symbol the loader should jump to when it loads the program. If you're making your own operating system it's really not used since there is no loader.
Instead, as you know, the program simply starts at the first code address.
To make place a special segment of code first, you could place it in a special code segment, and put it first in the list:
.text BLOCK(4K) : ALIGN(4K)
{
*(.text.boot) *(.text)
}
The segments in the list is placed in the order they are given.

The ENTRY directive is only useful for output formats that support an entrypoint. Since you're using a binary output, this won't work. What you can do is write a small stub in a separate source file (i.e. entry.c or entry.asm or whatever). Then, in the ld script, before the *(.text) line, you can put entry.o(.text). This instructs ld to load the symbols from a specific object file (whereas * denotes all object files). So the new ld script would look like this:
ENTRY(kernel_main)
SECTIONS
{
/* Origin */
. = 0xC0000000;
.text BLOCK(4K) : ALIGN(4K)
{
entry.o(.text)
*(.text)
}
/* etc. */
}
As long as entry.o contains just one function (that simply calls your kernel main), this should work.

Related

How to link a static library to its own section [duplicate]

My application calls some functions which are placed in an external static library. I link the external static library to my application and everything works (in this case I'm using GCC).
Nevertheless, the locations (addresses) of text, .data and .bss sections of the library are chosen by the linker. I can choose/change their locations by modifying the linker script, but it's tedious as I have to specify all the functions, variables, etc. of the library. What I mean it's something like:
. = 0x1000; /* new location */
KEEP(*(.text.library_function1));
KEEP(*(.text.library_function2));
[...]
An alternative solution is to build the external library by placing a section attribute for each function/variable, and then modifying the linker by re-locating the whole section. Something like:
/* C source file */
unsigned char __attribute__((section (".myLibrarySection"))) variable1[10];
unsigned char __attribute__((section (".myLibrarySection"))) variable2[10];
/* Linker script */
. = 0x1000;
KEEP(*(.myLibrarySection))
However, I'd like to be able to relocate entire .text, .data and .bss segments of an external static library without the need of using these tricks.
I'd like something like this (in linker script):
. = 0x1000;
KEEP(*(.text.library_file_name))
Is it possible using GCC toolchain?
Is it possible using other toolchains (IAR, Keil, etc.)?
You can use the archive:filename syntax in ld.
First place all the .o files from your external library into a static library .a file, if they aren't already. That is the normal way static library binaries are distributed.
Then in the linker script, specify:
.text.special : {
. = 0x1000;
*libspecial.a:*(.text .text.*)
}
.text {
*(.text .text.*)
}
The wildcard will pick all the files coming from libspecial.a and place them in the first section. The later wildcard will then pick anything left over. If there is a need to place the .text.special section after the normal section, you can use EXCLUDE_FILE directive in a similar way.
Can you just postprocess your lib to rename sections?
# Untested!
TMP=`mktemp -d`
trap "rm -rf $TMP" EXIT
cd $TMP
ar x path/to/your/lib.a
for o in *.o; do
for s in text data bss; do
objcopy --rename-section .$s=.mynew$s $o
done
done
ar rcs path/to/your/lib.a *.o

Is it possible to auto split the .text section across mulitple memory areas?

I am currently writting a embedded program for a microcontroller with a splitted flash region. Something like
MEMORY {
flash1 : ORIGIN = 0x1000, LENGTH = 0x1000
/* 1K gap */
flash2 : ORIGIN = 0x3000, LENGTH = 0x1000
}
My application has grown to a point where the ".text" section is larger than the area of flash1.
Is it possible to automatically split the text section accross the two areas?
Something like:
SECTIONS {
.text0 : { *(.text) } > flash1
.text1 : { *(.text) } > flash2
}
If I am doing something like the one above. I get a error message telling me that
ld: a.out section `.text' will not fit in region `flash1'
ld: region `flash1' overflowed by 240 bytes
I know I could do something like:
SECTIONS {
.text0 : { mylargefile (.text) } > flash1
.text1 : { *(.text) } > flash2
}
but I don't have a single large file. So the question is is it possible to tell the linker to fill the first output section until the it is full and afterwards continue with the next section?
Further information:
I do not provide a full example as my actually application is much more complex as I am although using LMA and VMA section and special section for some special files. But this answer should provide me enough help to continue or ask further questions.
I am looking forward for answers. I hope my question is clear enough without a full sample
EDIT1:
The solution of the question Splitting embedded program in multiple parts in memory is not correct in my case as the solution uses wildcards to spilt the files manually. I ask if there is a automatically solution. Otherwise I would be forced to manually adjust the linker file every time I do larger changes on the code base.
EDIT2:
Changed example to make sure there is a gap as remarked by Tom V
Well, some compilers allow in their linkers (and the scripts) to overflow to another section, if the first one is full.
But also these have sometimes problems, that it depends on the order of when the section is full and when it switches, it does not come back to fill the first one up, e.g. you have in the beginning or the middle a very big part. When the linker skips now to the next section due to overflow, the first was maybe just filled to the half. It does not use smaller parts AFTER that big part, to go back to the first sections to fill in.
So, it seems, the GNU LD, the Gold-linker and also the LLVM/CLANG linker (which state at their site, that the linker script is the same as GNU LD, and the exceptions page does not state anything), do not support to overflow into another section.
So, to make it easier, maybe some hints:
Filtering by filename patterns can get tedious over time. And, it does not allow you to filter by symbol, only by filename pattern and input section names.
If you have a approach like AUTOSAR MemMap, you could split the code by placing them into new sections with a different naming than default .text, .rodata, .data, .bss. (Unfortunately, GCC + CLANG went that extra way of using attribute(( )) instead of the #pragma or _Pragma() way of the C-standard). (AUTOSAR MemMap example at the end)
you could split into fast and slow code, e.g. introducing new sections like .codefast, .codeslow (e.g. ISR code as fast, task level code as "slow")
you could split into QM vs ASIL partitions introducing sections like .code_qm, .code_asila, .code_asilb
you could split code and config / const data , where the configuration is put into a separately flashable section, e.g. sections .text, .rodata could be split into .text, .const .postbuildconfig, .calib .. with a partial different coding style, you could here keep the code the same, but project config (e.g. CAN config, filter chains etc) could use a configurable config, where you just flash a new config, without updating the code itself
.text --> flash memory sector 1
.postbuildconfig --> flash memory sector 2
.calib --> flash memory sector 3
Before starting actually to really compile and link, maybe an inbetween build phase could use tools like objdump / nm / size / readelf to first scan over the .o files to give out the object / section sizes and summarize them by a script according to certain criterias e.g. input memory layout and by above special sections or by ordering by size and .o file name patterns, which you could use to update the linker script to adapt the memory definitions. SO, the script could try to fit until the gap as much as fits, then switches to the other memory. It could even try to generate the linker script parts which is later passed to the linker. You could write such a linker preprocess script in perl or python.
Together with the memory mapping to different sections, you could filter now like this:
MEMORY {
// Maybe you have two 128k areas separate by a gap
// Put the code in the first big part, and the more
// "configurable part" in the second area might even
// allow you to flash/update the separately
CODE1 : origin = 0x10000, len = 128k
// maybe here is a gap
CODE2 : origin = 0x10000, len = 64k
CONST : origin = 0x20000, len = 4k
CALIB : origin = 0x40000, len = 4k
POSTBUILD : origin = 0x50000, len = 48k
}
SECTIONS {
.code1 : {
*(.text) // default .text
*(.code_fast) // fast/slow code split
*(.code_qm) // qm/asil code split
} > CODE1
.code2 : {
*(.code_slow) // fast/slow code split
*(.code_asila) // qm/asil code split
*(.code_asilb) // qm/asil code split
} > CODE2
.const : {
*(.const)
*(.rodata)
} > CALIB
.calib : {
*(.calib)
*_calib.o(.calib) // in case you separate them also out into xxx_Calib.c files compiled to xxx_Calib.o files
} > CALIB
.postbuild : {
*(.postbuild)
*_PBCfg.o(.postbuild) // in case you separate them also out into xxx_PBCfg.c files compiled to xxx_PBCfg.o files
} > POSTBUILD
}
This approach allows you also to prepare the layout in a header, and generate that configs and calibs by certain external tools.
Additionally, it also allows a bit better to estimate your memory resource consumptions and therefore also, how and where to place/link them to the memory sections.
Here is an AUTOSAR MemMap usage example in code
#define XXX_START_SEC_CODE_FAST
#include "MemMap.h"
void XXX_Channel0_Notification(void) {
// Channel0 Finished Notification e.g. called from ISR
}
#define XXX_STOP_SEC_CODE_FAST
#include "MemMap.h"
The MemMap.h can configure this like:
#if defined(XXX_START_SEC_CODE_FAST)
#undef XXX_START_SEC_CODE_FAST
// open section .codefast
#pragma section code ".codefast"
#elif defined(XXX_START_SEC_CODE_SLOW)
#undef XXX_START_SEC_CODE_SLOW
// open section .codeslow
#pragma section code ".codeslow"
#endif
#if defined(XXX_STOP_SEC_CODE_FAST)
#undef XXX_STOP_SEC_CODE_FAST
// back to default section
#pragma section code
#elif defined(XXX_STOP_SEC_CODE_SLOW)
#undef XXX_STOP_SEC_CODE_SLOW
// back to default section
#pragma section code
#endif
The MemMap.h file could be generated, by scanning all the start/stop section defines, and generating the pragmas by a config tool (could be even Excel).
The advantage is, that you do not spill all the pragmas possible (e.g. different compilers <-> different dialects), or if to map or not to map. So you can actually reuse the code in different projects if possible.

Place segments of external static library to specific locations

My application calls some functions which are placed in an external static library. I link the external static library to my application and everything works (in this case I'm using GCC).
Nevertheless, the locations (addresses) of text, .data and .bss sections of the library are chosen by the linker. I can choose/change their locations by modifying the linker script, but it's tedious as I have to specify all the functions, variables, etc. of the library. What I mean it's something like:
. = 0x1000; /* new location */
KEEP(*(.text.library_function1));
KEEP(*(.text.library_function2));
[...]
An alternative solution is to build the external library by placing a section attribute for each function/variable, and then modifying the linker by re-locating the whole section. Something like:
/* C source file */
unsigned char __attribute__((section (".myLibrarySection"))) variable1[10];
unsigned char __attribute__((section (".myLibrarySection"))) variable2[10];
/* Linker script */
. = 0x1000;
KEEP(*(.myLibrarySection))
However, I'd like to be able to relocate entire .text, .data and .bss segments of an external static library without the need of using these tricks.
I'd like something like this (in linker script):
. = 0x1000;
KEEP(*(.text.library_file_name))
Is it possible using GCC toolchain?
Is it possible using other toolchains (IAR, Keil, etc.)?
You can use the archive:filename syntax in ld.
First place all the .o files from your external library into a static library .a file, if they aren't already. That is the normal way static library binaries are distributed.
Then in the linker script, specify:
.text.special : {
. = 0x1000;
*libspecial.a:*(.text .text.*)
}
.text {
*(.text .text.*)
}
The wildcard will pick all the files coming from libspecial.a and place them in the first section. The later wildcard will then pick anything left over. If there is a need to place the .text.special section after the normal section, you can use EXCLUDE_FILE directive in a similar way.
Can you just postprocess your lib to rename sections?
# Untested!
TMP=`mktemp -d`
trap "rm -rf $TMP" EXIT
cd $TMP
ar x path/to/your/lib.a
for o in *.o; do
for s in text data bss; do
objcopy --rename-section .$s=.mynew$s $o
done
done
ar rcs path/to/your/lib.a *.o

How do I specify manual relocation for GCC code?

I am in a situation in an embedded system (an xtensa processor) where I need to manually override a symbol, but the symbol happens to be in the middle of another symbol. When I try using -Wl,--wrap=symbol it won't work, since the symbol isn't its own thing.
What I need to do is specify (preferably in a GCC .S, though .c is okay) where the code will end up. Though the actual symbol will be located somewhere random by the compiler, I will be memcpying the code into the correct place.
40101388 <replacement_user_vect>:
40101388: 13d100 wsr.excsave1 a0
4010138b: 002020 esync
4010138e: 011fc5 call0 4010258c <_UserExceptionVector_1>
My problem is GCC creates the assembly with relative jumps assuming the code will be located where it is in flash, while the eventual location will be fixed in an interrupt vector. How do I tell GCC / GNU as "put the code wherever you feel like, but, trust me it will actually execute from {here}"
Though my code is at 0x40101388 (GCC decided) it will eventually reside and execute from 0x40100050. How do I trick GCC by telling it "put the code HERE" but pretend it's located "HERE"
EDIT: I was able to get around this, as it turns out, the function I needed to modify was held in the linker script, individually. I was able to just switch it out in the linker script. Though I still would love to know the answer, I now have a work-around.
In the linker script each output section has two associated addresses: VMA and LMA -- the address for which the code is linked and the address where the code will be loaded.
Put the code that needs to be relocated into separate section, add an output section to your linker script with desired VMA and LMA and put an input section matching the name of the code section inside it.
E.g. the following C code
void f(void) __attribute__((section(".relocatable1.text")))
{
...
}
extern char _relocatable1_lma[];
extern char _relocatable1_vma_start[];
extern char _relocatable1_vma_end[];
void relocatable1_copy(void)
{
memcpy(_relocatable1_vma_start, _relocatable1_lma,
_relocatable1_vma_end - _relocatable1_vma_start);
}
Together with the following piece of ld script, with VMA substituted with the desired target code location
SECTIONS {
...
.some_section : { ... }
.relocatable1 VMA : AT(LOADADDR(.some_section) + SIZEOF(.some_section)) {
_relocatable1_vma_start = . ;
*(.relocatable1.literal .relocatable1.text) ;
_relocatable1_vma_end = . ;
}
_relocatable1_lma = LOADADDR(.relocatable1) ;
...
}
should do what you want.

How to make duplicate sections in ELF file

I have a requirement where I need to create a duplicate/copy section of .data section.
I've tried creating a dummy section with same size of data section in linker script and copy the contents of data section to the dummy section in the init functions of my ELF image, but that doesn't suit my requirement, as I want the copy/duplicate section to be created along with final ELF image not during the execution of it.
Below is what I wanted in my linker script,
SECTIONS {
.data : { <data section contents> }
.dummydata : { <copy of .data section> }
}
Can anyone help to write the linker script to match above requirement?
I don't think this can be done with just ld and a linker script. Given this line from here:
If a file name matches more than one wildcard pattern, or if a file
name appears explicitly and is also matched by a wildcard pattern, the
linker will use the first match in the linker script.
It sounds like the linker script will only put the data (or anything) in one section.
However all hope is not lost. You can copy the section using objcopy and then add the section using objcopy again
objcopy -O binary --only-section=.data your-file temp.bin
objcopy --add-section .dummydata=temp.bin your-file
This will append the section to be the last section with a VMA/LMA of 0. You can then use objcopy to move the section to the desired location.
objcopy --change-section-address .dummydata=desired-address your-file
Of course if there is something already there that would be problematic. Luckily you can create a hole right after your first .data with something like:
data_start = .;
.data : { *(.data) }
data_end = .;
. += (data_end - data_start);
This should create a hole right after your first data, big enough to put another copy of data right after it. If this isn't exactly where you want it to be just add (data_end - data_start) where you want the hole.
Finally you can change the section flags, again with objcopy
objcopy --set-section-flags .dummydata=the-flags-you-want your-file
Not as clean as just duplicating something in the linker script but it should work.

Resources