Moving Grave6:(MG#_6.X03):16/10/1996 << Back To Moving Grave6


INTRODUCTION TO ┌─┐─┬─∙─∙ ∙ ∙ (*) PROTECTED MODE PROGRAMMING (*) ∙ ∙ ∙──┬─┌─┐ └─┼───────────────────────────────────────────────────────────────────────┼─┘ ├─│─┘ Writen By Stone Shadow └─:─┤ ├─:─┐ Copyright (c) 1996 - 97 By COEAC System Development. ┌─│─┤ ┌─┼───────────────────────────────────────────────────────────────────────┼─┐ └─┘─┴─ ∙∙ ∙ ∙ Creatures Of Electronic Anti Christ ∙ ∙ ∙∙ ─┴─└─┘ Los procesadores 80386/80486/80586 pueden operar en 3 modos distintos, Real, Protegido y Virtual 8086 (V86). @ El modo Real es el que todos conocemos, con sus limites de memoria convencional y demas, que desaprovecha gran cantidad del poder de los chips actuales. @ El Protegido es un modo sin limites de memoria, que permite hacer multitasking y aprovecha todo el poder de los chips de 32 bits. @ El V86 permite encapsular multiples sistemas trabajando en modo real en una misma maquina controlados por el modo Protegido. ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- - Entrando a la Dimension Desconocida - ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- Muy bien, el Modo Protegido es un mundo muy distinto al modo Real. Los registros que conocemos todavia estan (salvo que aparecen varios mas) asi que no se preocupen... Lo que cambia es el modo en que el CPU trata a la memoria. En el modo protegido hay 5 registros de segmento, los cuales son: CS Code Segment DS Data Segment ES Extra Segment FS Additional Segment GS Additional Segment De echo, estos registros se usan de una manera diferente a la normal, y para evitar confusiones se los llaman SELECTOR REGISTERS. Cuando se habla de 'Segmentos' en el modo protegido se refiere exclusivamente a un cacho de memoria en alguna parte de la ram, o sea un bloque y segmento son una misma cosa... Ya no se usa mas la forma 'segmento:offset' para referirnos a una poscicion en memoria, sino que se usa 'SELECTOR:OFFSET' para ello. Y creanme entre los antiguos Segmentos y los nuevos Selectors hay una muy gran diferencia, la cual empezare a explicar en este momento... Los Selectors (como los segmentos que conocemos) estan formados de 16 bits, pero sus bits tiene un significado especial: ------------------------------- F E D C B A 9 8 7 6 5 4 3 2 1 0 ------------------------------- x x Requested Privilege Level x Table Indicator x x x x x x x x x x x x x Index El Requested Privilege Level es el nivel de privilegio que usa en ese momento el Selector (acostumbrence a decirles selectors de ahora en mas). Y en base al nivel que poseen, el sistema operativo le entrega (a las rutinas que los estan usando), diferentes grados de accesso a los recursos del sistema (tiempo de procesador, etc). Esto es vital para que la maquina pueda hacer multitasking en forma exitosa y segura. Hay cuatro niveles (0->3), el 0 es acceso absoluto y de ahi en mas decrece proporcionalmente. El Index puede tener un valor de 0 a 8191 y es usado como puntero a un DESCRIPTOR que reside en una tabla de referencia llamada TABLA DESCRIPTORA. Hay 3 tipos de Tablas Descriptoras (GDT, LDT, IDT), hablare de ellas en un momento. El Table Indicator que se compone de 1 bit especifica a que clase de Tabla Descriptora apunta el selector. Si es 0 -> GDT, si es 1 -> LDT. ---- TABLAS DESCRIPTORAS ----- Tipos Descripcion Registros GDT Global descriptor table GDTR LDT Local descriptor table LDTR IDT Interrupt descriptor table IDTR Como dije antes, estas tablas son tablas de referencia. Contienen elementos llamados DESCRIPTORES, los cuales son bloques de informacion que 'apuntan y representan' porciones de la memoria del ordenador (No se inquieten, los describire a full mas adelante). La GDT contiene descriptores usados para describir el entorno (o sea la memoria) de todo el sistema. La LDT se utiliza para describir el entorno de un programa especifico y la IDT es usada para el manejo de interrupciones y no puede ser accedida mediante un selector. La IDT es analoga a la Interrupt Vector Table que reside en memoria baja en el modo real (nuestra vieja y conocida amiga, snifff... que nostalgia). Un sistema solo puede tener una GDT y una IDT, pero puede tener muchas diferentes LDTs, una por c/programa que trabaja en memoria (si trabaja en modo v86 puede tambien tener muchas IDTs). Como estas tablas pueden residir casi en cualquier parte de la memoria, la direccion inicial de c/una la encontramos en registros especiales de la CPU llamdos GDTR, LDTR e IDTR. Bueno, a todo esto ustedes querran conocer bien despues de todo que mierda es un DESCRIPTOR, no?... ------ DESCRIPTORES ------ Un Descriptor es una estructura un poco quisquillosa formada por 8 bytes. Estos 8 bytes representan un bloque determinado de memoria y especifican la direccion base, el tamaño y otros atributos del bloque. Tanto en la GDT y en la LDT puede haber hasta 8192 descriptores. (Nota: el primer descriptor en la GDT no puede ser accedido por el cpu). Hay 3 tipos diferentes de Descriptores: (1) Segment Descriptors (2) System Segment Descriptors & System Gate Descriptors El orden de los datos en un Descriptor depende del tipo de procesador que uno este usando, en los 80286 tienen una estructura diferente que en los 80386 y 80486. Por razones de practicidad voy a mostrar la estructura de estos ultimos, que creo es la que nos interesa (nota: el 80586 estoy casi seguro que por razones de compatibilidad usa la misma estructura que en los procesadores 80386/80486). Los Descriptores de Segmento (1) son los mas usados, y por lo tanto la 'llave maestra' hacia una porcion de memoria. ( Nota, no pasen el diagrama de abajo por alto, prestenle mucha atencion! Ahh, y otra cosa mas... Se me lavan los dientes despues de comer, OK? ) Cada Descriptor contiene en sus 8 bytes: ╔══════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ * BASE ADDRESS -----> Es la direccion inicial del bloque en memoria. ║ ║ [ Bytes 2-3 y 5-6 ] ║ ╠══════════════════════════════╗ (32 bits) ║ ║ ╚═══════════════════════════════════════════║ ║ * LIMIT -------------> Especifica el tamaño del bloque. ║ ║ [ Bytes 0-1 y el primer nibble del Byte 7] ║ ╠══════════════════════════════╗ (20 bits) ║ ║ ╚═══════════════════════════════════════════║ ║ * ACCESS RIGHTS -----> Indica diferentes atributos del bloque de memoria.║ ║ [ Byte 5 ] ║ ╠═╗ ╔════════════╗ (8 bits) ║ ║ ┌───────────────┐ ╚═══════════════════════════════════════════╣ ║ 7 6 5 4 3 2 1 0 ║ ║ │└─┬─┘│└───┬───┘ ║ ║ │ │ │ │ ║ ║ │ │ │ └── Type field > Indica algunos atributos del segmento ║ ║ │ │ │ ─────┬──── de memoria que describe. Estos atributos ║ ║ │ │ │ │ pueden ser: ║ ║ │ │ │ │ ┌┬─ ║ ║ │ │ │ │ ├┘ xxxx ║ ║ │ │ │ └──┤ 1 = El segmento ha sido accedido. ║ ║ │ │ │ │ 0 = El segmento no ha sido accedido. ║ ║ │ │ │ │ 000 = Normal read-only Data Seg.║ ║ │ │ │ │ 001 = Normal read/write Data Seg.║ ║ │ │ │ │ 010 = Expand-down read-only Data Seg.║ ║ │ │ │ │ 011 = Expand-down read/write Data Seg.║ ║ │ │ │ │ 100 = Execute-only no adaptado Code Seg.║ ║ │ │ │ │ 101 = Readable no adaptado Code Seg.║ ║ │ │ │ │ 110 = Execute-only adaptado Code Seg.║ ║ │ │ │ ├┐ 111 = Readable adaptado Code Seg.║ ║ │ │ │ └┴─ ║ ║ │ │ └─────── Seg field > Especifica si esta seteado a 1 que el ║ ║ │ │ ───────── descriptor es del tipo Segment Descriptor. ║ ║ │ └────────── DPL field > Especifica el nivel de acceso nescesario ║ ║ │ ───────── para usar el ese descriptor de segmento. ║ ║ │ Si tratas de acceder a un descriptor que ║ ║ │ tiene mas nivel que tu Code Selector (o sea║ ║ │ el segmento de codigo de tu programa) ocurr║ ║ │ una falla. ║ ║ └───────────── Pres field > Indica si el segmento al que queres ║ ║ acceder esta en memoria (seteado a 1) o ║ ║ si la data fue 'spooleada' al disco rigido.║ ║══════════════════════════════╗ ║ ║ ╚═══════════════════════════════════════════╣ ║ * SPECIAL BITS ------> Indican diferentes modos de operacion. ║ ║ [El ultimo nibble del Byte 7] ║ ╠═══╗ ╔══════════════════╗ (4 bits) ║ ║ 7 6 5 4 ╚═══════════════════════════════════════════╣ ║ │ │ │ │ ║ ║ │ │ │ │ ║ ║ │ │ │ └───── Reserved (En una palabras por ahora no se usa!) ║ ║ │ │ └─────── O > Ohhhh... Que sera?...;-) ║ ║ │ └───────── D > Tambien se lo llama B (de Big) y es el interruptor ║ ║ │ hacie el procesamiento en 32 bits. Si el bit esta ║ ║ │ apagado los operandos y modos de direccionamiento ║ ║ │ estan limitados a 16 bits (o sea que no podemos ║ ║ │ trabajar con un descriptor usando un offset de mas ║ ║ │ de 16 bits por ejemplo), si esta prendido todo ║ ║ │ el poder de los 384/486 esta a nuestra dispocision ║ ║ │ y con ellos el direccionamiento de offsets de ║ ║ │ 32 hermosos y gloriosos bits...(Sorry, me exite). ║ ║ │ ║ ║ └─────────── G > Indica la granularidad del campo LIMIT. Si este ║ ║ byte es 0 el valor en LIMIT la maquina lo proscesa ║ ║ en bytes (o sea que al ser de 20 bits tiene un ║ ║ max de 1 Mega) pero Ay Dios si el bit es 1, la ║ ║ maquina proscesa el valor en LIMIT en pages (c/una ║ ║ son 4k) o sea que el max de bytes que puede ║ ║ tener un segmento seria el de 4,294,963,200 bytes ║ ║ (a mi me parece suficiente y a ustedes?) ║ ║ ║ ╚══════════════════════════════════════════════════════════════════════════╝ Aqui abajo hay un diagrama mas resumido de los Descriptores, para que nos ayude a entender mejor su estructura: (bits de c/byte) F E D C B A 9 8 7 6 5 4 3 2 1 0 ┌───────────────────────────────┐ │ limit │ Byte 1 │ │ Byte 2 ├───────────────────────────────┤ │ base address (low) │ Byte 3 │ │ Byte 4 ╔ ├─┬───┬─┬───────┬───────────────┤ ╔═══╣ │ │ │ │ │ base address │ Byte 5 ║ ║ │P│DPL│S│ type │ (middle) │ Byte 6 ║ ╚ ├─┴─┴─┴─┴─┴─┴─┴─┼─────┬─┬───────┤ ║ │ base address │ │▓│ limit │ Byte 7 ║ │ (high) │G D O│▓│ (high)│ Byte 8 ║ └───────────────┴─┴─┴─┴─┴───────┘ ║ ╚══╦══╝ ║ ║ ╚══ Access Right Bits ╚═══ Especial bits Sipe, supongo que ya se dieron cuenta porque al referirme a los descriptores lo hacia como 'estructuras quisquillosas'...Jejeje... Porque mierda estas estructuras tienen la info en una forma tan desordenada en vez de tener la base address, el limit y demas partes en forma consecutiva ???? Bhue, esta vez no tiene que ver con una noche de farra en los laboratorios de los diseñadores... Es asi para mantener mal o bien un formato que nacio con la 80286, en esta maquina los descriptores eran de mismo tamaño (8 bytes) que en las otras pero con 16 bits al pedo (sin usar)... Adivinen donde acomodaron los muchachos de Intel los bits extra que necesitaban para sus nuevas maquinas?... JEJe... Qui li vamos a hacer!... --- System Segment & System Gate Descriptors --- Se acuerdan de los Access Rights Bits ??... No ?!!!... Ahhh, les convenia... Pues cuando el bit 4 (Seg field) esta en 0 el descriptor toma un sentido especial para el sistema, y cobran otro significado los valores en el Type field: xxxx 1 0001 Task State Segment 2 0010 Local Descriptor Table (LDT) 3 0011 Busy Task State Segment 4 0100 Call Gate 5 0101 Task Gate 6 0110 Interrupt Gate 7 0111 Trap Gate Ahora el Descriptor describe un Segmento de Sistema o una Compuerta del Systema (depende del valor en el Type field). Los System Segment Descriptors son usados para direccionar diferentes tablas de sistema y task management. Por ejemplo, si en el type field seteamos el valor 2 (0010), un Descriptor (en la GDT) apuntara a una LDT usada por un programa especifico. De esta manera los programas pueden controlar su propio entorno (memoria) de una manera distinta a otros programas que pueden estar corriendo en el sistema. Los System Gate Descriptors (Type 4 a 7) son usados para transferir el control entre diferentes procesos. CONTINUARA... ---/ Moving Grave 6 [MG#6] /--- ---/ COEAC Group. /--- -= Written by Stone Shadow =-