stringtranslate.com

Tabla de descriptores globales

La tabla de descriptores globales ( GDT ) es una estructura de datos utilizada por los procesadores de la familia Intel x86 a partir del 80286 para definir las características de las diversas áreas de memoria utilizadas durante la ejecución del programa, incluida la dirección base, el tamaño y privilegios de acceso como ejecutabilidad y escriturabilidad. Estas áreas de memoria se denominan segmentos en la terminología de Intel.

Descripción

La GDT es una tabla de entradas de 8 bytes. Cada entrada puede hacer referencia a un descriptor de segmento , segmento de estado de tarea (TSS), tabla de descriptores locales (LDT) o puerta de llamada . Las puertas de llamada se diseñaron para transferir el control entre niveles de privilegios x86, aunque este mecanismo no se utiliza en la mayoría de los sistemas operativos modernos.

También hay una tabla de descriptores locales (LDT). Se pueden definir múltiples LDT en el GDT, pero solo uno está actual a la vez: generalmente asociado con la tarea actual. Mientras que la LDT contiene segmentos de memoria que son privados para un proceso específico, la GDT contiene segmentos globales. Los procesadores x86 tienen funciones para cambiar automáticamente el LDT actual en eventos específicos de la máquina, pero no tienen funciones para cambiar automáticamente el GDT.

Cada acceso a la memoria realizado por un proceso siempre pasa por un segmento. En el procesador 80386 y posteriores, debido a los límites y compensaciones de los segmentos de 32 bits , es posible hacer que los segmentos cubran toda la memoria direccionable, lo que hace que el direccionamiento relativo al segmento sea transparente para el usuario.

Para hacer referencia a un segmento, un programa debe utilizar su índice dentro de GDT o LDT. Dicho índice se denomina selector de segmento (o selector). El selector debe cargarse en un registro de segmento para poder utilizarse. Aparte de las instrucciones de máquina que permiten establecer/obtener la posición del GDT y de la tabla de descriptores de interrupciones (IDT), en la memoria, cada instrucción de máquina que hace referencia a la memoria tiene un registro de segmento implícito, ocasionalmente dos. La mayoría de las veces, este registro de segmento se puede anular agregando un prefijo de segmento antes de la instrucción.

Al cargar un selector en un registro de segmento se lee la entrada GDT o LDT en el momento de cargarse y se almacenan en caché las propiedades del segmento en un registro oculto. Las modificaciones posteriores al GDT o LDT no tendrán efecto hasta que se vuelva a cargar el registro de segmento.

Formato de un descriptor de segmento

GDT en 64 bits

El GDT todavía está presente en modo de 64 bits; Se debe definir una GDT, pero generalmente nunca se modifica ni se utiliza para la segmentación. El tamaño del registro se ha ampliado de 48 a 80 bits y los descriptores de 64 bits son siempre "planos" (por lo tanto, de 0x0000000000000000 a 0xFFFFFFFFFFFFFFFF). Sin embargo, las bases de FS y GS no están restringidas a 0 y continúan usándose como punteros al desplazamiento de elementos como el bloque de entorno de proceso y el bloque de información de subprocesos.

Si se borra el bit de Sistema (cuarto bit del campo Acceso), el tamaño del descriptor es de 16 bytes en lugar de 8. Esto se debe a que, aunque se ignoran los segmentos de código/datos, los TSS no, pero el puntero TSS se puede ignorar. Tiene una longitud de 64 bits y, por lo tanto, el descriptor necesita más espacio para insertar la palabra clave más alta del puntero TSS.

Las versiones de 64 bits de Windows prohíben la conexión de GDT; intentar hacerlo hará que la máquina realice una comprobación de errores . [1]

Tabla de descriptores locales

Una tabla de descriptores locales ( LDT ) es una tabla de memoria utilizada en la arquitectura x86 en modo protegido y que contiene descriptores de segmentos de memoria , al igual que la GDT: inicio de dirección en la memoria lineal, tamaño, ejecutabilidad, capacidad de escritura, privilegio de acceso, presencia real en la memoria, etc.

Las LDT son hermanas de la Tabla de descriptores globales (GDT) y cada una define hasta 8192 segmentos de memoria accesibles para los programas; tenga en cuenta que, a diferencia de la GDT, la entrada cero es una entrada válida y se puede utilizar como cualquier otra entrada LDT. También tenga en cuenta que, a diferencia del GDT, el LDT no se puede utilizar para almacenar ciertas entradas del sistema: TSS o LDT. Sin embargo, las puertas de llamadas y las puertas de tareas están bien.

Historia

