2012-01-16 21 views
5

Stavo leggendo su su come Linux funziona nel mio OS-libro, quando mi sono imbattuto in questo ..Chiamata di sistema senza commutazione di contesto?

[...] il kernel viene creato come un unico, monolitico binario. Il motivo principale è migliorare le prestazioni. Poiché tutto il codice del kernel e le strutture dati sono conservati in un unico spazio indirizzo, non è necessario alcun cambio di contesto quando un processo chiama una funzione del sistema operativo o quando viene consegnato un interrupt hardware.

Per me è stato abbastanza sorprendente, sicuramente è necessario memorizzare il contesto del processo prima di passare alla modalità kernel per gestire un'interruzione .. Ma ok, lo comprerò per ora. Alcune pagine in avanti, mentre descriveva il contesto di pianificazione di un processo, diceva:

Entrambe le chiamate di sistema e gli interrupt che si verificano mentre il processo è in esecuzione useranno questo stack.

"questo stack" è il punto in cui il kernel memorizza i registri del processo e così via.

Non è questa una contraddizione diretta alla prima citazione? Mi manca interpretarlo in qualche modo?

risposta

3

Penso che la prima citazione si riferisca alle differenze tra un kernel monolitico e uno microkernel.

Linux essendo monolitico, tutti i suoi componenti del kernel (driver di periferica, scheduler, gestore VM) funzionano a ring 0. Pertanto, non è necessario alcun cambio di contesto quando si effettuano chiamate di sistema e si gestiscono gli interrupt.

Microkernel di contrasto, in cui componenti come driver di dispositivo e provider IPC vengono eseguiti in user space, all'esterno dello squillo 0. Pertanto, questa architettura richiede ulteriori switch di contesto quando si effettuano chiamate di sistema (poiché il modulo di esecuzione potrebbe risiedere nello spazio utente) e la gestione degli interrupt (per inoltrare gli interrupt ai driver del dispositivo).

+0

Grazie. È passato molto tempo da quando l'ho studiato, ma avevo l'impressione che gli interrupt hardware in realtà interrompessero l'esecuzione e salta immediatamente alla procedura di gestione anziché eseguire il polling per gli interrupt in seguito. Ho pensato che se il processo era in esecuzione in modalità kernel avrebbe comunque bisogno di memorizzare il suo contesto prima di quel salto, ma forse quello è stato il mio errore? Suppongo ora che non sarebbe diverso da qualsiasi altra chiamata di metodo se il metodo chiamato gestisce correttamente i registri utilizzati .. ho capito bene? – user1130005

+0

La mia comprensione è che il processo è in esecuzione in modalità utente e in effetti esiste un contesto che passa alla modalità kernel prima che l'interrupt venga gestito. Tuttavia, * la gestione * dell'interrupt non richiede un commutatore di contesto aggiuntivo nei kernel monolitici, ma avviene in microkernel (poiché i driver di dispositivo risiedono nello spazio utente). –

2

"Switch di contesto" potrebbe significare uno di un paio di cose, entrambe rilevanti: (1) passaggio da utente a modalità kernel per elaborare la chiamata di sistema o un passaggio involontario alla modalità kernel per elaborare un interrupt contro lo stack di interrupt , o (2) passaggio per eseguire un altro processo utente nello spazio utente, con un salto allo spazio del kernel tra i due.

Qualsiasi spostamento dallo spazio utente allo spazio del kernel implica il risparmio di spazio utente sufficiente per tornare in modo affidabile. Se il codice dello spazio del kernel decide che - mentre non stai più eseguendo il codice utente per quel processo - è tempo di lasciar correre un altro processo utente, entra.

Quindi almeno sei parlare di 2-3 stack o luoghi per memorizzare un "contesto": gli interrupt hardware necessitano di uno stack a livello di kernel per dire cosa restituire; le chiamate di metodo/subroutine utente usano uno stack standard per ottenere quello fatto. Etc.

I kernel Unix originali - e il modello non è poi così diverso per questa parte - gestivano le chiamate di sistema come un cuoco a breve termine che elabora ordini di colazione: spostalo sul fornello per fare spazio all'ordine di pancetta appena arrivata, avvia la pancetta, torna al primo ordine. Tutto nel contesto di commutazione del kernel. Non era un'enorme applicazione di monitoraggio, che probabilmente ha fatto impazzire la gente del software IBM e DEC.

0

Quando si effettua una chiamata di sistema in Linux, un interruttore di contesto viene eseguito dallo spazio utente allo spazio del kernel (da ring3 a ring0). Ogni processo ha uno stack di modalità kernel associato, che viene utilizzato dalla chiamata di sistema.Prima che la chiamata di sistema venga eseguita, i registri CPU del processo vengono memorizzati sul suo stack in modalità utente, questo stack è diverso dallo stack in modalità kernel ed è quello che il processo utilizza per le esecuzioni dello spazio utente.

Quando un processo è in modalità kernel (o modalità utente), le funzioni di chiamata della stessa modalità non richiedono un interruttore di contesto. Questo è ciò che viene indicato dalla prima citazione.

La seconda citazione fa riferimento allo stack in modalità kernel e non allo stack in modalità utente.

Detto questo, devo menzionare le ottimizzazioni Linux, in cui non è necessaria alcuna transizione allo spazio del kernel per eseguire una chiamata di sistema, cioè tutta l'elaborazione relativa alla chiamata di sistema viene eseguita nello spazio utente stesso (quindi no context switch). vsyscall e VDSO sono tali tecniche. L'idea dietro di loro è abbastanza semplice. È quello di inviare allo spazio utente, i dati necessari per l'esecuzione della corrispondente chiamata di sistema. Maggiori informazioni possono essere trovate in this LWN article.

In aggiunta a questo, ci sono stati alcuni progetti di ricerca in cui tutta l'esecuzione avviene nello stesso squillo. I programmi spaziali utente e il codice OS risiedono entrambi nello same ring. L'idea è di eliminare l'overhead degli interruttori ad anello. Microsoft's [singularity][2] OS è uno di questi progetti.