Le chiamate di sistema non vengono gestite come le normali chiamate di funzione. Ci vuole un codice speciale per effettuare la transizione dallo spazio utente allo spazio del kernel, fondamentalmente un po 'di codice assembly inline iniettato nel programma nel sito di chiamata. Il codice laterale del kernel che "intercetta" la chiamata di sistema è anche roba di basso livello che probabilmente non è necessario comprendere a fondo, almeno all'inizio.
Nel include/linux/syscalls.h
sotto la directory dei sorgenti del kernel, si trova questo:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Quindi /usr/include/asm*/unistd.h
, trovi questo:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
Questo codice dice che mkdir(2)
è la chiamata di sistema # 83. Vale a dire, le chiamate di sistema sono chiamate per numero, non per indirizzo come con una normale chiamata di funzione all'interno del proprio programma o verso una funzione in una libreria collegata al proprio programma. Il codice di colla per assemblaggio in linea che ho menzionato sopra lo usa per effettuare la transizione dallo spazio utente a quello del kernel, prendendo i tuoi parametri insieme ad esso.
Un'altra prova che le cose sono un po 'strane qui è che non c'è sempre un rigido elenco di parametri per le chiamate di sistema: open(2)
ad esempio, può accettare 2 o 3 parametri. Ciò significa che open(2)
è sovraccarico , una caratteristica di C ++, non C, tuttavia l'interfaccia di syscall è compatibile con C. (Questa non è la stessa cosa della funzione varargs di C , che consente a una singola funzione di accettare un numero variabile di argomenti.)
Per rispondere alla tua prima domanda, non esiste un singolo file dove mkdir()
esiste. Linux supporta molti file system diversi e ognuno ha la propria implementazione dell'operazione "mkdir". Il livello di astrazione che consente al kernel di nascondere tutto ciò che si nasconde dietro una singola chiamata di sistema è chiamato VFS . Quindi, probabilmente vuoi iniziare a scavare fs/namei.c
, con vfs_mkdir()
. Le attuali implementazioni del codice di modifica del file system di basso livello sono altrove. Ad esempio, viene chiamata l'implementazione ext4 ext4_mkdir()
, definita in fs/ext4/namei.c
.
Per quanto riguarda la tua seconda domanda, sì, ci sono schemi per tutto questo, ma non una singola regola. Ciò di cui hai effettivamente bisogno è una comprensione abbastanza ampia di come funziona il kernel per capire dove dovresti cercare una particolare chiamata di sistema. Non tutte le chiamate di sistema coinvolgono VFS, quindi le loro catene di chiamate sul lato kernel non iniziano tutte fs/namei.c
. mmap(2)
, ad esempio, inizia mm/mmap.c
perché fa parte del sottosistema di gestione della memoria ("mm") del kernel.
Ti consiglio di ottenere una copia di " Capire il kernel Linux " di Bovet e Cesati.