Quali sono le differenze tra la modalità utente e la modalità kernel, perché e come si attivano entrambe e quali sono i casi d'uso?
Quali sono le differenze tra la modalità utente e la modalità kernel, perché e come si attivano entrambe e quali sono i casi d'uso?
Risposte:
Modalità kernel
In modalità kernel, il codice in esecuzione ha accesso completo e illimitato all'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. Gli arresti anomali in modalità kernel sono catastrofici; interromperanno l'intero PC.
Modalità utente
In modalità Utente, il codice in esecuzione non è in grado di accedere direttamente all'hardware o alla memoria 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 computer verrà eseguita in modalità utente.
Leggi di più
Queste sono due diverse modalità in cui il computer può funzionare. Prima di questo, quando i computer erano come una grande stanza, se qualcosa va in crash, si ferma l'intero computer. Così gli architetti informatici decidono di cambiarlo. I microprocessori moderni implementano nell'hardware almeno 2 stati diversi.
Modalità utente:
Modalità kernel:
Come avviene il passaggio.
Il passaggio dalla modalità utente alla modalità kernel non viene eseguito automaticamente dalla CPU. La CPU è interrotta da interrupt (timer, tastiera, I / O). Quando si verifica l'interrupt, la CPU interrompe l'esecuzione del programma in esecuzione, passa alla modalità kernel, esegue il gestore degli interrupt. Questo gestore salva lo stato della CPU, esegue le sue operazioni, ripristina lo stato e torna in modalità utente.
http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode
http://tldp.org/HOWTO/KernelAnalysis-HOWTO-3.html
Un processore in un computer che esegue Windows ha due diverse modalità: modalità utente e modalità kernel. Il processore passa da una modalità all'altra a seconda del tipo di codice in esecuzione sul processore. Le applicazioni vengono eseguite in modalità utente e i componenti principali del sistema operativo vengono eseguiti in modalità kernel. Sebbene molti driver vengano eseguiti in modalità kernel, alcuni driver potrebbero essere eseguiti in modalità utente.
Quando si avvia un'applicazione in modalità utente, Windows crea un processo per l'applicazione. Il processo fornisce all'applicazione uno spazio di indirizzi virtuali privati e una tabella handle privata. Poiché lo spazio degli indirizzi virtuali di un'applicazione è privato, un'applicazione non può modificare i dati che appartengono a un'altra applicazione. Ogni applicazione viene eseguita in isolamento e, se un'applicazione si blocca, l'arresto è limitato a quell'unica applicazione. Altre applicazioni e il sistema operativo non sono interessati dal crash.
Oltre ad essere privato, lo spazio degli indirizzi virtuali di un'applicazione in modalità utente è limitato. Un processore in esecuzione in modalità utente non può accedere agli indirizzi virtuali riservati per il sistema operativo. La limitazione dello spazio degli indirizzi virtuali di un'applicazione in modalità utente impedisce all'applicazione di alterare e possibilmente danneggiare i dati critici del sistema operativo.
Tutto il codice eseguito in modalità kernel condivide un singolo spazio di indirizzi virtuali. Ciò significa che un driver in modalità kernel non è isolato dagli altri driver e dal sistema operativo stesso. Se un driver in modalità kernel scrive accidentalmente nell'indirizzo virtuale sbagliato, i dati che appartengono al sistema operativo o un altro driver potrebbero essere compromessi. Se un driver in modalità kernel si blocca, l'intero sistema operativo si blocca.
Se sei un utente Windows una volta passato questo link ne otterrai di più.
Gli anelli della CPU sono la distinzione più chiara
In modalità protetta x86, la CPU è sempre in uno dei 4 anelli. Il kernel Linux usa solo 0 e 3:
Questa è la definizione più difficile e veloce di kernel vs userland.
Perché Linux non usa gli anelli 1 e 2: CPU Privilege Rings: Perché gli anelli 1 e 2 non vengono usati?
Come viene determinato l'anello attuale?
L'anello corrente viene selezionato da una combinazione di:
tabella descrittore globale: una tabella in memoria delle voci GDT e ogni voce ha un campo Privl
che codifica l'anello.
L'istruzione LGDT imposta l'indirizzo sulla tabella descrittiva corrente.
Vedi anche: http://wiki.osdev.org/Global_Descriptor_Table
il segmento registra CS, DS, ecc., che puntano all'indice di una voce nella GDT.
Ad esempio, CS = 0
significa che la prima voce del GDT è attualmente attiva per il codice in esecuzione.
Cosa può fare ogni anello?
Il chip della CPU è costruito fisicamente in modo che:
l'anello 0 può fare qualsiasi cosa
ring 3 non può eseguire diverse istruzioni e scrivere su diversi registri, in particolare:
non può cambiare il proprio anello! Altrimenti, potrebbe impostarsi sull'anello 0 e gli squilli sarebbero inutili.
In altre parole, non è possibile modificare il descrittore di segmento corrente , che determina l'anello corrente.
non è possibile modificare le tabelle delle pagine: come funziona la paginazione x86?
In altre parole, non è possibile modificare il registro CR3 e il paging stesso impedisce la modifica delle tabelle delle pagine.
Ciò impedisce a un processo di vedere la memoria di altri processi per motivi di sicurezza / facilità di programmazione.
Impossibile registrare gestori di interrupt. Questi vengono configurati scrivendo nelle posizioni di memoria, che viene anche impedito dal paging.
I gestori vengono eseguiti nell'anello 0 e violerebbero il modello di sicurezza.
In altre parole, non è possibile utilizzare le istruzioni LGDT e LIDT.
non può eseguire istruzioni I / O come in
e out
, e quindi avere accessi hardware arbitrari.
Altrimenti, ad esempio, i permessi sui file sarebbero inutili se qualsiasi programma potesse leggere direttamente dal disco.
Più precisamente grazie a Michael Petch : è effettivamente possibile per il sistema operativo consentire istruzioni IO sull'anello 3, questo è effettivamente controllato dal segmento di stato del task .
Ciò che non è possibile è che l'anello 3 si dia il permesso di farlo se non lo aveva in primo luogo.
Linux lo disabilita sempre. Vedi anche: Perché Linux non usa il cambio di contesto hardware tramite TSS?
In che modo i programmi e i sistemi operativi passano tra gli anelli?
quando la CPU è accesa, inizia a eseguire il programma iniziale nell'anello 0 (beh, ma è una buona approssimazione). Puoi pensare che questo programma iniziale sia il kernel (ma normalmente è un bootloader che poi chiama il kernel ancora nell'anello 0 ).
quando un processo userland vuole che il kernel faccia qualcosa come scrivere su un file, usa un'istruzione che genera un interrupt come int 0x80
osyscall
per segnalare il kernel. x86-64 Linux syscall hello world esempio:
.data
hello_world:
.ascii "hello world\n"
hello_world_len = . - hello_world
.text
.global _start
_start:
/* write */
mov $1, %rax
mov $1, %rdi
mov $hello_world, %rsi
mov $hello_world_len, %rdx
syscall
/* exit */
mov $60, %rax
mov $0, %rdi
syscall
compila ed esegui:
as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out
Quando ciò accade, la CPU chiama un gestore di callback di interrupt che il kernel ha registrato al momento dell'avvio. Ecco un esempio di metallo nudo concreto che registra un gestore e lo utilizza .
Questo gestore viene eseguito nell'anello 0, che decide se il kernel consentirà questa azione, eseguirà l'azione e riavvierà il programma userland nell'anello 3. x86_64
quando exec
viene utilizzata la chiamata di sistema (o quando il kernel verrà avviato/init
), il kernel prepara i registri e la memoria del nuovo processo userland, quindi salta al punto di ingresso e commuta la CPU sull'anello 3
Se il programma cerca di fare qualcosa di cattivo come scrivere su un registro proibito o un indirizzo di memoria (a causa del paging), la CPU chiama anche un gestore di callback del kernel nell'anello 0.
Ma poiché la userland era cattiva, questa volta il kernel potrebbe interrompere il processo o dargli un avviso con un segnale.
Quando il kernel si avvia, imposta un orologio hardware con una frequenza fissa, che genera periodicamente interruzioni.
Questo orologio hardware genera interrupt che eseguono l'anello 0 e gli consentono di programmare quali processi userland riattivare.
In questo modo, la pianificazione può avvenire anche se i processi non stanno effettuando alcuna chiamata di sistema.
Qual è il punto di avere più squilli?
Ci sono due principali vantaggi nel separare kernel e userland:
Come giocarci?
Ho creato una configurazione bare metal che dovrebbe essere un buon modo per manipolare direttamente gli anelli: https://github.com/cirosantilli/x86-bare-metal-examples
Sfortunatamente non ho avuto la pazienza di fare un esempio di userland, ma sono arrivato fino alla configurazione del paging, quindi userland dovrebbe essere fattibile. Mi piacerebbe vedere una richiesta di pull.
In alternativa, i moduli del kernel Linux vengono eseguiti nell'anello 0, quindi puoi utilizzarli per provare operazioni privilegiate, ad esempio leggere i registri di controllo: Come accedere ai registri di controllo cr0, cr2, cr3 da un programma? Ottenere l'errore di segmentazione
Ecco una comoda configurazione QEMU + Buildroot per provarlo senza uccidere il tuo host.
Lo svantaggio dei moduli del kernel è che altri kthread sono in esecuzione e potrebbero interferire con i tuoi esperimenti. Ma in teoria puoi prendere il controllo di tutti i gestori di interrupt con il tuo modulo del kernel e possedere il sistema, in realtà sarebbe un progetto interessante.
Anelli negativi
Sebbene gli anelli negativi non siano effettivamente citati nel manuale Intel, in realtà ci sono modalità CPU che hanno ulteriori capacità rispetto allo stesso anello 0, e quindi si adattano bene al nome "anello negativo".
Un esempio è la modalità hypervisor utilizzata nella virtualizzazione.
Per ulteriori dettagli vedere:
BRACCIO
In ARM, gli anelli sono invece chiamati livelli di eccezione, ma le idee principali rimangono le stesse.
Esistono 4 livelli di eccezione in ARMv8, comunemente usati come:
EL0: userland
EL1: kernel ("supervisore" nella terminologia ARM).
Inserito con l' svc
istruzione (SuperVisor Call), precedentemente nota come swi
prima dell'assemblaggio unificato , che è l'istruzione utilizzata per effettuare chiamate di sistema Linux. Hello world esempio ARMv8:
hello.s
.text
.global _start
_start:
/* write */
mov x0, 1
ldr x1, =msg
ldr x2, =len
mov x8, 64
svc 0
/* exit */
mov x0, 0
mov x8, 93
svc 0
msg:
.ascii "hello syscall v8\n"
len = . - msg
Provalo con QEMU su Ubuntu 16.04:
sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-as -o hello.o hello.S
arm-linux-gnueabihf-ld -o hello hello.o
qemu-arm hello
Ecco un esempio di metallo nudo concreto che registra un gestore SVC e fa una chiamata SVC .
EL2: hypervisor , ad esempio Xen .
Inserito con l' hvc
istruzione (HyperVisor Call).
Un hypervisor sta a un sistema operativo, ciò che un sistema operativo sta a userland.
Ad esempio, Xen consente di eseguire più sistemi operativi come Linux o Windows sullo stesso sistema contemporaneamente e isola i sistemi operativi l'uno dall'altro per sicurezza e facilità di debug, proprio come fa Linux per i programmi userland.
Gli hypervisor sono una parte fondamentale dell'attuale infrastruttura cloud: consentono a più server di funzionare su un singolo hardware, mantenendo l'utilizzo dell'hardware sempre vicino al 100% e risparmiando un sacco di soldi.
AWS, ad esempio, ha utilizzato Xen fino al 2017, quando il suo passaggio a KVM ha fatto notizia .
EL3: ancora un altro livello. TODO esempio.
Entrato con l' smc
istruzione (Secure Mode Call)
Il modello di riferimento dell'architettura ARMv8 DDI 0487C.a - Capitolo D1 - Il modello del programmatore a livello di sistema AArch64 - La Figura D1-1 lo illustra magnificamente:
La situazione ARM è leggermente cambiata con l'avvento di ARMv8.1 Virtualization Host Extensions (VHE) . Questa estensione consente al kernel di funzionare in EL2 in modo efficiente:
VHE è stato creato perché le soluzioni di virtualizzazione del kernel Linux come KVM hanno guadagnato terreno su Xen (vedi ad esempio il passaggio di AWS a KVM menzionato sopra), perché la maggior parte dei client necessita solo di VM Linux e, come puoi immaginare, è tutto in un unico progetto, KVM è più semplice e potenzialmente più efficiente di Xen. Quindi ora il kernel Linux host funge da hypervisor in quei casi.
Nota come ARM, forse per il vantaggio del senno di poi, ha una convenzione di denominazione migliore per i livelli di privilegio rispetto a x86, senza la necessità di livelli negativi: 0 è il più basso e 3 il più alto. I livelli più alti tendono ad essere creati più spesso di quelli inferiori.
L'attuale EL può essere interrogato con l' MRS
istruzione: qual è l'attuale modalità di esecuzione / livello di eccezione, ecc.?
ARM non richiede la presenza di tutti i livelli di eccezione per consentire implementazioni che non richiedono la funzionalità per salvare l'area del chip. ARMv8 "Livelli di eccezione" dice:
Un'implementazione potrebbe non includere tutti i livelli di eccezione. Tutte le implementazioni devono includere EL0 e EL1. EL2 e EL3 sono opzionali.
QEMU, ad esempio, è predefinito su EL1, ma EL2 ed EL3 possono essere abilitati con le opzioni della riga di comando: qemu-system-aarch64 inserendo el1 durante l'emulazione di a53 all'accensione
Snippet di codice testati su Ubuntu 18.10.
in
e out
sono disponibili per squillare 3. Il TSS può puntare a una tabella dei permessi di I / O nell'attività corrente che concede l'accesso in lettura / scrittura a tutte o porte specifiche.
Prenderò una pugnalata al buio e immagino che tu stia parlando di Windows. In poche parole, la modalità kernel ha pieno accesso all'hardware, ma la modalità utente no. Ad esempio, molti se non la maggior parte dei driver di dispositivo sono scritti in modalità kernel perché hanno bisogno di controllare i dettagli più fini del loro hardware.
Vedi anche questo wikibook .
Altre risposte hanno già spiegato la differenza tra modalità utente e modalità kernel. Se vuoi davvero entrare nei dettagli dovresti procurarti una copia di Windows Internals , un ottimo libro scritto da Mark Russinovich e David Solomon che descrive l'architettura ei dettagli interni dei vari sistemi operativi Windows.
Che cosa
Fondamentalmente la differenza tra le modalità kernel e utente non dipende dal sistema operativo e si ottiene solo limitando l'esecuzione di alcune istruzioni solo in modalità kernel tramite la progettazione hardware. Tutti gli altri scopi, come la protezione della memoria, possono essere eseguiti solo con tale restrizione.
Come
Significa che il processore vive in modalità kernel o in modalità utente. Utilizzando alcuni meccanismi, l'architettura può garantire che ogni volta che si passa alla modalità kernel il codice del sistema operativo viene recuperato per essere eseguito.
Perché
Avendo questa infrastruttura hardware, questi potrebbero essere raggiunti in sistemi operativi comuni: