c - 使用自定义系统调用编译 Linux 内核模块时出错

标签 c linux linux-kernel system-calls kernel-module

我会一步步教你

首先我在我的 Linux 内核目录中编辑 3 个文件

  1. 打开 LINUX_DIRECTORY/arch/x86/syscalls/syscall_64.tbl 并添加我正在实现的自定义调用——使用适当的格式

  2. 在此处声明它们:LINUX_DIRECTORY/include/linux/syscalls.h – 使用适当的格式:

  3. 打开 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/

相关文章:

linux - 如何写入proc大量数据

linux - 以可以在 SQL 的 IN 子句中使用的方式音译 unix 文件

linux-kernel - 从内核模块到设备的 I/O 失败并显示 EFAULT

linux - binfmt-support - 不允许我回显注册

c - 为 Linux 内核编写内置对象?

c - double free 错误释放 1000 字节

c++ - 使用 Windows API 查找路径类型

c - 使用重定向解决静态库中的 'undefined reference'

linux - 编写一个运行程序的 shell 脚本,模拟用户对程序的输入

c - 了解 printf 的隐式转换