GNU/Linux >> Linux Esercitazione >  >> Linux

Come funziona internamente copy_from_user dal kernel di Linux?

L'implementazione di copy_from_user() dipende fortemente dall'architettura.

Su x86 e x86-64, esegue semplicemente una lettura diretta dall'indirizzo dello spazio utente e scrive nell'indirizzo dello spazio kernel, disabilitando temporaneamente SMAP (Supervisor Mode Access Prevention) se è configurato. La parte difficile è che il copy_from_user() il codice viene inserito in una regione speciale in modo che il gestore degli errori di pagina possa riconoscere quando si verifica un errore al suo interno. Un errore di protezione della memoria che si verifica in copy_from_user() non uccide il processo come farebbe se fosse attivato da qualsiasi altro codice del contesto del processo, o manda in panico il kernel come farebbe se si verificasse nel contesto dell'interruzione - riprende semplicemente l'esecuzione in un percorso di codice che restituisce -EFAULT al chiamante.


per quanto riguarda "com'è copy_to_user dal momento che il kernel sta trasmettendo l'indirizzo dello spazio del kernel, come può accedervi un processo dello spazio utente"

Un processo dello spazio utente può tentare di accedere a qualsiasi indirizzo. Tuttavia, se l'indirizzo non è mappato nello spazio utente di quel processo (ovvero nelle tabelle delle pagine di quel processo) o se si verifica un problema con l'accesso come un tentativo di scrittura a una posizione di sola lettura, viene generato un errore di pagina. Nota che almeno su x86, ogni processo ha tutto lo spazio del kernel mappato nel 1 gigabyte più basso dello spazio degli indirizzi virtuali di quel processo, mentre i 3 gigabyte superiori dei 4 GB dello spazio degli indirizzi totale (sto usando qui il classico a 32 bit case) vengono utilizzati per il testo del processo (ovvero il codice) e i dati. Una copia da o verso lo spazio utente viene eseguita dal codice del kernel che è in esecuzione per conto del processo e in realtà è la mappatura della memoria (ovvero le tabelle delle pagine) di quel processo che sono in uso durante la copia. Ciò avviene mentre l'esecuzione è in modalità kernel, ovvero modalità privilegiata/supervisore in linguaggio x86. Supponendo che il codice dello spazio utente abbia superato una posizione di destinazione legittima (ovvero un indirizzo correttamente mappato in quello spazio di indirizzi del processo) in cui copiare i dati, copy_to_user , eseguito dal contesto del kernel sarebbe in grado di scrivere normalmente a quell'indirizzo/regione senza problemi e dopo che il controllo ritorna all'utente, anche lo spazio utente può leggere da questa posizione impostata dal processo stesso per iniziare. Dettagli più interessanti possono si trova nei capitoli 9 e 10 di Understanding the Linux Kernel, 3rd Edition, di Daniel P. Bovet, Marco Cesati. In particolare, access_ok() è un controllo di validità necessario ma non sufficiente. L'utente può comunque passare indirizzi che non appartengono allo spazio degli indirizzi del processo. In questo caso, si verificherà un'eccezione di errore di pagina mentre il codice del kernel sta eseguendo la copia. La parte piùinteressanteècome il gestore degli errori di pagina del kernel determina che l'errore di pagina in tal caso nonèdovuto a un bug nel codice del kernel ma piuttosto a un indirizzo errato dell'utente (specialmente se il codice del kernel in questione proviene da un modulo del kernel caricato).


Linux
  1. Come cercare nel Web da terminale su Linux

  2. Come funziona il bit appiccicoso?

  3. Come funziona il comando 'ls' in Linux/Unix?

  4. Come calcolare l'utilizzo della CPU di un processo tramite PID in Linux da C?

  5. Come funziona il comando ps?

Come modificare la priorità di un processo in Linux

Come costruire il kernel Linux da zero

Come funziona la memoria di scambio in Linux?

In che modo Linux carica l'immagine "initrd"?

Come funziona una GUI Linux al livello più basso?

Come funziona il display di Linux?