Sto imparando a conoscere il kernel di Linux ma non capisco come passare dalla modalità utente alla modalità kernel in linux. come funziona? potresti darmi qualche consiglio o darmi qualche link per riferirmi ad esso o qualche libro su questo? grazie mille!Come passare dalla modalità utente alla modalità kernel?
risposta
L'unico modo in cui un applicazione utente può avviare in modo esplicito un interruttore modalità kernel durante il normale funzionamento è di fare chiamata di sistema quali open, read, write ecc
Ogni volta che un'applicazione utente chiama queste API chiamate di sistema con i parametri appropriati, viene attivato un interrupt/eccezione software (SWI).
Come risultato di questo SWI, il controllo dell'esecuzione del codice passa dall'applicazione utente a una posizione predefinita nella tabella vettoriale di interrupt [IVT] fornita dal sistema operativo.
Questo IVT contiene un indirizzo per la routine del gestore di eccezioni SWI, che esegue tutti i passaggi necessari per passare l'applicazione utente in modalità kernel e avviare l'esecuzione delle istruzioni del kernel per conto del processo utente.
Non proprio. Su x86 qualsiasi eccezione che si origina in modalità utente trasferirà il controllo al gestore delle eccezioni appropriato nel sistema operativo, in modalità kernel. –
Vero. Non appena ho postato la mia risposta, ho voluto modificarla riflettendo che è il caso in cui l'app utente vuole passare esplicitamente alla modalità kernel. Tuttavia, ho faticato a farlo a causa di problemi di rete. L'ho modificato ora per riflettere questo. –
@AmarnathRevanna Come sa il sistema operativo che è passato alla modalità kernel durante la manutenzione di un SWI? Esiste un registro/bit hardware specifico che tiene traccia della modalità per essere supervisore (squillo 0)/utente (squillo 3) e viene aggiornato su un SWI? Fondamentalmente ciò che asserisce il passaggio all'utente alla modalità kernel a livello hardware. – Shyam
Ho appena letto questo, ed è una buona risorsa. Spiega la modalità utente e la modalità kernel, perché i cambiamenti avvengono, quanto costosi sono e fornisce alcune interessanti letture correlate.
http://www.codinghorror.com/blog/2008/01/understanding-user-and-kernel-mode.html
Ecco un breve estratto:
Kernel Mode
in modalità kernel, il codice di esecuzione ha un accesso completo e senza restrizioni per l'hardware sottostante. Può eseguire qualsiasi istruzione della CPU e fare riferimento a qualsiasi indirizzo di memoria. La modalità kernel è generalmente riservata alle funzioni di livello più basso e più affidabili del sistema operativo. Arresti anomali in modalità kernel sono catastrofici; fermeranno l'intero PC.
User Mode
in modalità utente, il codice di esecuzione non ha possibilità di accedere direttamente alla memoria di hardware o di riferimento. Il codice in esecuzione in modalità utente deve delegare alle API di sistema per accedere all'hardware o alla memoria. A causa della protezione offerta da questo tipo di isolamento, i crash in modalità utente sono sempre recuperabili. La maggior parte del codice in esecuzione sul tuo computer verrà eseguito in modalità utente.
Per passare dalla modalità utente alla modalità kernel è necessario eseguire una chiamata di sistema.
Se vuoi solo vedere cosa sta succedendo sotto il cofano, vai su TLDP is your new friend e vedi il codice (è ben documentato, non c'è bisogno di ulteriori conoscenze per capire un codice assembly).
a cui sei interessato:
movl $len,%edx # third argument: message length
movl $msg,%ecx # second argument: pointer to message to write
movl $1,%ebx # first argument: file handle (stdout)
movl $4,%eax # system call number (sys_write)
int $0x80 # call kernel
Come si può vedere, una chiamata di sistema è solo un involucro intorno al codice assembly, che esegue un'interruzione (0x80) e di conseguenza un gestore per questo chiamata di sistema sarà chiamato.
Imbrogliamo un po 'e usiamo un preprocessore C qui per costruire un eseguibile (foo.S è un file in cui si inserisce un codice dal link sottostante):
gcc -o foo -nostdlib foo.S
Run via strace per garantire che otterremo ciò che scriviamo:
$ strace -t ./foo
09:38:28 execve("./foo", ["./foo"], 0x7ffeb5b771d8 /* 57 vars */) = 0
09:38:28 stat(NULL, Hello, world!
NULL) = 14
09:38:28 write(0, NULL, 14)
Qual è il contesto della tua domanda? Stai chiedendo dei meccanismi specifici della CPU su una CPU specifica o in generale? C'è un problema che stai cercando di risolvere? –