¿Qué implica el diseño de memoria del núcleo virtual en dmesg?

19

Mientras revisaba la "Salida de dmesg" pude ver una lista de valores que no puedo entender correctamente.

Memory: 2047804k/2086248k available (3179k kernel code, 37232k reserved, 1935k data, 436k init, 1176944k highmem)
virtual kernel memory layout:
    fixmap  : 0xffc57000 - 0xfffff000   (3744 kB)
    pkmap   : 0xff800000 - 0xffa00000   (2048 kB)
    vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)
    lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)
      .init : 0xc0906000 - 0xc0973000   ( 436 kB)
      .data : 0xc071ae6a - 0xc08feb78   (1935 kB)
      .text : 0xc0400000 - 0xc071ae6a   (3179 kB)

De los valores entiendo que tengo 2 GB de RAM (memoria física). Pero el resto de las cosas parecen ser números mágicos para mí.

Me gustaría saber acerca de cada uno (fixmap, pkmap, etc.) en breve (si hay más dudas, publicaré cada uno como una pregunta separada).

¿Alguien podría explicarme eso?

Sen
fuente

Respuestas:

22

En primer lugar, un sistema de 32 bits tiene 0xffffffff( 4'294'967'295) direcciones lineales para acceder a una ubicación física encima de la RAM.
El kernel divide estas direcciones en espacio de usuario y kernel.

El usuario puede acceder al espacio de usuario (memoria alta) y, si es necesario, también el núcleo.
El rango de direcciones en notación hexadecimal y dec:

0x00000000 - 0xbfffffff
0 - 3'221'225'471

El kernel solo puede acceder al espacio del kernel (poca memoria).
El rango de direcciones en notación hexadecimal y dec:

0xc0000000 - 0xffffffff
3'221'225'472 - 4'294'967'295

Me gusta esto:

0x00000000             0xc0000000  0xffffffff 
    |                        |          |
    +------------------------+----------+
    |  User                  |  Kernel  |
    |  space                 |  space   |
    +------------------------+----------+

Por lo tanto, el diseño de memoria que vio dmesgcorresponde a la asignación de direcciones lineales en el espacio del núcleo.

Primero, las secuencias .text, .data e .init que proporcionan la inicialización de las propias tablas de páginas del núcleo (traducen lineal a direcciones físicas).

.text : 0xc0400000 - 0xc071ae6a   (3179 kB)

El rango donde reside el código del núcleo.

.data : 0xc071ae6a - 0xc08feb78   (1935 kB)

El rango donde residen los segmentos de datos del núcleo.

.init : 0xc0906000 - 0xc0973000   ( 436 kB)

El rango donde residen las tablas de páginas iniciales del núcleo.

(y otros 128 kB para algunas estructuras de datos dinámicos).

Este espacio de direcciones mínimo es lo suficientemente grande como para instalar el kernel en la RAM e inicializar sus estructuras de datos principales.

Su tamaño utilizado se muestra dentro del paréntesis, tome por ejemplo el código del núcleo:

0xc071ae6a - 0xc0400000 = 31AE6A

En notación decimal, eso es 3'255'914(3179 kB).


Segundo, el uso del espacio del núcleo después de la inicialización.

lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)

El kernel puede usar el rango lowmem para acceder directamente a las direcciones físicas.
Este no es el 1 GB completo, porque el núcleo siempre requiere al menos 128 MB de direcciones lineales para implementar la asignación de memoria no contigua y las direcciones lineales correlacionadas.

vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)

La asignación de memoria virtual puede asignar marcos de página basados ​​en un esquema no contiguo. La principal ventaja de este esquema es evitar la fragmentación externa, esto se usa para áreas de intercambio, módulos de kernel o asignación de buffers a algunos dispositivos de E / S.

pkmap   : 0xff800000 - 0xffa00000   (2048 kB)

La asignación de kernel permanente permite que el kernel establezca asignaciones duraderas de marcos de página de alta memoria en el espacio de direcciones del kernel. Cuando se asigna una página HIGHMEM usando kmap (), las direcciones virtuales se asignan desde aquí.

fixmap  : 0xffc57000 - 0xfffff000   (3744 kB)

Estas son direcciones lineales correlacionadas que pueden referirse a cualquier dirección física en la RAM, no solo a los últimos 1 GB como las direcciones lowmem. Las direcciones lineales correlacionadas son un poco más eficientes que sus colegas de lowmem y pkmap. Hay descriptores de tabla de páginas dedicados asignados para la asignación fija, y las asignaciones de páginas HIGHMEM usando kmap_atomic se asignan desde aquí.


Si quieres sumergirte más en el agujero del conejo:
Comprender el kernel de Linux

meneo
fuente
Gracias por esta gran respuesta. Me gustaría saber por qué low mem no está lleno 1GB y más sobre la siguiente parte de la oración "porque el núcleo siempre requiere al menos 128 MB de direcciones lineales para implementar la asignación de memoria no contigua y direcciones lineales correlacionadas".
Sen
El kernel tiene que acceder a código de memoria alta de vez en cuando (por ejemplo, la información de BIOS y ACPI reside en los primeros MB de la RAM), no puede hacerlo directamente (como el área de baja memoria), por lo tanto, necesita asignar poca memoria a direcciones lineales de alta memoria, los 128 MB están reservados solo para este propósito. El área de vmalloc se asigna principalmente en algunas áreas de alta memoria y se reasigna bastante rápido.
meneo
Entonces, ¿las páginas configuradas por el kernel para la llamada al sistema virtual también forman parte de fixmap? Me encontré con esta pregunta porque quiero saber qué hay exactamente en la página con la dirección fffb5000, fffa1000, etc ... Estoy recibiendo una sobrecarga en mi reproducción de registro de máquina virtual porque muchas CPU virtuales acceden MUCHO a esta página ... ¿cómo Sé exactamente qué hay en esta dirección ... GRAN RESPUESTA por cierto :)
Deepthought