¿Qué son la memoria alta y la memoria baja en Linux?

92

Estoy interesado en la diferencia entre Highmem y Lowmem:

  1. ¿Por qué hay tanta diferenciación?
  2. ¿Qué ganamos al hacerlo?
  3. ¿Qué características tiene cada uno?
Sen
fuente
@hiro, quieres decir que "HIGHMEM" es "dirección virtual del núcleo" como lo describe ldd3. Estoy de acuerdo contigo. es confuso, ldd3 definió "LOWMEM" "HIGHMEM", también definió "dirección virtual del núcleo" "dirección lógica del núcleo". son lo mismo, pero tienen un nombre diferente. esa es la "belleza" del software, es tan dependiente del lenguaje de descripción.
Steve

Respuestas:

69

En una arquitectura de 32 bits, el rango de espacio de direcciones para direccionar RAM es:

0x00000000 - 0xffffffff

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

El kernel de Linux se divide en 3/1 (también podría ser 2/2, o 1/3 1 ) en el espacio del usuario (memoria alta) y el espacio del kernel (memoria baja) respectivamente.

El rango de espacio del usuario:

0x00000000 - 0xbfffffff

Cada proceso de usuario recién generado obtiene una dirección (rango) dentro de esta área. Los procesos del usuario generalmente no son de confianza y, por lo tanto, tienen prohibido acceder al espacio del kernel. Además, se consideran no urgentes, como regla general, el núcleo intenta diferir la asignación de memoria a esos procesos.

El rango de espacio del kernel:

0xc0000000 - 0xffffffff

Un núcleo procesa obtiene su dirección (rango) aquí. El kernel puede acceder directamente a este 1 GB de direcciones (bueno, no el 1 GB completo, hay 128 MB reservados para acceso de alta memoria).

Los procesos generados en el espacio del kernel son confiables, urgentes y se supone que están libres de errores, la solicitud de memoria se procesa instantáneamente.

Cada proceso del kernel también puede acceder al rango de espacio del usuario si lo desea. Y para lograr esto, el kernel asigna una dirección desde el espacio del usuario (la memoria alta) a su espacio del kernel (la memoria baja), los 128 MB mencionados anteriormente están especialmente reservados para esto.


1 La CONFIG_VMSPLIT_...opción controla si la división es 3/1, 2/2 o 1/3 ; probablemente puede consultar debajo /boot/config*para ver qué opción se seleccionó para su núcleo.

meneo
fuente
Esto es viejo y no estoy seguro de que estés por aquí. Pero quiero preguntar una cosa: los 128 MB reservados en el espacio del kernel (para acceso de memoria alta), ¿son todas las referencias del área de memoria del espacio del usuario? Entonces, un proceso de kernel puede acceder a cualquier espacio de usuario al referirse a esta área, ¿verdad?
Amumu
1
¿Por qué siempre está en 1/4? Es decir, ¿por qué no podría dividirlo 5/1 o algo así?
mgalgs
¿Qué significa exactamente "puede acceder directamente" aquí? Quiero decir, ¿no se accede al núcleo mismo a través del mecanismo de memoria virtual?
telenn
1
Creo que lo que dices sobre la memoria alta / baja está mal: creo que en un sistema puro de 32 bits, el kernel puede acceder directamente a los 3 GB de espacio de usuario directamente (el kernel puede acceder al espacio del kernel y al espacio del usuario). Sin embargo, cuando tiene un núcleo PAE, las cosas se vuelven más complejas, ahora tiene más de 3 GB de RAM, cada proceso puede ser de 3 GB y no puede acceder directamente a todo el espacio del usuario. Aquí es donde entra en juego la memoria alta y esa memoria de 128 MB en el espacio del kernel. Con un kernel de 64 bits, se vuelve más simple nuevamente, no hay hombres altos, ya que todo el espacio de usuario es accesible desde el kernel.
ctrl-alt-delor
2
@mgalgs ¼, 2/4 y ¾ era solo un conjunto de opciones predeterminadas que estaban expuestas. Desde 2007, también se pueden seleccionar 5/16 y 15/32. Si sabe editar qué línea #define, puede elegir una división casi arbitraria propia.
jørgensen
28

La primera referencia a la que recurrir es a los Controladores de dispositivos Linux (disponibles en línea y en forma de libro), particularmente el capítulo 15, que tiene una sección sobre el tema.

