实现一个类似 module_init 的 Linux 内核,但是在 ld 脚本中遇到了一些麻烦
Implement a similar module_init as Linux kernel, but meet some trouble in ld script
我非常喜欢 linux 内核 module_init 功能,我想为我的用户 space 应用程序实现相同的功能。
我尝试修改链接器脚本来执行此操作:
1、复制一个x86-64标准的ld脚本
2、添加我的自定义栏目
.module.init :
{
PROVIDE_HIDDEN (__module_init_start = .);
*(.module_init*)
PROVIDE_HIDDEN (__module_init_end = .);
}
3、将init函数指针放入moudle_init段
#define app_module_init(x) __initcall(x);
#define __initcall(fn) \
static initcall_t __initcall_##fn \
__attribute__ ((__section__(".module_init"))) = fn
app_module_init(unit_test_1_init);
app_module_init(unit_test_2_init);
app_module_init(unit_test_3_init);
app_module_init(unit_test_4_init);
4、使用自定义链接描述文件(基于标准链接描述文件)编译应用程序
gcc -o "./module_init" -T module.lds ./module_init.o
5,然后我objdump moudle_init,我发现生成的部分是:
Disassembly of section .module_init:
0000000000a01080 <__initcall_unit_test_1_init>:
a01080: ad lods %ds:(%rsi),%eax
a01081: 05 40 00 00 00 add [=15=]x40,%eax
...
0000000000a01088 <__initcall_unit_test_2_init>:
a01088: c2 05 40 retq [=15=]x4005
a0108b: 00 00 add %al,(%rax)
a0108d: 00 00 add %al,(%rax)
...
0000000000a01090 <__initcall_unit_test_3_init>:
a01090: d7 xlat %ds:(%rbx)
a01091: 05 40 00 00 00 add [=15=]x40,%eax
...
0000000000a01098 <__initcall_unit_test_4_init>:
a01098: ec in (%dx),%al
a01099: 05 40 00 00 00 add [=15=]x40,%eax
但是 __module_init_start 和 __module_init_end 变量不是我期望的值。在我的例子中,__module_init_start 是 0x4005ad,__module_init_end 是 0x400000003。
这很奇怪,因为0x4005ad是__initcall_unit_test_1_init.
的地址
谁能告诉我如何让这个用户 space module_init 工作?
链接描述文件只能设置变量的地址。使用 &__module_init_start
获取指向节开头的指针,使用 &__module_init_end
获取指向结尾的指针。
我非常喜欢 linux 内核 module_init 功能,我想为我的用户 space 应用程序实现相同的功能。
我尝试修改链接器脚本来执行此操作:
1、复制一个x86-64标准的ld脚本
2、添加我的自定义栏目
.module.init :
{
PROVIDE_HIDDEN (__module_init_start = .);
*(.module_init*)
PROVIDE_HIDDEN (__module_init_end = .);
}
3、将init函数指针放入moudle_init段
#define app_module_init(x) __initcall(x);
#define __initcall(fn) \
static initcall_t __initcall_##fn \
__attribute__ ((__section__(".module_init"))) = fn
app_module_init(unit_test_1_init);
app_module_init(unit_test_2_init);
app_module_init(unit_test_3_init);
app_module_init(unit_test_4_init);
4、使用自定义链接描述文件(基于标准链接描述文件)编译应用程序
gcc -o "./module_init" -T module.lds ./module_init.o
5,然后我objdump moudle_init,我发现生成的部分是:
Disassembly of section .module_init:
0000000000a01080 <__initcall_unit_test_1_init>:
a01080: ad lods %ds:(%rsi),%eax
a01081: 05 40 00 00 00 add [=15=]x40,%eax
...
0000000000a01088 <__initcall_unit_test_2_init>:
a01088: c2 05 40 retq [=15=]x4005
a0108b: 00 00 add %al,(%rax)
a0108d: 00 00 add %al,(%rax)
...
0000000000a01090 <__initcall_unit_test_3_init>:
a01090: d7 xlat %ds:(%rbx)
a01091: 05 40 00 00 00 add [=15=]x40,%eax
...
0000000000a01098 <__initcall_unit_test_4_init>:
a01098: ec in (%dx),%al
a01099: 05 40 00 00 00 add [=15=]x40,%eax
但是 __module_init_start 和 __module_init_end 变量不是我期望的值。在我的例子中,__module_init_start 是 0x4005ad,__module_init_end 是 0x400000003。 这很奇怪,因为0x4005ad是__initcall_unit_test_1_init.
的地址谁能告诉我如何让这个用户 space module_init 工作?
链接描述文件只能设置变量的地址。使用 &__module_init_start
获取指向节开头的指针,使用 &__module_init_end
获取指向结尾的指针。