gpt4 book ai didi

linux-kernel - 编译器/链接器如何解析内核 API,例如从 linux 上的模块调用的 'printk'

转载 作者:行者123 更新时间:2023-12-01 10:05:44 24 4
gpt4 key购买 nike

我已经编写了一个示例 hello.ko 内核模块:

#include <linux/module.h>      /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */

int init_module(void)
{
printk(KERN_INFO "Hello world.\n");
return 0;
}

void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}

在这里,我使用了“printk”方法,它是 Linux 公开的内核 API。我可以在“/proc/kallsyms”中看到 Linux 导出的符号。我很想知道 gcc/ld 如何链接被调用的内核 API? gcc/ld 是否从“/proc/kallsyms”或其他文件中获取内核方法的地址并执行链接?如果是,gcc/ld 如何知道这一点?我找不到任何可以说明这一点的选项。

最佳答案

Linux 内核的模块加载器基本上包含一个专用运行时链接器。 .ko 文件实际上是一个与任何其他文件一样的目标文件,因此它带有一个符号表。如果你运行 nm在它上面(nm <path/to/some_module.ko>),你会看到很多标记为“U”的符号,即“未定义”。这包括模块使用的核心内核函数的符号,例如 printk , __kmalloc , kfree等,但在许多情况下还有其他模块实现的符号。

当模块被加载时,内核运行模块的 undefined symbol 并在(运行时)符号表中查找它们,修补相关的内存位置,就像任何其他链接器一样。如果符号表中还没有任何 undefined symbol ,加载将失败(使用 insmod 而不是 modprobe 很容易演示,因为它不会加载依赖项)。它还将模块导出的任何符号添加到符号表中以供其他模块使用,跟踪依赖关系,因此您不能抽出另一个模块使用的模块。 Ilya Matveychikov已在评论中链接到模块加载器中的相关代码,如果您想了解所有血腥细节,这将有所帮助。

关于linux-kernel - 编译器/链接器如何解析内核 API,例如从 linux 上的模块调用的 'printk',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10946081/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com