En un mundo ideal, cada componente del sistema podría asignar toda la memoria a la que necesita acceder. Y este es el caso de los procesos en Linux y en la mayoría de los sistemas operativos: un proceso de 32 bits solo puede acceder a un poco menos de 2 ^ 32 bytes de memoria virtual (de hecho, aproximadamente 3 GB en una arquitectura típica de Linux de 32 bits). Se vuelve difícil para el kernel, que necesita poder mapear la memoria completa del proceso cuya llamada al sistema está ejecutando, más toda la memoria física, más cualquier otro dispositivo de hardware mapeado en memoria.

Entonces, cuando un kernel de 32 bits necesita asignar más de 4 GB de memoria, debe compilarse con soporte de alta memoria. La memoria alta es memoria que no está asignada permanentemente en el espacio de direcciones del núcleo. (La memoria baja es lo contrario: siempre está asignada, por lo que puede acceder a ella en el núcleo simplemente haciendo referencia a un puntero).

Cuando accede a una memoria alta desde el código del núcleo, kmapprimero debe llamar para obtener un puntero de una estructura de datos de página ( struct page). Las llamadas kmapfuncionan tanto si la página está en memoria alta o baja. También hay kmap_atomicrestricciones adicionales pero es más eficiente en máquinas multiprocesador porque utiliza un bloqueo de grano más fino. El puntero obtenido kmapes un recurso: utiliza el espacio de direcciones. Una vez que haya terminado con él, debe llamar kunmap(o kunmap_atomic) para liberar ese recurso; entonces el puntero ya no es válido y no se puede acceder al contenido de la página hasta que kmapvuelva a llamar .

Gilles
fuente
2
Gracias Gilles por la respuesta. Pero aún no puedo entender todo el concepto. ¿Podría ser un poco más simple sin reducir la información que contiene?
Sen
17

Esto es relevante para el kernel de Linux; No estoy seguro de cómo un núcleo de Unix maneja esto.

La memoria alta es el segmento de memoria que los programas de espacio de usuario pueden abordar. No puede tocar Memoria baja.

Low Memory es el segmento de memoria que el kernel de Linux puede abordar directamente. Si el kernel debe acceder a High Memory, primero debe asignarlo a su propio espacio de direcciones.

Recientemente se introdujo un parche que le permite controlar dónde está el segmento. La desventaja es que puede quitar la memoria direccionable del espacio del usuario para que el kernel pueda tener más memoria que no tiene que asignar antes de usar.

Recursos adicionales:

Shawn J. Goff
fuente
4

HIGHMEM es un rango de espacio de memoria del kernel, pero NO es la memoria a la que accedes, sino que es un lugar donde pones lo que quieres acceder.

Un mapa de memoria virtual de Linux de 32 bits típico es como:

  • 0x00000000-0xbfffffff: proceso de usuario (3GB)

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

(Aquí se ignora el vector específico de la CPU y todo lo demás).

Linux divide el espacio del kernel de 1 GB en 2 partes, LOWMEM y HIGHMEM. La división varía de una instalación a otra.

Si una instalación elige, digamos, 512MB-512MB para mems BAJO y ALTO, el 512MB LOWMEM (0xc0000000-0xdfffffff) se asigna estáticamente en el momento del arranque del kernel; por lo general, se utilizan los primeros bytes de la memoria física para que las direcciones virtuales y físicas en este rango tengan un desplazamiento constante de, por ejemplo, 0xc0000000.

Por otro lado, el último 512MB (HIGHMEM) no tiene mapeo estático (aunque podría dejar páginas mapeadas semipermanentemente allí, pero debe hacerlo explícitamente en su código de controlador). En cambio, las páginas se asignan temporalmente y no se asignan aquí para que las direcciones virtuales y físicas en este rango no tengan una asignación consistente. Los usos típicos de HIGHMEM incluyen buffers de datos de una sola vez.

hiro
fuente
3

Hasta donde recuerdo, "High Memory" se usa para el espacio de la aplicación y "Low Memory" para el kernel.

La ventaja es que las aplicaciones (espacio de usuario) no pueden acceder a la memoria de espacio de kernel.

Gert
fuente
0

Mucha gente ha dicho que la poca memoria es para el sistema operativo. Esto suele ser cierto, pero no tiene por qué serlo. La memoria alta y la memoria baja son solo dos partes del espacio de memoria, pero en el sistema Linux la memoria baja es solo para el núcleo y la memoria alta para los procesos del usuario.

De acuerdo con el "Libro de los dinosaurios (conceptos del sistema operativo)", podemos colocar el sistema operativo en memoria baja o memoria alta. El factor principal que afecta esta decisión es la ubicación del vector de interrupción. Dado que el vector de interrupción a menudo se encuentra en poca memoria, los programadores generalmente también colocan el sistema operativo en poca memoria.

Zheng Gao
fuente