我是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);
}
然后我用单行在Makefile
目录中创建了my_syscall
:
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.c
和syscalls.h
文件中,声明都是相同的。这是宣告syscall的仅有的两个文件,但它也在syscall_64.tbl
中被命名,这似乎是linux试图指向我的地方。但是,当我直接按照指南进行操作时,我看不出在表中声明它出了什么问题。任何帮助,将不胜感激!
信息:
内核版本:5.4.15
Linux发行版:Ubuntu 14
某些体系结构(包括x86-64)使用syscall包装器调用真正的syscall处理程序。若要定义实际的syscall处理程序及其包装器(对于使用syscall包装器的体系结构),请在syscall处理程序主体之前使用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表条目的最后一部分从“ sys_my_syscall”更改为“ __x64_sys_my_syscall”。如果向上滚动,则其他条目具有相同的前缀。进行更改后,内核开始编译。