kallsyms 中不存在 init 函数
init function not present in kallsyms
我写了一个简单的hello world内核模块
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
static int __init test_hello_init(void)
{
printk(KERN_INFO"%s: In init\n", __func__);
return 0;
}
static void __exit test_hello_exit(void)
{
printk(KERN_INFO"%s: In exit\n", __func__);
}
module_init(test_hello_init);
module_exit(test_hello_exit);
加载模块后,我正在检查添加到 /proc/kallsysms 中的所有符号。我没有观察到 test_hello_init。为什么我们没有
0000000000000000 r __func__.20413 [hello]
0000000000000000 t test_hello_exit [hello]
0000000000000000 r __func__.20417 [hello]
0000000000000000 r _note_6 [hello]
0000000000000000 d __this_module [hello]
0000000000000000 t cleanup_module [hello]
使用 Linux 内核 5.8 源作为参考,“kallsyms”的模块符号 table 是通过调用 add_kallsyms()
(在“kernel/module .c") 在模块加载时(调用路径:系统调用 init_module()
、load_module()
、post_relocation()
、add_kallsyms()
),在模块完全初始化之前。它添加了模块的完整符号table(由模块的kallsyms
成员指向),还构造了一个cut-down,核心符号table(在模块的core_kallsyms
member) 在模块初始化后使用。
从完整符号table到核心符号table的切换发生在调用
/* Switch to core kallsyms now init is done: kallsyms may be walking! */
rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
来自 do_init_module()
(调用路径:系统调用 init_module()
、load_module()
、do_init_module()
)。这发生在模块的 init
函数(如果有)被调用之后。
do_init_module()
还负责在模块初始化成功后丢弃模块的初始内存部分(包含标记为 __init
的函数和标记为 __initdata
的数据)。这是通过将指向模块初始化部分的指针添加到静态 init_free_list
列表并安排工作项以释放列表中的任何部分来完成的:
freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);
freeinit->module_init = mod->init_layout.base;
if (llist_add(&freeinit->node, &init_free_list))
schedule_work(&init_free_wq);
计划的工作功能是do_free_init()
。用空列表交换 init_free_list
并遍历 init_free_list
的原始副本以释放模块的初始内存部分:
list = llist_del_all(&init_free_list);
llist_for_each_safe(pos, n, list) {
initfree = container_of(pos, struct mod_initfree, node);
module_memfree(initfree->module_init);
kfree(initfree);
}
我写了一个简单的hello world内核模块
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
static int __init test_hello_init(void)
{
printk(KERN_INFO"%s: In init\n", __func__);
return 0;
}
static void __exit test_hello_exit(void)
{
printk(KERN_INFO"%s: In exit\n", __func__);
}
module_init(test_hello_init);
module_exit(test_hello_exit);
加载模块后,我正在检查添加到 /proc/kallsysms 中的所有符号。我没有观察到 test_hello_init。为什么我们没有
0000000000000000 r __func__.20413 [hello]
0000000000000000 t test_hello_exit [hello]
0000000000000000 r __func__.20417 [hello]
0000000000000000 r _note_6 [hello]
0000000000000000 d __this_module [hello]
0000000000000000 t cleanup_module [hello]
使用 Linux 内核 5.8 源作为参考,“kallsyms”的模块符号 table 是通过调用 add_kallsyms()
(在“kernel/module .c") 在模块加载时(调用路径:系统调用 init_module()
、load_module()
、post_relocation()
、add_kallsyms()
),在模块完全初始化之前。它添加了模块的完整符号table(由模块的kallsyms
成员指向),还构造了一个cut-down,核心符号table(在模块的core_kallsyms
member) 在模块初始化后使用。
从完整符号table到核心符号table的切换发生在调用
/* Switch to core kallsyms now init is done: kallsyms may be walking! */
rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
来自 do_init_module()
(调用路径:系统调用 init_module()
、load_module()
、do_init_module()
)。这发生在模块的 init
函数(如果有)被调用之后。
do_init_module()
还负责在模块初始化成功后丢弃模块的初始内存部分(包含标记为 __init
的函数和标记为 __initdata
的数据)。这是通过将指向模块初始化部分的指针添加到静态 init_free_list
列表并安排工作项以释放列表中的任何部分来完成的:
freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);
freeinit->module_init = mod->init_layout.base;
if (llist_add(&freeinit->node, &init_free_list))
schedule_work(&init_free_wq);
计划的工作功能是do_free_init()
。用空列表交换 init_free_list
并遍历 init_free_list
的原始副本以释放模块的初始内存部分:
list = llist_del_all(&init_free_list);
llist_for_each_safe(pos, n, list) {
initfree = container_of(pos, struct mod_initfree, node);
module_memfree(initfree->module_init);
kfree(initfree);
}