Memoria de pagina

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 31 de enero de 2019; las comprobaciones requieren 13 ediciones .

La memoria de página  es una forma de organizar la memoria virtual , en la que las direcciones virtuales se asignan a las físicas página por página. Para la arquitectura x86 de 32 bits, el tamaño de página mínimo es de 4096 bytes. [una]

El soporte para este modo está presente en la mayoría de los procesadores de 32 y 64 bits. Este modo es clásico para casi todos los sistemas operativos modernos, incluidos Windows y la familia UNIX . El uso generalizado de dicho modo comenzó con el procesador VAX y el sistema operativo VMS desde finales de la década de 1970 (según algunas fuentes, la primera implementación). En la familia x86, el soporte ha aparecido desde la generación 386, que también es la primera generación de 32 bits.

Tareas a resolver

Conceptos

La dirección utilizada en el código de máquina, es decir, el valor del puntero, se denomina "dirección virtual".

La dirección que el procesador pone en el bus se denomina "dirección lineal" (que luego se convierte en una dirección física).

La entrada de la tabla de páginas normalmente contiene la siguiente información:

El número de registros en una tabla es limitado y depende del tamaño del registro y del tamaño de la página. Se utiliza una organización de tablas de varios niveles, a menudo de 2 o 3 niveles, a veces de 4 niveles (para arquitecturas de 64 bits).

En el caso de 2 niveles, se utiliza un "catálogo" de páginas, que almacena entradas que apuntan a las direcciones físicas de las tablas de páginas . Las tablas contienen registros que apuntan a páginas de datos.

Cuando se utiliza una organización de 3 niveles, se agrega un superdirectorio que contiene entradas que apuntan a varios directorios.

Los bits superiores de la dirección virtual indican el número de la entrada en el directorio, los del medio indican el número de la entrada en la tabla, los bits inferiores (la dirección dentro de la página) van a la dirección física sin traducción.

El formato de las entradas de la tabla, su tamaño, el tamaño de la página y la organización de las tablas dependen del tipo de procesador y, a veces, también de su modo de funcionamiento.

Históricamente, x86 ha utilizado PTE de 32 bits, direcciones virtuales de 32 bits, páginas de 4 KB, 1024 entradas de tabla, tablas de dos niveles. Los 10 bits superiores de la dirección virtual son el número de entrada en el directorio, los 10 siguientes son el número de entrada en la tabla, los 12 inferiores son la dirección dentro de la página.

A partir del Pentium Pro, el procesador admite páginas de 4 MB. Sin embargo, para que el sistema y los programas que se ejecutan en él utilicen páginas de este tamaño, la tecnología de páginas de 4 MB (páginas enormes) debe estar habilitada correctamente y la aplicación debe configurarse para utilizar páginas de este tamaño.

El procesador x86 en modo PAE (extensión de dirección física) y en modo x86_64 (modo largo) utiliza PTE de 64 bits (de los cuales no se utilizan realmente todos los bits de dirección física, desde 36 en PAE hasta 48 en algunos x86_64), 32 bits direcciones virtuales, páginas de 4 KB, 512 entradas de tabla, tablas de tres niveles con cuatro directorios y cuatro entradas de superdirectorio. Los 2 bits superiores de la dirección virtual son el número de la entrada en el superdirectorio, los 9 bits siguientes están en el directorio, los 9 bits siguientes están en la tabla. La dirección física del directorio o superdirectorio se carga en uno de los registros de control del procesador .

Cuando se usa PAE , se usan páginas de 2 MB en lugar de páginas grandes de 4 MB. Véase también PSE .

En la arquitectura x86_64 es posible utilizar páginas de 4 kilobytes (4096 bytes), 2 megabytes y (en algunos AMD64) 1 gigabyte.

Si el acceso a la memoria no se puede traducir a través de la TLB , entonces el microcódigo del procesador accede a las tablas de páginas e intenta cargar el PTE desde allí en la TLB. Si los problemas persisten después de tal intento, entonces el procesador ejecuta una interrupción especial llamada “ fallo de página ” (fallo de página). El controlador de esta interrupción se encuentra en el subsistema de memoria virtual del kernel del sistema operativo.

Algunos procesadores (MIPS) no tienen microcódigo para acceder a la tabla y generan una falla de página inmediatamente después de una búsqueda fallida en el TLB, el acceso a la tabla y su interpretación ya están asignados al manejador de fallas de página. Esto priva a las tablas de páginas del requisito de ajustarse a un formato codificado de forma rígida a nivel de hardware.

Causas de fallo de página (fallo de página ):

