【发布时间】:2018-04-10 08:32:16
【问题描述】:
我正在尝试实现与this quesition 类似的目标。我正在编译一个用C编写的固件文件,代码需要调用bootloader中的一个函数。
我的固件文件如下所示:
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
经过更多阅读,我认为我应该使用ld 的-R 标志来完成此操作。
从文件名中读取符号名称及其地址,但不要重新定位它或将其包含在输出中。这允许您的输出文件以符号方式引用其他程序中定义的内存的绝对位置。您可以多次使用此选项。
只是还没有让它工作得很好。
【问题讨论】:
-
我从来没有完全按照我想要的方式完成这项工作。但我会在未来的某个时候回到它......
标签: gcc ld bootloader firmware