从固件链接到引导加载程序回调函数

时间:2018-04-10 08:32:17

标签: gcc ld bootloader firmware

我试图获得与this quesition类似的内容。我正在编译用C编写的固件文件,代码需要在引导程序中调用一个函数。

我的固件文件如下所示:

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

使用gcc firmware.c编译固件函数时没有错误,但函数体只包含两条​​nop指令,它们之间没有任何内容(这是有意义的,函数未定义)。

我创建了一个运行引导加载程序的脚本并打印出地址&callback,我可以在固件中使用它来定义main()中的函数指针:

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

这使回调工作,但我不想运行引导程序来编译固件。

我尝试使用链接器脚本摸索,但我是那些新手。

我尝试提供

PROVIDE(callback = 0x0000000000000969);

PROVIDE(callback = 0x555555554abd);

通过编译固件来链接到链接器:

gcc -Xlinker -T linkerscript firmware.c

第一个地址来自nm firmware.out | grep callback,另一个来自运行gdb中的引导加载程序。使用链接描述文件进行编译会出现此错误:

/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

经过多次阅读后,我想我应该使用-R的{​​{1}}标志来完成此任务。

  

从文件名中读取符号名称及其地址,但不要将其重新定位或将其包含在输出中。这允许您的输出文件以符号方式引用其他程序中定义的内存的绝对位置。您可以多次使用此选项。

只是还没有让它正常工作。

1 个答案:

答案 0 :(得分:1)

使用--no-dynamic-linker链接选项,done by U-Boot to solve this issue。请注意,如果您通过gcc调用链接器,则必须使用-Wl,--no-dynamic-linker设置该选项。