2016-03-28 14 views
7

Cerco di capire il meccanismo in Linux di mappare lo spazio in modalità kernel in spazio in modalità utente utilizzando mmap.Come viene mappata l'anatomia della memoria Spazio del kernel

Per prima cosa ho un modulo kernel caricabile (LKM) che fornisce un dispositivo di carattere con funzionalità mmap. Quindi un'applicazione per lo spazio utente apre il dispositivo e chiama mmap. LKM alloca lo spazio di memoria sull'heap del LKM all'interno dello spazio in modalità kernel (indirizzo alto virtuale). Sul lato spazio utente il puntatore dati punta a un indirizzo virtuale basso.

La figura seguente mostra come immagino sia l'anatomia della memoria. È giusto?

Memory mapping

Per favore fatemi sapere se domanda non è chiaro, cercherò di aggiungere ulteriori dettagli.


Modifica: l'immagine è stata modificata per quanto riguarda Gil Hamilton. La freccia nera indica ora un indirizzo fisico.

+2

Sì. Questo è fondamentalmente corretto. Lo disegnerei con la pesante freccia nera che punta a destra. Cioè, condivide le stesse pagine fisiche. Non ottiene lo stesso indirizzo virtuale del kernel e in qualche modo "punta" sull'area dei dati del kernel. Invece ottiene la propria mappatura indipendente alle stesse pagine di memoria fisica. –

+0

Spesso posso leggere che ogni thread in Linux ottiene una propria area di memoria virtuale suddivisa in un kernel da 1 GB e uno spazio utente da 3 GB. In questo caso: alcune parti del modulo del kernel si trovano all'interno dello spazio del kernel parte dell'applicazione dello spazio utente? – Alex44

+1

Sì. In quel modello, lo spazio di indirizzamento virtuale del kernel è il primo 1GB (per x86 a 32 bit). Lo spazio in modalità utente è il 3GB in basso. Quindi condividono lo spazio di indirizzi virtuali da 4 GB. Quando è presente un interruttore di contesto, viene installata una nuova tabella di pagina. Ha gli stessi mapping per 1 GB superiore ma nuovi mapping per la modalità utente del nuovo processo. Tuttavia, la modalità utente non può mai accedere al primo 1GB (ad esempio, se tenta di accedere a quella memoria, riceverà un "SIGSEGV" a causa di restrizioni di accesso alla tabella di pagina). La modalità kernel * può * accedere tecnicamente allo spazio in modalità utente direttamente, anche se generalmente avviene tramite un'API. –

risposta

0

Nel disegno mancano alcune importanti ipotesi sottostanti.

Il kernel non ha bisogno di mmap() per accedere alla memoria dello spazio utente. Se un processo utente ha memoria, è già mappato nello spazio indirizzo per definizione. In questo senso, la memoria è già condivisa tra utente e kernel.

mmap() crea una nuova area nello spazio degli indirizzi virtuali dell'utente, in modo che l'area dell'indirizzo possa essere popolata dalla memoria fisica se successivamente acceduta. L'effettiva allocazione della memoria e la modifica della voce della tabella di pagina vengono eseguite dal kernel.

mmap() ha senso solo per la gestione della metà utente dello spazio di indirizzi virtuali. La metà del kernel dello spazio degli indirizzi è gestita in modo completamente diverso.

Inoltre, la metà del kernel è condivisa da tutti i processi nel sistema. Ogni processo ha il suo spazio di indirizzamento virtuale dedicato, ma le tabelle delle pagine sono programmate in modo tale che le voci della tabella di pagina per metà del kernel siano impostate esattamente allo stesso modo per tutti i processi.

Ancora, il kernel non è mmap() per accedere alla memoria dello spazio utente. mmap() è piuttosto un servizio fornito dal kernel all'utente per modificare il mapping corrente nello spazio degli indirizzi virtuali dell'utente.

BTW, il kernel in realtà ha alcuni modi per accedere alla memoria utente, se lo desidera.

Prima di tutto, il kernel ha una regione dedicata di spazio indirizzo del kernel (come parte del suo spazio del kernel) che mappa l'interezza della memoria fisica presente in modo consecutivo. (Questo è vero in tutti i sistemi a 64 bit. Nel sistema a 32 bit il kernel deve "rimappare" al volo per ottenere ciò.)

Secondo, se il kernel viene immesso tramite una chiamata di sistema o un'eccezione non con l'interrupt hardware, hai un contesto di processo valido, quindi il kernel può direttamente "dereferenziare" il puntatore dello spazio utente per ottenere il valore corretto.

In terzo luogo, se il kernel vuole deferire un puntatore dello spazio utente di un processo mentre esegue un contesto preso in prestito come in un gestore di interrupt, il kernel può tracciare l'indirizzo virtuale del processo attraversando l'albero vm_area_struct per il permesso e spostando la tabella della pagina su scoprire la cornice fisica effettiva della pagina.

0

È possibile controllare le regioni di memoria eseguendo il iterating attraverso la "struct vm_area_struct" di vma attraverso la corrente.

Se si camminano gli elenchi di indirizzi e si derivano indirizzi fisici mappati per gli indirizzi virtuali che non sono correlati allo spazio utente, il layout della memoria sarà più chiaro.

A parte questa piccola correzione in questa figura, BSS non è un segmento, ma la sezione che è incorporare al segmento dati, consultare le specifiche ELF per maggiori dettagli, script del linker

Problemi correlati