know linux-kernel linux-device-driver

linux kernel - know - ¿Diferencia entre la dirección virtual del kernel y la dirección lógica del kernel?



linux kernel version (4)

Básicamente hay 3 tipos de direccionamiento, a saber:

  1. Direccionamiento lógico: la dirección está formada por base y desplazamiento. Esto no es más que direccionamiento segmentado, donde la dirección (o desplazamiento) en el programa siempre se usa con el valor base en el descriptor de segmento
  2. Direccionamiento lineal: también llamada dirección virtual. Aquí las direcciones son contiguas, pero la dirección física no lo es. La paginación se utiliza para implementar esto.
  3. Direccionamiento físico: la dirección real en la memoria principal!

Ahora, en Linux, la memoria del Kernel (en el espacio de direcciones) está más allá de los 3 GB (3 GB a 4 GB), es decir, 0xc000000 ... Las direcciones utilizadas por el Kernel no son direcciones físicas. Para mapear la dirección virtual usa PAGE_OFFSET. Se debe tener cuidado de que no haya traducción de la página involucrada. Es decir, estas direcciones son contiguas en la naturaleza. Sin embargo, hay un límite para esto, es decir, 896 MB en x86. Más allá de que la paginación se utiliza para la traducción. Cuando utiliza vmalloc, estas direcciones se devuelven para acceder a la memoria asignada.

En resumen, cuando alguien se refiere a la memoria virtual en el contexto del espacio de usuario, entonces es a través de la paginación. Si se menciona la memoria virtual del kernel, entonces es una dirección PAGE_OFFSETed o vmalloced.

(Referencia - Entendiendo el Kernel de Linux - Basado en 2.6)

Shash

No puedo diferenciar exactamente entre la dirección lógica del kernel y la dirección virtual. En el libro de controladores de dispositivos Linux, se dice que todas las direcciones lógicas son direcciones virtuales del kernel y que las direcciones virtuales no tienen ningún mapeo lineal. ¿Pero lógicamente sabio cuando decimos que es lógico y cuando decimos virtual y en qué situación usamos estos dos?


El kernel de Linux asigna la mayor parte del espacio de direcciones virtuales que pertenece al kernel para realizar un mapeo 1: 1 con un desplazamiento de la primera parte de la memoria física. (un poco menos que para 1Gb para 32bit x86, puede ser diferente para otros procesadores o configuraciones). Por ejemplo, para el código del kernel en la dirección x86 0xc00000001 se asigna a la dirección física 0x1.

Esto se denomina asignación lógica: una asignación 1: 1 (con un desplazamiento) que permite al núcleo acceder a la mayor parte de la memoria física de la máquina.

Pero esto no es suficiente: en algún momento tenemos más de 1 Gb de memoria física en una máquina de 32 bits, en algún momento queremos hacer referencia a bloques de memoria física no contiguos como contiguos para simplificar, en algún momento queremos asignar regiones de E / S mapeadas en memoria que no son RAM.

Para esto, el kernel mantiene una región en la parte superior de su espacio de direcciones virtuales donde realiza una asignación "aleatoria" de página a página. La asignación allí no sigue el patrón 1: 1 del área de asignación lógica. Esto es lo que llamamos el mapeo virtual.

Es importante agregar que en muchas plataformas (x86 es un ejemplo), tanto la asignación lógica como la virtual se realizan utilizando el mismo mecanismo de hardware (TLB que controla la memoria virtual). En muchos casos, la "asignación lógica" se realiza en realidad utilizando la función de memoria virtual del procesador, por lo que esto puede ser un poco confuso. Por lo tanto, la diferencia es el patrón según el cual se realiza el mapeo: 1: 1 para lógico, algo aleatorio para virtual.


En pocas palabras, la dirección virtual incluiría "memoria alta", que no hace la asignación 1: 1 para la dirección física, si su tamaño de RAM es mayor que el rango de direcciones del kernel (normalmente, para 1G / 3G en X86, su La RAM es 3G pero el rango de direccionamiento de su kernel es 1G) y también el retorno de la dirección de kmap () y vmalloc (), lo que requiere que el kernel establezca una tabla de páginas para la asignación de memoria. como la dirección lógica siempre está asignada a la memoria por el núcleo (asignación 1: 1), no es necesario llamar explícitamente a la API del núcleo, como set_pte para configurar la entrada de la tabla de páginas para la página en particular.

así que la dirección virtual no puede ser una dirección lógica todo el tiempo.


Las direcciones lógicas del kernel son asignaciones accesibles al código del kernel a través de las funciones normales de acceso a la memoria de la CPU. En los sistemas de 32 bits, solo existen 4 GB de espacio de direcciones lógicas del kernel, incluso si hay más memoria física en uso. El espacio de direcciones lógicas respaldado por la memoria física se puede asignar con kmalloc .

Las direcciones virtuales no necesariamente tienen direcciones lógicas correspondientes. Puede asignar memoria física con vmalloc y recuperar una dirección virtual que no tiene una dirección lógica correspondiente (en sistemas de 32 bits con PAE, por ejemplo). Luego puede usar kmap para asignar una dirección lógica a esa dirección virtual.