首页 文章

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

提问于
浏览
0

我正在努力实现与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

经过多次阅读后,我想我应该使用 ld-R 标志来实现这一目标 .

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

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

1 回答

  • 1

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

相关问题