jarmokivekas
jarmokivekas

Reputation: 187

Linking to a bootloader callback function from firmware

I'm trying to achieve something similar as in this quesition. I'm compiling a firmware file written in C, and the code needs to call a function in the bootloader.

My firmware file looks like this:

void callback(void); 
int main(void){
    __asm__("nop; ");
    callback(); 
    __asm__("nop; ");
    return(0)
}

The firmware function compiles without error using gcc firmware.c but the function body only contains the two nop instruction with nothing in-between them (which makes sense, the function is undefined).

I made a script that runs the bootloader and prints out the address &callback, which i can use in the firmware to define a function pointer in my main():

void (*call_this)(void) = (void (*)(void )) 0x555555554abd;
call_this();

That makes the callback work, but I don't want to have to run the bootloader to compile the firmware.


I've tried fumbling around with linker scripts, but I'm new to those.

I tried supplying

PROVIDE(callback = 0x0000000000000969);

or

PROVIDE(callback = 0x555555554abd);

to the linker by compiling the firmware with:

gcc -Xlinker -T linkerscript firmware.c

The first address is from nm firmware.out | grep callback, the other from running the bootloader in gdb. Compiling with the linker script gives this error:

/usr/bin/ld: firmware.out: Not enough room for program headers, try linking with -N
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

After some more reading, I think I should to use the -R flag of ld to accomplish this.

Read symbol names and their addresses from filename, but do not relocate it or include it in the output. This allows your output file to refer symbolically to absolute locations of memory defined in other programs. You may use this option more than once.

Just haven't made it work quite right yet.

Upvotes: 0

Views: 321

Answers (1)

Claudio
Claudio

Reputation: 10947

Use the --no-dynamic-linker linking option, as done by U-Boot to solve this issue. Note that if you invoke the linker trough gcc the option must be set using -Wl,--no-dynamic-linker.

Upvotes: 1

Related Questions