我是一名学习操作系统的大学生。
我正在尝试在 Linux 内核中添加我自己的系统调用,但出了点问题。
我的环境如下:
- Linux 内核 v.4.19.1
- 64 位 Ubuntu LTS 18.04.1,在 Oracle VirtualBox 5.2.18 上配备英特尔酷睿 i5-4210M CPU
- 64 位 Windows 10 Home 1803 作为主机
因为我在 x86_64 机器上工作,所以我从 arch/x86/entry/syscalls/syscall_64.tbl 开始。
在 Linux 内核 v.4.19.1 中,最后一个条目是
334 common rseq __x64_sys_rseq
所以我在下面添加了这三行。
335 common my_syscall_0 sys_my_syscall_0
336 common my_syscall_1 sys_my_syscall_1
337 common my_syscall_2 sys_my_syscall_2
其次,我在 include/linux/syscalls.h 中添加了函数原型(prototype)。
asmlinkage int sys_my_syscall_0(void);
asmlinkage int sys_my_syscall_1(int);
asmlinkage int sys_my_syscall_2(int, int);
第三,我创建了一个新文件 kernel/my_syscall.c 并添加了函数的实现。
asmlinkage int sys_my_syscall_0(void)
{
printk("my_syscall_0\n");
return 0;
}
asmlinkage int sys_my_syscall_1(int a)
{
printk("my_syscall_1 : %d\n", a);
return 0;
}
asmlinkage int sys_my_syscall_0(int a, int b)
{
printk("my_syscall_2 : %d, %d\n", a, b);
return b;
}
然后,我在 kernel/Makefile 中添加了 my_syscall.o 以编译 kernel/my_syscall.c。
obj-y = fork.o exec_domain.o panic.o \
cpu.o exit.o softirq.o resource.o \
sysctl.o sysctl_binary.o capability.o ptrace.o user.o \
signal.o sys.o umh.o workqueue.o pid.o task_work.o \
extable.o params.o \
kthread.o sys_ni.o nsproxy.o \
notifier.o ksysfs.o cred.o reboot.o \
async.o range.o smpboot.o ucount.o \
my_syscall.o
用make-kpkg和dpkg命令编译后,我做了一个测试程序。
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
int main()
{
printf("1 : %d\n", syscall(335));
printf("2 : %d\n", syscall(336, 1));
printf("3 : %d\n", syscall(337, 2, 3));
return 0;
}
然而,结果很奇怪。 dmesg 向我展示了一些根本没有意义的巨大数字。
# dmesg
...
my_syscall_0
my_syscall_1 : 1111490392
my_syscall_2 : 1111490392, 1111490392
似乎每次执行程序时它都在变化。
显然,传递参数存在一些问题。但是,strace 命令向我显示值传递良好。
# strace ./syscall
...
syscall_0x14F(0x7ffd21866538, 0x7ffd21866548, ....) = 0
...
syscall_0x150(0x1, 0, 0, 0, 0x7f9e1562f3a0, ....) = 0
...
syscall_0x14F(0x2, 0x3, 0x7f9e1562f3a0, ....) = 0
....
简介
我进行了简单的系统调用。
传递给它们的参数没有按应有的方式工作。
问题:为了增加新的系统调用,上面的步骤有没有问题?
问题:给系统调用传递参数有什么需要注意的问题吗?
提前致谢。
最佳答案
您需要告诉构建系统您的系统调用需要 2 个参数,并且它们是 int
类型。这样,作为构建系统一部分的脚本将生成适当的包装器,用于将参数转换为您需要的类型。您应该使用 -
SYSCALL_DEFINE2(my_syscall_2, int, a, int, b) // Yes, there is a comma between the types and the argument names
{
printk("my_syscall_2 : %d, %d\n", a, b);
return b;
}
SYSCALL_DEFINEx
在 linux/include/linux/syscalls.h 中定义.
您可以查看 linux/fs/read_write.c 中的示例
关于c - 如何给Linux系统调用传递参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53735886/