Error: conflicting types when trying to make a simple syscall

Error: conflicting types when trying to make a simple syscall

我是 Linux 编程的新手,我正在尝试按照本指南松散地实现一个简单的系统调用:https://medium.com/anubhav-shrimal/adding-a-hello-world-system-call-to-linux-kernel-dad32875872。在我的 linux 内核目录中,我创建了一个名为 my_syscall 的新目录。在该目录中,我创建了 my_syscall.c。这里是my_syscall.c

#include <linux/syscalls.h>
#include <linux/kernel.h>

asmlinkage long sys_my_syscall(int i) {
   prink(KERN_INFO "This is the system call.");
   return(0);
}

然后我在 my_syscall 目录中用一行创建了一个 Makefile

obj-y := my_syscall.o

然后我将内核目录中 Makefile 中的这一行编辑为:

core-y         += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ my_syscall/

然后,在目录 linux-5.4.15/arch/x86/entry/syscalls 中,我编辑了 syscall_64.tbl 以在最后包含以下行:

548     64         my_syscall          sys_my_syscall

最后,在目录 linux-5.4.15/include/linux 中,我编辑了 syscalls.h 文件以在 #endif:

之前包含这一行
asmlinkage long sys_my_syscall(int i);

现在,当我 运行 命令 sudo make 时,我 运行 很快就会出现以下错误:

./arch/x86/include/generated/asm/syscalls_64.h:2664:19: error: conflicting types for 'sys_my_syscall'
__SYSCALL_64(548, sys_my_syscall, )

arch/x86/entry/syscall_64.c:18:60: note: in definition of macro '__SYSCALL-64'
  #define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);

In file included from arch/x86/entry/syscall_64.c:7:0:
./include/linux/syscalls.h:1423:17: note: previous declaration of 'sys_my_syscall' was here
 asmlinkage long sys_my_syscall(int i);
                 ^
make[3]: *** [arch/x86/entry/syscall_64.o] Error 1
make[2]: *** [arch/x86/entry] Error 2
make[1]: *** [arch/x86] Error 2
make: *** [sub-make] Error 2

我不知道如何处理这个错误。由于类型冲突错误,我认为我在某个地方以不同方式声明了系统调用,但在 my_syscall.csyscalls.h 文件中,声明是相同的。这是仅有的两个声明系统调用的文件,但它也在 syscall_64.tbl 中命名,这似乎是 linux 试图指向我的地方。但是,我没有看到我在 table 中声明它的方式有什么问题,因为我直接按照指南进行操作。如有任何帮助,我们将不胜感激!

信息:

内核版本:5.4.15

Linux分布:Ubuntu14

一些架构(包括 x86-64)使用 系统调用包装器 来调用真正的系统调用处理程序。要定义真正的系统调用处理程序及其包装器(对于使用系统调用包装器的体系结构),请在系统调用处理程序的主体之前使用 SYSCALL_DEFINE<n> 宏之一。 SYSCALL_DEFINE<n>宏的参数是函数名,后面跟着<n>对``type, param' ' 用于函数参数。

您的 sys_my_syscall 系统调用处理函数只有一个参数,因此在函数主体之前使用 SYSCALL_DEFINE1 宏:

#include <linux/syscalls.h>
#include <linux/kernel.h>

SYSCALL_DEFINE1(sys_my_syscall, int, i)
{
   printk(KERN_INFO "This is the system call (param %d).\n", i);
   return(0);
}

我正在做类似的事情并且得到了完全相同的错误。

为我修复错误的是将 syscall_64.tbl table 条目的最后部分从 "sys_my_syscall" 更改为“__x64_sys_my_syscall”。如果向上滚动,其他条目具有相同的前缀。在我做出更改后,内核开始编译。

我最终放弃了尝试在内核 5 中实现它。不幸的是,none 其他解决方案导致我的内核编译。我回滚了我的内核并按照步骤 here 进行操作。这导致系统调用正常工作。我不确定如何在内核 5+ 中实现此功能。

我刚刚更改了在 syscall_64.tbl 中定义系统调用编号的位置。

而不是这个:

548     64         my_syscall          sys_my_syscall

我写了这个:

436     common     my_syscall          __x64_sys_my_syscall

Screen Capture of my configuration

成功了。

    #include <linux/syscalls.h>
    #include <linux/kernel.h>

    SYSCALL_DEFINE1(my_syscall, int, i)
    {
       printk(KERN_INFO "This is the system call (param %d).\n", i);
       return(0);
    }

内核5,把“my_syscall”前面的“sys_”删掉试试。它对我有用