Come ha scritto Mat, questo è probabilmente irragionevolmente ambito. Tuttavia, cercherò di dedicare altrettanta attenzione alla somma delle domande, come farei con una domanda a ragione, nella speranza che ciò possa aiutarti a iniziare le ricerche.
1 Qual è la differenza tra "preemption" e "context switch"?
La prelazione è l'atto di interrompere un processo senza il suo coinvolgimento. In questo contesto, ciò significa probabilmente che verrà attivato un interrupt del timer.La parola deriva da un concetto legale di preemption: l'atto o il diritto di rivendicare o acquistare prima o preferire ad altri. Per i propri scopi, ciò significa che quando si attiva l'interruzione del timer, la routine di servizio di interruzione (ISR) ha la precedenza sul codice precedentemente in esecuzione. Questo non ha necessariamente bisogno di coinvolgere un kernel; è possibile avere codice in esecuzione in qualsiasi ISR che verrà eseguito in modo preventivo.
Un interruttore di contesto è ciò che accade quando il codice OS (in esecuzione preventiva) altera lo stato del processore (registri, modalità e stack) tra un processo o il contesto di un thread e un altro. Lo stato del processore può trovarsi a una determinata riga di codice in un thread. Avrà dati temporanei nei registri, un puntatore allo stack in una certa area di memoria e altre informazioni di stato. Un OS preemptive può memorizzare questo stato (sia nella memoria statica che nello stack dei processi) e caricare lo stato di un processo precedente. Questo è noto come un interruttore di contesto.
2 Quali sono le differenze chiave tra un kernel preemptive e nonpreemptive? Che lavoro è richiesto a un programmatore per rendere il kernel preventivo?
In un kernel preventiva, un interrupt può sparare in tra due istruzioni di montaggio (noti come 'punti di sequenza'). In un kernel non preemptive, il processo in esecuzione deve chiamare una funzione yield()
per consentire l'esecuzione degli altri thread. I kernel preventivi sono più complessi, ma forniscono una migliore illusione della concorrenza. I kernel non preventivi possono essere eseguiti in modo molto semplice con setjmp.h
, ma ogni thread deve chiamare regolarmente yield()
o gli altri thread non verranno eseguiti.
Quando viene chiamata una funzione come yield()
, lo stato del processore viene memorizzato automaticamente. Quando si desidera rendere il sistema operativo preventivo, è necessario memorizzare queste informazioni manualmente.
3 Come creare e utilizzare la modalità utente?
I documenti ARM dicono che in modalità utente, qualsiasi istruzione che passa a una modalità privilegiata verrà trattata come istruzione non definita.
Corretto. Tuttavia, dicono anche che qualsiasi interrupt verrà eseguito automaticamente in modalità privilegiata. Su un sistema ARM, è possibile utilizzare l'istruzione svc
per generare un interrupt software. Il codice SVC (parte del tuo sistema operativo) sarà quindi in grado di funzionare in modalità privilegiata.
4 Se è così, l'unico modo per un programma dello spazio utente di utilizzare il codice del kernel è syscalls?
Corretto. Almeno, questo è l'unico modo sicuro o corretto.
5 In che modo un kernel risponde o interagisce con userspace, quindi?
Su ARM, l'istruzione SVC può ottenere un valore di 8 bit. Questo può essere usato per generare 256 syscalls come yield, abilitare gli interrupt, disabilitare gli interrupt o qualunque cosa sia necessaria. È anche possibile scegliere di creare una memoria condivisa o un meccanismo di interazione di trasmissione di messaggi, se necessario.
6 Ciò significa che l'unico thread del kernel dopo l'avvio (in un sistema semplice) sarebbe il thread inattivo?
Questo dipende interamente da come si progetta il proprio sistema. È probabilmente più semplice se si sceglie di avviare il proprio kernel solo dopo aver creato tutti i thread, in questo modo non è necessario preoccuparsi di allocare dinamicamente i thread. In alternativa, si può iniziare con il thread inattivo e aggiungere altri thread in seguito (attraverso una shell remota? Penso che ci si vuole almeno un thread utente che esegue costantemente ...)
7 Se la pagina in cui il codice del kernel e risiede i dati non è mappato quando si passa a un processo utente, quindi su un syscall o interrupt, come si esegue il codice del kernel senza essere mappato nello spazio degli indirizzi virtuali?
Proprio come codice in modalità kernel viene eseguito in modalità privilegiata, anche se il codice è stato precedentemente in esecuzione in modalità utente, così sarà kernel modalità di esecuzione di codice da stack pointer principale (MSP), anche se il codice processo è stato utilizzato un indirizzo diverso spazio.
8 Un "kernel preempibile" significa solo che il kernel è stato progettato in modo tale che sarebbe sicuro avere un cambio di contesto durante l'esecuzione del codice del kernel? o richiede più lavoro da fare se c'è?
Penso che ciò significhi che il kernel possa prevenire il codice utente, non che il kernel stesso possa essere preventivato. Sarebbe difficile e insolito che qualsiasi cosa interrompa il kernel. Ciò richiederebbe più lavoro, e sto faticando a capire perché lo vorresti.
Dal [FAQ]:. "I vostri quesiti dovrebbero essere ragionevolmente scope Se si può immaginare un intero libro che risponde alla tua domanda, si sta chiedendo troppo. " Ci sono troppe domande qui e lo scopo è davvero ampio. Sembra che tu abbia bisogno di un buon libro sul design del sistema operativo in generale, e uno buono su ARM in particolare. – Mat
Sì, un libro sarebbe una buona cosa come menzionato nella domanda. lo scopo stesso delle domande non è così ampio, si tratta di preemption o della relazione dell'utente del kernel. Comunque ho paura che siano troppi per un singolo post, mi dispiace per quello. Vedrò cosa una mod ti consiglia di scomporre o cambiare in qualcosa del tipo "hai bisogno di un buon libro di progettazione del sistema per braccio" .. – sgupta
Le domande di raccomandazione del libro non funzionano qui. (Ci sono alcuni storici che rimangono, ma quelli nuovi non sono i benvenuti.) – Mat