我会一步步教你
首先我在我的 Linux 内核目录中编辑 3 个文件
打开
LINUX_DIRECTORY/arch/x86/syscalls/syscall_64.tbl
并添加我正在实现的自定义调用——使用适当的格式在此处声明它们:
LINUX_DIRECTORY/include/linux/syscalls.h
– 使用适当的格式:打开
LINUX_DIRECTORY/Makefile
并将我存储新系统调用的目录添加到core-y
行:core-y := usr/my_system_call_directory/
这是我遇到问题的地方。在 LINUX_DIRECTORY/my_system_call_directory
中,我添加了一个 C 文件,其中包含我的自定义系统调用定义及其相应的 Makefile
。我将定义留空,因为在我的内核模块的 C 文件中,我声明了一个外部函数(我的自定义系统调用)并定义了一个单独的函数,该函数设置为我的外部函数:
extern long (*start_shuttle)(void);
long my_start_shuttle(void) {
// stuff here
}
int init_module(void) {
// stuff here
start_shuttle = my_start_shuttle;
// more stuff
}
重新编译内核后,我尝试制作
内核模块并得到一个no definition for start_shuttle
错误。
这是因为我在 my_system_call_directory
中将 start_shuttle
的定义留空了吗?它应该与我在内核模块中定义的 my_start_shuttle
完全匹配,还是应该添加一些特殊的东西?我提前问了一些愚蠢的问题,因为我的机器重新编译 Linux 需要很长时间,而且我不确定要更改什么。谢谢
最佳答案
想通了。对于像我这样慢的人,您必须使用包装器和 stub 。
所以对于这个例子,在 my_system_call_directory
中,在用于新系统调用定义的 c
文件中,您需要这样的东西:
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/export.h>
// initialize the stub function to be NULL
long (*start_shuttle)(void) = NULL;
EXPORT_SYMBOL(start_shuttle);
// wrapper
asmlinkage long sys_start_shuttle(void)
{
if (start_shuttle)
return start_shuttle();
else
return -ENOSYS;
}
关于c - 使用自定义系统调用编译 Linux 内核模块时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26411341/