El controlador de fallas del kernel puede cargar la página deseada desde un archivo o desde el área de intercambio (ver intercambio ), puede crear una copia de solo lectura de la página disponible para escritura, o puede generar una excepción (en términos de UNIX, la señal SIGSEGV ) en este proceso.

Cada proceso tiene su propio conjunto de tablas de páginas . El registro del directorio de páginas se vuelve a cargar en cada cambio de contexto de proceso . También es necesario restablecer la parte de la TLB que se aplica a este proceso.

En la mayoría de los casos, el kernel del sistema operativo se coloca en el mismo espacio de direcciones que los procesos, y los 1 o 2 gigabytes superiores del espacio de direcciones de 32 bits de cada proceso están reservados para él. Esto se hace para evitar cambiar las tablas de páginas al entrar y salir del núcleo. Las páginas del kernel están marcadas como inaccesibles para el código de modo de usuario.

La memoria de la región del kernel suele ser exactamente la misma para todos los procesos, pero algunas subregiones de la región del kernel (por ejemplo, la región de Windows donde residen el subsistema de gráficos y el controlador de video) pueden ser diferentes para diferentes grupos de procesos (sesiones).

Dado que la memoria del kernel es la misma para todos los procesos, no es necesario recargar los TLB correspondientes después de un cambio de proceso. Para esta optimización, x86 admite el indicador "global" en el PTE.

Archivos mapeados en memoria

El controlador de fallas de página en el kernel puede leer la página dada del archivo.

Esto lleva a la posibilidad de una fácil implementación de archivos mapeados en memoria. Conceptualmente, esto es lo mismo que asignar memoria y leer en ella una parte de un archivo, con la diferencia de que la lectura se realiza implícitamente “a la carta”, expresada por un fallo de página al intentar acceder a ella.

La segunda ventaja de este enfoque es, en el caso de una pantalla de solo lectura, compartir la misma memoria física entre todos los procesos que muestran un archivo determinado (cada proceso tiene su propia memoria asignada).

La tercera ventaja es la capacidad de "descartar" algunas de las páginas asignadas sin cambiarlas por el espacio de intercambio necesario para la memoria asignada. En el caso de una necesidad repetida de una página, se puede volver a cargar rápidamente desde el archivo.

La cuarta ventaja es la no utilización de la memoria caché del disco en este modo, lo que supone un ahorro en la copia de datos de la memoria caché a la región solicitada. Las ventajas de una caché de disco, que optimiza operaciones de pequeño tamaño, así como la lectura repetida de los mismos datos, desaparecen por completo al leer páginas enteras, y más aún grupos de páginas, quedando la desventaja de la copia extra obligatoria.

Los sistemas operativos Windows y UNIX utilizan archivos asignados en memoria para cargar módulos ejecutables y bibliotecas dinámicas. También son utilizados por la utilidad grep de GNU para leer el archivo de entrada, así como para cargar fuentes en varios subsistemas gráficos.

Página y segmento de memoria virtual

Una gran ventaja de la memoria virtual paginada en comparación con la segmentada es la ausencia de punteros "cerca" y "lejos".

La presencia de tales conceptos en la programación reduce la aplicabilidad de la aritmética de punteros y conduce a grandes problemas con la portabilidad del código desde/hacia tales arquitecturas. Así, por ejemplo, una parte importante del software de código abierto se desarrolló originalmente para plataformas de 32 bits sin segmentos con memoria de página y no se puede transferir a arquitecturas de segmentos sin una reelaboración seria.

Además, las arquitecturas de segmento tienen el problema más difícil SS != DS, que fue ampliamente conocido a principios de la década de 1990 en la programación bajo versiones de Windows de 16 bits. Este problema genera dificultades en la implementación de bibliotecas dinámicas, debido a que tienen sus propios DS y SS del proceso actual, lo que lleva a la imposibilidad de usar punteros "cercanos" en ellos. Además, tener su propio DS en las bibliotecas requiere parches (MakeProcInstance) para establecer el valor de DS correcto para las devoluciones de llamada desde la biblioteca a la aplicación que realiza la llamada.

Memoria virtual y caché de disco

: de

La compatibilidad con archivos asignados en memoria requiere que el kernel del sistema operativo admita la estructura "un conjunto de páginas físicas que contienen segmentos de un archivo dado". El mapeo de un archivo en la memoria se realiza llenando las entradas de la tabla con enlaces a páginas de una estructura determinada.

Es bastante obvio que esta estructura es un caché de disco listo para usar. Usarlo como caché también resuelve el problema de coherencia entre un archivo de lectura/escritura y un archivo mapeado en memoria.

