Devi dire al sistema di compilazione che la tua chiamata di sistema richiede 2 argomenti e che sono di tipo int
. Questo è così che gli script che fanno parte del sistema di compilazione genereranno wrapper appropriati per trasmettere gli argomenti nel tipo richiesto. Invece di definire il gestore effettivo come hai fatto tu, dovresti usare -
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
è definito in linux/include/linux/syscalls.h.
Puoi guardare un esempio in linux/fs/read_write.c
Ho trovato la soluzione. Come ha risposto @Ajay Brahmakshatriya, dovrei usare la macro SYSCALL_DEFINEx. Inoltre, dovrei modificare arch/x86/entry/syscalls/syscall_64.tbl anche.
Ecco il riepilogo finale.
Come aggiungere nuove chiamate di sistema
Innanzitutto, modifica arch/x86/entry/syscalls/syscall_64.tbl :aggiungi quelle righe sotto.
335 common my_syscall_0 __x64_sys_my_syscall_0
336 common my_syscall_1 __x64_sys_my_syscall_1
337 common my_syscall_2 __x64_sys_my_syscall_2
Secondo, modifica include/linux/syscalls.h :aggiungi quelle righe sotto.
asmlinkage long sys_my_syscall_0(void);
asmlinkage long sys_my_syscall_1(int);
asmlinkage long sys_my_syscall_2(int, int);
Terzo, crea un nuovo file per l'implementazione. Nel mio caso, kernel/my_syscall.c .
#include <linux/syscalls.h>
#include <linux/kernel.h>
SYSCALL_DEFINE0(my_syscall_0)
{
printk("my_syscall_0\n");
return 0;
}
SYSCALL_DEFINE1(my_syscall_1, int, a)
{
printk("my_syscall_1 : %d\n", a);
return 0;
}
SYSCALL_DEFINE2(my_syscall_2, int, a, int, b)
{
printk("my_syscall_2 : %d, %d\n", a, b);
return b;
}
In quarto luogo, aggiungi il file creato a Makefile nella sua directory. Nel mio caso, kernel/Makefile .
...
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
...
Infine, compila e installa il kernel. Ora sarai in grado di vedere che le nuove chiamate di sistema funzionano bene.
#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 command mi mostra che le chiamate di sistema funzionano bene.
# dmesg
my_syscall_0
my_syscall_1 : 1
my_syscall_2 : 2, 3