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


92

Sono interessato alla differenza tra Highmem e Lowmem:

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

@hiro, intendi "HIGHMEM" è "indirizzo virtuale del kernel" come descritto da ldd3. Sono d'accordo con te. è confuso, ldd3 definito "LOWMEM" "HIGHMEM", anche definito "indirizzo virtuale del kernel" "indirizzo logico del kernel". sono la stessa cosa, ma hanno un nome diverso. questa è la "bellezza" del software, dipende dalla lingua-descrizione.
steve

Risposte:


69

Su un'architettura a 32 bit, l'intervallo di indirizzi per indirizzare la RAM è:

0x00000000 - 0xffffffff

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

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 bassa).

L'intervallo di spazio utente:

0x00000000 - 0xbfffffff

Ogni processo utente appena generato ottiene un indirizzo (intervallo) all'interno di quest'area. I processi 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 sopra menzionati sono particolarmente riservati per questo.


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


Questo è vecchio e non sono sicuro che tu sia qui. Ma voglio chiederti una cosa: i 128 MB riservati nello spazio del kernel (per un accesso ad alta memoria), sono tutti i riferimenti dell'area di memoria dello spazio utente? Quindi, un processo del kernel può accedere a qualsiasi spazio utente facendo riferimento a quest'area, giusto?
Amumu,

1
Perché è sempre in 1/4? Cioè perché non è possibile dividerlo in 5/1 o qualcosa del genere?
mgalgs,

Cosa significa esattamente "accedere direttamente" qui? Voglio dire, non è possibile accedere al kernel stesso tramite il meccanismo di memoria virtuale?
telenn,

1
Credo che ciò che dici sulla memoria alta / bassa sia sbagliato: credo che in un puro sistema a 32 bit, il kernel possa accedere direttamente a tutti i 3 GB di spazio utente (il kernel può accedere allo spazio del kernel e allo spazio utente). Tuttavia, quando si ha un kernel PAE, le cose diventano più complesse, ora hai più di 3 GB di RAM, ogni processo può essere di 3 GB e non puoi accedere direttamente all'intero spazio utente. È qui che entra in gioco mem alta e 128 MB di memoria nello spazio del kernel. Con un kernel a 64 bit diventa di nuovo più semplice, niente uomini alti, poiché tutto lo spazio utente è accessibile dal kernel.
ctrl-alt-delor,

2
@mgalgs ¼, 2/4 e ¾ erano solo una serie di scelte predefinite che erano state esposte. Dal 2007, si possono anche selezionare 5/16 e 15/32. Se sai di modificare quale linea #define, puoi scegliere una tua divisione quasi arbitraria.
jørgensen,

28

Il primo riferimento a cui rivolgersi è Linux Device Driver (disponibile sia online che in forma di libro), in particolare il capitolo 15 che contiene 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 chiamare kmapprima per ottenere un puntatore da una struttura di dati di pagina ( struct page). La chiamata kmapfunziona se la pagina è in memoria alta o bassa. C'è anche quello kmap_atomicche ha aggiunto vincoli ma è più efficiente su macchine multiprocessore perché utilizza un blocco a grana più fine. Il puntatore ottenuto attraverso kmapè una risorsa: utilizza lo spazio degli indirizzi. Una volta che hai finito, devi chiamare kunmap(o kunmap_atomic) per liberare quella risorsa; quindi il puntatore non è più valido e non è possibile accedere ai contenuti della pagina finché non si chiama di kmapnuovo.


2
Grazie Gilles per la risposta .. Ma non sono ancora in grado di ottenere l'intero concetto. Potresti per favore essere un po 'più semplice senza ridurre le informazioni in esso?
Sen

17

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

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

La memoria insufficiente è il segmento di memoria che il kernel Linux può indirizzare direttamente. Se il kernel deve accedere alla memoria elevata, 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:


4

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 da 512 MB (0xc0000000-0xdfffffff) viene mappato staticamente all'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 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.


3

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.


0

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.