GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie übergebe ich Parameter an den Linux-Systemaufruf?

Sie müssen dem Build-System mitteilen, dass Ihr Systemaufruf 2 Argumente erfordert und dass sie vom Typ int sind . Auf diese Weise generieren die Skripts, die Teil des Build-Systems sind, geeignete Wrapper zum Umwandeln der Argumente in den gewünschten Typ. Anstatt den eigentlichen Handler wie Sie zu definieren, sollten Sie -

verwenden
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 ist in linux/include/linux/syscalls.h definiert.

Sie können sich ein Beispiel in linux/fs/read_write.c

ansehen

Ich habe die Lösung gefunden. Wie @Ajay Brahmakshatriya antwortete, sollte ich das Makro SYSCALL_DEFINEx verwenden. Außerdem sollte ich arch/x86/entry/syscalls/syscall_64.tbl ändern auch.

Hier ist die abschließende Zusammenfassung.

Wie man neue Systemaufrufe hinzufügt

Ändern Sie zuerst arch/x86/entry/syscalls/syscall_64.tbl :Fügen Sie diese Zeilen unten hinzu.

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

Ändern Sie zweitens include/linux/syscalls.h :Fügen Sie diese Zeilen unten hinzu.

asmlinkage long sys_my_syscall_0(void);
asmlinkage long sys_my_syscall_1(int);
asmlinkage long sys_my_syscall_2(int, int);

Drittens erstellen Sie eine neue Datei für die Implementierung. Für meinen Fall 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;
}

Viertens, fügen Sie die erstellte Datei zu Makefile in ihrem Verzeichnis hinzu. Für meinen Fall 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
...

Schließlich kompilieren und installieren Sie den Kernel. Jetzt können Sie sehen, dass neue Systemaufrufe gut funktionieren.

#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 Befehl zeigt mir, dass Systemaufrufe gut funktionieren.

# dmesg
my_syscall_0
my_syscall_1 : 1
my_syscall_2 : 2, 3

Linux
  1. So konfigurieren Sie die Virtualisierung unter Redhat Linux

  2. So ändern Sie den Hostnamen unter Linux

  3. So überprüfen Sie, ob ein Linux-System 32-Bit oder 64-Bit ist

  4. So überprüfen Sie die Systemverfügbarkeit in Linux

  5. Wie übergebe ich Parameter an einen Alias?

So übergeben Sie das Passwort an den SSH-Befehl in Linux

So verwenden Sie systemctl unter Linux

So verwenden Sie den Linux-Strace-Befehl

So listen Sie Dienste unter Linux auf

So verwenden Sie den fd-Befehl auf einem Linux-System

Wie kann ich überprüfen, ob das Linux-System 32-Bit oder 64-Bit ist?