En procesadores x86 que no tienen funciones de paginación, como el Intel 80286 , el LDT es esencial para implementar espacios de direcciones separados para múltiples procesos. Generalmente habrá una LDT por proceso de usuario, que describe la memoria privada, mientras que la GDT describirá la memoria compartida y la memoria del kernel . El sistema operativo cambiará el LDT actual cuando programe un nuevo proceso, usando la instrucción de máquina LLDT o cuando use un TSS . Por el contrario, el GDT generalmente no se cambia (aunque esto puede suceder si se ejecutan monitores de máquinas virtuales como VMware en la computadora).

La falta de simetría entre ambas tablas se ve subrayada por el hecho de que el LDT actual se puede activar automáticamente en ciertos eventos, en particular si se utiliza la multitarea basada en TSS , mientras que esto no es posible para el GDT. El LDT tampoco puede almacenar ciertos tipos privilegiados de segmentos de memoria (por ejemplo, TSS). Finalmente, la LDT en realidad se define mediante un descriptor dentro de la GDT, mientras que la GDT se define directamente mediante una dirección lineal.

La creación de memoria compartida a través de GDT tiene algunos inconvenientes. Cabe destacar que dicha memoria es visible para todos los procesos y con igualdad de derechos. Para restringir la visibilidad y diferenciar la protección de la memoria compartida, por ejemplo para permitir solo el acceso de solo lectura para algunos procesos, se pueden usar entradas LDT separadas, apuntadas a las mismas áreas de memoria física y creadas solo en las LDT de los procesos que han solicitado acceso a un área de memoria compartida determinada.

Las entradas LDT (y GDT) que apuntan a áreas de memoria idénticas se denominan alias . Los alias también suelen crearse para obtener acceso de escritura a segmentos de código: no se puede utilizar un selector ejecutable para escribir. (Los programas en modo protegido construidos en el llamado modelo de memoria pequeña , donde todo está ubicado en el mismo segmento de memoria, deben usar selectores separados para código y datos/pila, lo que hace que ambos selectores también sean técnicamente "alias".) En el caso de En el GDT, también se crean alias para obtener acceso a segmentos del sistema como los TSS.

Los segmentos tienen un indicador "Presente" en sus descriptores, lo que permite eliminarlos de la memoria si surge la necesidad. Por ejemplo, los segmentos de código o los segmentos de datos no modificados se pueden desechar y los segmentos de datos modificados se pueden intercambiar en el disco. Sin embargo, debido a que segmentos enteros deben operarse como una unidad, es necesario limitar su tamaño para garantizar que el intercambio pueda realizarse de manera oportuna. Sin embargo, utilizar segmentos más pequeños y más fácilmente intercambiables significa que los registros de segmento deben recargarse con mayor frecuencia, lo que en sí mismo es una operación que requiere mucho tiempo.

Uso moderno

El microprocesador Intel 80386 introdujo la paginación : asignación de páginas de memoria física separadas (en sí mismas unidades de memoria muy pequeñas) en las mismas direcciones virtuales, con la ventaja de que la paginación del disco es mucho más rápida y eficiente que el intercambio de segmentos. Por lo tanto, los sistemas operativos x86 modernos de 32 bits utilizan muy poco el LDT, principalmente para ejecutar código heredado de 16 bits .

Si es necesario ejecutar código de 16 bits en un entorno de 32 bits mientras se comparte memoria (esto sucede, por ejemplo, cuando se ejecutan programas OS/2 1.x en OS/2 2.0 y posteriores), el LDT debe escribirse de tal manera que cada La dirección plana (paginada) también tiene un selector en el LDT (normalmente esto da como resultado que el LDT se llene con entradas de 64 KiB). Esta técnica a veces se denomina mosaico LDT . El tamaño limitado del LDT significa que el espacio de direcciones virtuales planas debe limitarse a 512 megabytes (8191 x 64 KiB); esto es lo que sucede en OS/2, aunque esta limitación se solucionó en la versión 4.5. También es necesario asegurarse de que los objetos asignados en el entorno de 32 bits no superen los límites de 64 KiB; esto genera algo de desperdicio de espacio de direcciones.

Si el código de 32 bits no tiene que pasar objetos de memoria arbitrarios al código de 16 bits, por ejemplo, presumiblemente en la emulación OS/2 1.x presente en Windows NT o en la capa de emulación de Windows 3.1 , no es necesario limitar artificialmente la Tamaño del espacio de direcciones de 32 bits.

Referencias

  1. ^ "Política de parches para sistemas basados ​​en x64". 8 de octubre de 2009. Archivado desde el original el 19 de enero de 2022 . Consultado el 11 de diciembre de 2020 . Si el sistema operativo detecta una de estas modificaciones o cualquier otro parche no autorizado, generará una verificación de errores y apagará el sistema.

enlaces externos