Por lo tanto, las rutas de E/S almacenadas en caché a un archivo de disco (FsRtlCopyRead en Windows y generic_file_read() en Linux) se implementan como copias de datos en páginas físicas asignadas a un archivo.

Esta organización de caché es la única en Windows, este sistema operativo no tiene un caché de disco de bloque clásico en absoluto. Los metadatos del sistema de archivos se almacenan en caché creando archivos falsos (IoCreateStreamFileObject) y creando un caché de página para ellos.

Consideraciones de seguridad

Inicialmente, la arquitectura x86 no tenía un indicador de "página no ejecutable" ( NX ).

El soporte para esta bandera apareció en la arquitectura x86 como parte del modo PAE (Physical Address Extension) en la generación Pentium 4, bajo una gran presión de los especialistas en seguridad (ver los archivos NTBugTraq). Establecer este indicador en las páginas de pila y montón permite implementar la protección de ejecución de datos de hardware, lo que hace imposible que funcionen muchos tipos de malware, incluida, por ejemplo, la explotación maliciosa de muchas fallas en Internet Explorer (falla de diciembre de 2008, consulte el conocimiento de MS base no se puede usar si DEP está habilitado ).

La compatibilidad con Windows PAE , que permite la protección de la ejecución de datos , se introdujo en Windows 2000 y está habilitada de manera predeterminada en las versiones de servidor de Windows y deshabilitada en las versiones de cliente.

Soporte para memoria de más de 4 GB en Windows

Los dispositivos PCI, incluida la memoria de la tarjeta de video, generalmente solo admiten direcciones de 32 bits. Por lo tanto, se les debe dar direcciones físicas por debajo de la marca de 4 GB. Esta "apertura" reduce la cantidad de memoria física visible por debajo de la marca de 4 GB a aproximadamente 3,2 GB. El controlador reasigna el resto de la memoria física por encima de la marca de 4 GB.

Cualquier acceso a la memoria por encima de 4 GB (es decir, más de aproximadamente 3,2 GB) requiere que el controlador (es decir, el puente norte del conjunto de chips) admita esta configuración. Los conjuntos de chips modernos (por ejemplo, Intel G33) tienen ese soporte.

También requiere una configuración de BIOS llamada reasignación de memoria que mapea la región [3,2...4] a [4...4,8].

El procesador x86 fuera del modo PAE utiliza direcciones físicas y PTE de 32 bits, es decir, no dispone de más de 4 GB (consulte también PSE-36 para conocer una forma de evitar esta limitación). Por lo tanto, para utilizar más de 3,2 GB de memoria en un sistema operativo, debe ser compatible con PAE. Para Windows, esta es la opción de arranque; para Linux, esta es la opción de compilación del kernel.

Además, Microsoft ha deshabilitado por la fuerza la compatibilidad con direcciones físicas de más de 4 GB por motivos políticos y de marketing en los siguientes sistemas operativos:

La compatibilidad con direcciones físicas superiores a 4 GB está disponible en las siguientes versiones:

Por lo tanto, para usar una memoria superior a 3,2 GB en Windows, necesita:

Sin embargo, incluso en una versión "reducida" de Windows que no admite direcciones de más de 4 GB, tiene sentido usar siempre PAE porque (ver arriba) la Protección de ejecución de datos ( DEP ) también requiere PAE. Habilitar PAE puede hacer que una pequeña parte del software deje de funcionar, como el emulador de Windows Mobile. Según la versión oficial de Microsoft, la introducción de un límite de espacio de direcciones de 4 GB se debe a que algunos controladores de dispositivos faltan o tienen un soporte deficiente para el espacio de direcciones de 36 bits, esto debe tenerse en cuenta, debido a limitaciones de hardware o inadecuado controladores, es imposible habilitar PAE en versiones que admiten direcciones físicas superiores a 4 GB. La capacidad de habilitar o deshabilitar PAE no depende de los controladores, pero si el controlador de algún equipo PCI antiguo no admite correctamente las direcciones físicas que no caben en 32 bits, entonces este dispositivo no funcionará correctamente y puede hacer que toda la computadora falle. congelar.

Véase también

Notas

  1. Manual del desarrollador de software de las arquitecturas Intel® 64 e IA-32 Volumen 3 (3A, 3B, 3C y 3D): Guía de programación del sistema (diciembre de 2016). Consultado el 21 de diciembre de 2019. Archivado desde el original el 19 de mayo de 2020.  (Inglés)

Enlaces