我希望能够声明函数,以便将它们添加到特定的代码部分,然后它们都在我的启动函数之前执行。像这样:
void __attribute__((__section__(".driverinit"))) disk_driver_init() {
dev_register(&diskDevice);
}
目的是将它们中的每一个都添加到一个数组中,以便可以处理其中包含的函数。我知道我可以在全局范围内添加这些功能,但我会尽可能避免这种情况。
问题是,一旦第一个函数返回,我就不知道如何转到集合中的下一个函数。或者可能有函数在最后不生成“ret”并失败。不确定这是否可能。
这是反汇编,我希望它运行代码部分中的每个函数,然后如果可能的话跳转到末尾的 _start...
Disassembly of section .driverinit:
0000000000000000 <disk_driver_init>:
0: a9bf7bfd stp x29, x30, [sp, #-16]!
4: 910003fd mov x29, sp
8: d0000040 adrp x0, a000 <FLAG_APP_CMD+0x138>
c: 9128e000 add x0, x0, #0xa38
10: 9400020f bl 84c <dev_register>
14: d503201f nop
18: a8c17bfd ldp x29, x30, [sp], #16
1c: d65f03c0 ret
20: 14000002 b 28 <_start>
24: d65f03c0 ret
Disassembly of section .text.boot:
0000000000000028 <_start>:
28: d53800a0 mrs x0, mpidr_el1
2c: 92401c00 and x0, x0, #0xff
30: b4000040 cbz x0, 38 <startup_proc>
有人可以引导我朝着正确的方向前进吗?
最佳答案
不是将函数本身放在一个特殊的部分,而是将指针放在这个特殊部分中的函数:
void disk_driver_init() {
dev_register(&diskDevice);
}
void __attribute__((section(".driverinit")))(* const disk_driver_init_ptr)() = disk_driver_init;
您需要一些东西来标记该部分的结尾,因此将其单独放在一个文件中,并将其作为您链接的最后一个目标文件:
void __attribute__((section(".driverinit")))(* const driverinit_end)() = 0;
然后你可以像这样调用所有的驱动初始化函数:
void __attribute__((section(".driverinit")))(* const driverinit_start)() = 0;
void
call_driver_init_fns(void) {
void (* const *fn)() = &driverinit_start + 1;
while (fn != &driverinit_end) {
(*fn)();
fn++;
}
}
请注意,此目标文件需要位于第一个,或者至少在链接时将函数指针放入 .driverinit
的任何其他目标文件之前。
这基本上就是 C++ 构造函数的工作方式。您可以通过使用为 .driverinit
的开始和结束提供符号的自定义链接器脚本来避免浪费空间 _start
和 _end
变量部分。还有 GCC constructor attribute ,但如果您没有使用标准运行时(我猜您没有),您将不得不弄清楚它在您的平台上的工作方式并自己实现启动代码。
关于c - 如何在代码段中运行每个 "function"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63199378/