Wie greife ich vom User-Space aus auf den Systemaufruf zu?

Ich habe einige Absätze in LKD gelesen1 und ich kann den folgenden Inhalt einfach nicht verstehen:

Zugriff auf den Systemaufruf aus dem User-Space

Im Allgemeinen bietet die C-Bibliothek Unterstützung für Systemaufrufe. Benutzeranwendungen können Funktionsprototypen aus den Standardköpfen abrufen und mit der C-Bibliothek verknüpfen, um Ihren Systemaufruf (oder die Bibliotheksroutine, die wiederum Ihren syscall-Aufruf verwendet) zu verwenden. Wenn Sie den Systemaufruf jedoch gerade geschrieben haben, ist es zweifelhaft, dass glibc ihn bereits unterstützt!

Zum Glück stellt Linux eine Reihe von Makros zur Verfügung, mit denen der Zugriff auf Systemaufrufe umbrochen werden kann. Es richtet den Registerinhalt ein und gibt die Trap-Anweisungen aus. Diese Makros werden benannt_syscalln(), wohern liegt zwischen null und sechs. Die Anzahl entspricht der Anzahl der an den Syscall übergebenen Parameter, da das Makro wissen muss, wie viele Parameter zu erwarten sind, und folglich in die Register schreiben muss. Betrachten Sie beispielsweise den Systemaufrufopen(), definiert als

long open(const char *filename, int flags, int mode)

Das syscall-Makro zur Verwendung dieses Systemaufrufs ohne explizite Bibliotheksunterstützung wäre

#define __NR_open 5
_syscall3(long, open, const char *, filename, int, flags, int, mode)

Dann kann die Anwendung einfach anrufenopen().

Für jedes Makro gibt es 2 + 2 × n Parameter. Der erste Parameter entspricht dem Rückgabetyp des Syscalls. Der zweite ist der Name des Systemaufrufs. Als nächstes folgen Typ und Name für jeden Parameter in der Reihenfolge des Systemaufrufs. Das__NR_open define ist in<asm/unistd.h>; es ist die Systemrufnummer. Das_syscall3 Makro wird mit Inline-Assembly zu einer C-Funktion erweitert; Die Assembly führt die im vorherigen Abschnitt beschriebenen Schritte aus, um die Systemrufnummer und die Systemparameter in die richtigen Register zu verschieben und den Software-Interrupt auszulösen, um den Kernel abzufangen. Das Einfügen dieses Makros in eine Anwendung ist alles, was für die Verwendung von erforderlich istopen() Systemaufruf.

Lassen Sie uns das Makro schreiben, um unser großartiges neues zu nutzenfoo() Rufen Sie das System auf und schreiben Sie einen Testcode, um unsere Bemühungen zu demonstrieren.

#define __NR_foo 283
__syscall0(long, foo)

int main ()
{
        long stack_size;

        stack_size = foo ();
        printf ("The kernel stack size is %ld\n", stack_size);
        return 0;
}

Was machtdie anwendung kann einfach anrufenopen() bedeuten?

Außerdem, für das letzte Stück Code, wo ist die Deklaration vonfoo()? Und wie kann ich diesen Code kompilierbar und lauffähig machen? Was sind die Header-Dateien, die ich einschließen muss?

__________
1 Linux-Kernel-Entwicklungvon Robert Love.PDF-Datei bei wordpress.com (siehe Seite 81);Google Books-Ergebnis.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage