Systemaufrufe werden nicht wie normale Funktionsaufrufe behandelt. Für den Übergang vom User-Space zum Kernel-Space wird spezieller Code benötigt, im Grunde ein bisschen Inline-Assembler-Code, der an der aufrufenden Site in Ihr Programm eingefügt wird. Der Kernel-Side-Code, der den Systemaufruf "abfängt", ist ebenfalls ein Teil auf niedriger Ebene, den Sie wahrscheinlich zumindest auf den ersten Blick nicht genau verstehen müssen.
In include/linux/syscalls.h
Ihrem Kernel-Quellverzeichnis finden Sie Folgendes:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Dann /usr/include/asm*/unistd.h
finden Sie in:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
Dieser Code besagt, dass mkdir(2)
es sich um den Systemaufruf Nr. 83 handelt. Das heißt, Systemaufrufe werden nach Nummer und nicht nach Adresse aufgerufen, wie bei einem normalen Funktionsaufruf in Ihrem eigenen Programm oder bei einer Funktion in einer Bibliothek, die mit Ihrem Programm verknüpft ist. Der oben erwähnte Inline-Assembler-Code verwendet diesen Code, um den Übergang vom Benutzer- zum Kernel-Space durchzuführen, wobei Ihre Parameter mitgeführt werden.
Ein weiterer Beweis dafür, dass die Dinge hier etwas seltsam sind, ist, dass es nicht immer eine strikte Parameterliste für Systemaufrufe gibt: open(2)
Beispielsweise können 2 oder 3 Parameter verwendet werden. Das heißt, es open(2)
ist überladen , eine Funktion von C ++, nicht von C, aber die Syscall-Schnittstelle ist C-kompatibel. (Dies ist nicht dasselbe wie die varargs-Funktion von C , mit der eine einzelne Funktion eine variable Anzahl von Argumenten annehmen kann.)
Zur Beantwortung Ihrer ersten Frage existiert keine einzige Datei mkdir()
. Linux unterstützt viele verschiedene Dateisysteme und jedes hat eine eigene Implementierung der Operation "mkdir". Die Abstraktionsschicht, die es dem Kernel ermöglicht, alles, was sich hinter einem einzelnen Systemaufruf verbirgt, wird als VFS bezeichnet . Also möchten Sie wahrscheinlich anfangen fs/namei.c
, mit zu graben vfs_mkdir()
. Die tatsächlichen Implementierungen des Änderungscodes für das Dateisystem auf niedriger Ebene befinden sich an anderer Stelle. Zum Beispiel heißt die ext4-Implementierung ext4_mkdir()
, definiert in fs/ext4/namei.c
.
Bei Ihrer zweiten Frage gibt es zwar Muster, aber keine einzige Regel. Was Sie tatsächlich brauchen, ist ein ziemlich umfassendes Verständnis der Funktionsweise des Kernels, um herauszufinden, wo Sie nach einem bestimmten Systemaufruf suchen sollten. Nicht alle Systemaufrufe beziehen das VFS mit ein, sodass ihre kernelseitigen Aufrufketten nicht alle in beginnen fs/namei.c
. mmap(2)
Beginnt beispielsweise in mm/mmap.c
, weil es Teil des Speicherverwaltungssubsystems ("mm") des Kernels ist.
Ich empfehle Ihnen eine Kopie von " Understanding the Linux Kernel " von Bovet und Cesati.