Linux 手册页的第 2 部分包含 system calls
.
找到这个链接后,我说“OK!我用这个引用来开发每个模块,它是完整的”。
但似乎我无法使用此部分的某些功能(如 bind(2)
)。在包含必需的 header (如 <sys/socket.h>
)后,模块编译失败。
一些函数/宏,如 printk
没有在第 2 节中列出。许多人使用 Linux Apis,我找不到任何官方引用(就像 printk
)。我不知道他们是怎么找到这些功能的? (可能是通过阅读内核的整个源代码而不是阅读任何引用资料)
有些函数像memset
在第 3 节(用户空间库)中进行了描述,但内核模块开发人员可以毫无错误地使用它!
在开发可加载内核模块时,我在哪里可以找到可用 header 和函数 的COMPLETE 引用? (类似于 MSDN 和 WINDDK 引用资料)
#include <linux/init.h>
#include <linux/module.h>
/* A complete list of availabe headers and functions is missing! */
static int my_init(void)
{
return 0;
}
static void my_exit(void)
{
return;
}
module_init(my_init);
module_exit(my_exit);
最佳答案
如您所知,内核是一个非常庞大且独立的野兽。这意味着您不能包含任何在您的内核源代码树下找不到的内容。
当你实现你的模块时,这意味着你唯一可以链接到的就是你得到的东西:
- 内核源代码树本身
- 你制作的另一个模块(我建议尽可能避免这种情况......)
请注意,只有导出后才能使用这些函数。您可以使用 nm
进行检查已编译的实用程序 .ko
一个模块的文件。如果你想导出模块的一些符号,你必须使用 macro EXPORT_SYMBOL
.
注意不要混淆用户空间包含,通常在/usr/include 下与内核模块 header (您可能希望链接到它)找到。
在您提供的示例中,sys/socket.h 是 make headers_install
之后 header 的位置.在此位置,它旨在供用户空间应用程序使用。这不是您在编写模块时想要的。
我认为你必须更深入地了解内核中套接字的使用。通过谷歌搜索,我找到了 -> this <- 在 LWN 上检查了我的 3.8 内核源代码树的 include/linux/net.h header 。链接中描述的补丁集成在内核中,很可能就是您要找的。p>
memset 示例也说明了我到目前为止所解释的内容:如果您想在普通应用程序中使用它,则必须包含 string.h header ,位于 /usr/include/string.h。它的内核等效项位于 ...
/your-kernel-source-tree-dir/include/linux/string.h
Et voila !您可以在任何内核代码段中使用 memset 和 friend ,只要您包含正确的 header !
因此,当您感到有些沮丧时,想着伙计,我只需在我的应用程序中包含这个 header 就可以使用它......深入了解内核源代码树(或grep
为您做 ;))。您很有可能找到您要找的东西!
关于c - 我可以在可加载内核模块中使用哪些头文件和函数(外部库除外)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17271056/