Debe decirle al sistema de compilación que su llamada al sistema requiere 2 argumentos y que son del tipo int
. Esto es para que las secuencias de comandos que forman parte del sistema de compilación generen contenedores apropiados para convertir los argumentos en el tipo que necesita. En lugar de definir el controlador real como lo hizo, debe usar -
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
se define en linux/include/linux/syscalls.h.
Puede ver un ejemplo en linux/fs/read_write.c
Encontré la solución. Como respondió @Ajay Brahmakshatriya, debería usar la macro SYSCALL_DEFINEx. Y también, debería modificar arch/x86/entry/syscalls/syscall_64.tbl también.
Aquí está el resumen final.
Cómo agregar nuevas llamadas al sistema
Primero, modifique arch/x86/entry/syscalls/syscall_64.tbl :agregue esas líneas a continuación.
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
En segundo lugar, modifique include/linux/syscalls.h :agregue esas líneas a continuación.
asmlinkage long sys_my_syscall_0(void);
asmlinkage long sys_my_syscall_1(int);
asmlinkage long sys_my_syscall_2(int, int);
En tercer lugar, cree un nuevo archivo para la implementación. Para mi 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;
}
Cuarto, agregue el archivo creado a Makefile en su directorio. Para mi 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
...
Finalmente, compile e instale el kernel. Ahora, podrá ver que las nuevas llamadas al sistema funcionan bien.
#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 El comando me muestra que las llamadas al sistema están funcionando bien.
# dmesg
my_syscall_0
my_syscall_1 : 1
my_syscall_2 : 2, 3