it-swarm.it

Cosa sono la memoria alta e la memoria insufficiente su Linux?

Sono interessato alla differenza tra Highmem e Lowmem:

  1. Perché esiste una tale differenziazione?
  2. Cosa otteniamo facendo così?
  3. Quali funzionalità hanno ciascuna?
94
Sen

Su un'architettura a 32 bit, l'intervallo dello spazio degli indirizzi per l'indirizzamento RAM è:

0x00000000 - 0xffffffff

o 4'294'967'295 (4GB).

Il kernel di Linux lo divide in 3/1 (potrebbe anche essere 2/2 o 1/3 1) rispettivamente nello spazio utente (memoria alta) e nello spazio kernel (memoria insufficiente).

L'intervallo di spazio utente:

0x00000000 - 0xbfffffff

Ogni processo utente appena generato ottiene un indirizzo (intervallo) all'interno di quest'area. I processi dell'utente non sono generalmente attendibili e pertanto è vietato accedere allo spazio del kernel. Inoltre, sono considerati non urgenti, come regola generale, il kernel cerca di rinviare l'allocazione della memoria a tali processi.

La gamma di spazio del kernel:

0xc0000000 - 0xffffffff

I processi di un kernel ottengono qui il suo indirizzo (intervallo). Il kernel può accedere direttamente a questi 1 GB di indirizzi (beh, non tutti i 1 GB, ci sono 128 MB riservati per l'accesso ad alta memoria).

I processi generati nello spazio del kernel sono attendibili, urgenti e considerati privi di errori, la richiesta di memoria viene elaborata istantaneamente.

Ogni processo del kernel può anche accedere all'intervallo di spazio dell'utente se lo desidera. E per raggiungere questo obiettivo, il kernel mappa un indirizzo dallo spazio utente (la memoria alta) al suo spazio kernel (la memoria bassa), i 128 MB menzionati sopra sono riservati in particolare.


1 Se la divisione è 3/1, 2/2 o 1/3 è controllata da CONFIG_VMSPLIT_... opzione; probabilmente puoi controllare sotto /boot/config* per vedere quale opzione è stata selezionata per il tuo kernel.

70
wag

Il primo riferimento a cui rivolgersi è Linux Device Driver (disponibile sia online che in forma di libro), in particolare capitolo 15 che ha una sezione sull'argomento.

In un mondo ideale, ogni componente del sistema sarebbe in grado di mappare tutta la memoria a cui deve accedere. E questo è il caso dei processi su Linux e della maggior parte dei sistemi operativi: un processo a 32 bit può accedere solo a poco meno di 2 ^ 32 byte di memoria virtuale (in effetti circa 3 GB su una tipica architettura Linux a 32 bit). Diventa difficile per il kernel, che deve essere in grado di mappare l'intera memoria del processo di cui è in esecuzione la chiamata di sistema, oltre all'intera memoria fisica, oltre a qualsiasi altro dispositivo hardware mappato in memoria.

Pertanto, quando un kernel a 32 bit deve mappare più di 4 GB di memoria, deve essere compilato con un supporto di memoria elevato. La memoria alta è la memoria che non è mappata in modo permanente nello spazio degli indirizzi del kernel. (La memoria insufficiente è l'opposto: è sempre mappata, quindi puoi accedervi nel kernel semplicemente dereferenziando un puntatore.)

Quando si accede a memoria elevata dal codice del kernel, è necessario innanzitutto chiamare kmap per ottenere un puntatore da una struttura di dati di pagina (struct page). Chiamare kmap funziona se la pagina è in memoria alta o bassa. C'è anche kmap_atomic che ha aggiunto vincoli ma è più efficiente su macchine multiprocessore perché utilizza un blocco a grana più fine. Il puntatore ottenuto tramite kmap è una risorsa: utilizza lo spazio degli indirizzi. Una volta terminato, devi chiamare kunmap (o kunmap_atomic) per liberare quella risorsa; quindi il puntatore non è più valido e non è possibile accedere al contenuto della pagina finché non si chiama nuovamente kmap.

Questo è rilevante per il kernel Linux; Non sono sicuro di come gestisca questo kernel Unix.

L'High Memory è il segmento di memoria a cui possono rivolgersi i programmi di spazio utente. Non può toccare memoria insufficiente.

La memoria insufficiente è il segmento di memoria che il kernel Linux può indirizzare direttamente. Se il kernel deve accedere a High Memory, deve prima mapparlo nel proprio spazio di indirizzi.

Recentemente è stata introdotta una patch che ti consente di controllare dove si trova il segmento. Il compromesso è che puoi portare la memoria indirizzabile lontano dallo spazio utente in modo che il kernel possa avere più memoria che non deve mappare prima dell'uso.

Risorse addizionali:

17
Shawn J. Goff

HIGHMEM è una gamma di spazio di memoria del kernel, ma NON è la memoria a cui si accede ma è un luogo in cui si inserisce ciò a cui si desidera accedere.

Una tipica mappa di memoria virtuale Linux a 32 bit è simile a:

  • 0x00000000-0xbfffffff: processo utente (3 GB)

  • 0xc0000000-0xffffffff: spazio del kernel (1 GB)

(Qui vengono ignorati il ​​vettore specifico della CPU e qualsiasi altra cosa).

Linux divide lo spazio del kernel da 1 GB in 2 pezzi, LOWMEM e HIGHMEM. La divisione varia da installazione a installazione.

Se un'installazione sceglie, diciamo, 512 MB-512 MB per mem LOW e HIGH, il LOWMEM 512 MB (0xc0000000-0xdfffffff) viene mappato staticamente al momento dell'avvio del kernel; di solito vengono utilizzati i primi così tanti byte della memoria fisica in modo che gli indirizzi virtuali e fisici in questo intervallo abbiano un offset costante, diciamo, 0xc0000000.

D'altro canto, quest'ultimo 512 MB (HIGHMEM) non ha una mappatura statica (anche se è possibile lasciare le pagine mappate in modo semi-permanente lì, ma è necessario farlo esplicitamente nel codice del driver). Invece, le pagine vengono temporaneamente mappate e non mappate qui in modo che gli indirizzi virtuali e fisici in questo intervallo non abbiano una mappatura coerente. Gli usi tipici di HIGHMEM includono buffer di dati a tempo singolo.

4
hiro

Per quanto ricordo, "High Memory" è usato per lo spazio delle applicazioni e "Low Memory" per il kernel.

Il vantaggio è che le applicazioni (spazio utente) non possono accedere alla memoria spazio kernel.

3
Gert

Molte persone hanno detto che la memoria insufficiente è per il sistema operativo. Questo di solito è vero ma non deve essere. Alta memoria e poca memoria sono solo due parti dello spazio di memoria, ma nel sistema Linux la memoria bassa è solo per il kernel e la memoria alta per i processi utente.

Secondo il "Libro dei dinosauri (concetti del sistema operativo)", possiamo posizionare il sistema operativo in memoria insufficiente o memoria elevata. Il principale fattore che influenza questa decisione è la posizione del vettore di interrupt. Poiché il vettore di interruzione è spesso in memoria insufficiente, i programmatori di solito mettono anche il sistema operativo in memoria insufficiente.

0
Zheng Gao