2012-08-10 1 views
6

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?

+0

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? –

risposta

11

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.

+2

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. –

+0

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. –

+0

@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

0

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.

1

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)