Story Transcript
• Modo Virtual del 8086 El 80386 soporta la ejecución de uno o más programas diseñados para el 8086, 8088, 80186 u 80188 en un entorno en modo protegido. Un programa de 8086 corre en este entorno como parte de una tarea V86 (virtual 8086). Bajo este modo de funcionamiento puede haber no sólo varias tareas V86 ejecutándose simultáneamente, sino que también se pueden ejecutar varias tareas en 80386. Cada tarea se va a ejecutar en una máquina virtual como se comentó en el capítulo 1, que no interactuará con el resto de las máquinas virtuales. Este mecanismo de independencia entre las distintas tareas es ofrecida por el hardware 80386, ahora el programador se ha de preocupar por crear el software necesario para controlar correctamente cada una de estas máquinas virtuales. Todo este software que ayuda a implementar una máquina virtual se denomina monitor de V86. Una tarea V86 genera las direcciones de memoria como se hacen en el modo real (segmento*16 + desplazamiento), por tanto, se salta el mecanismo de segmentación que ofrece el modo protegido a través de la GDT, para generar las direcciones. Hay que mencionar que una tarea que fue diseñada para el modo real del 8086 puede ejecutarse casi sin problemas en el modo V86. En algunos casos algún conjunto de instrucciones pueden diferir ligeramente la ejecución en V86 y en modo real, por lo que un Multitasker ha de tener presencia de ello, a fin de evitar una ejecución errónea de la tarea V86. • Estructura de una tarea V86 Una tarea V86 consiste en un programa realizado para el 8086 y que es ejecutado bajo el 80386 a través de un programa monitor que controla todos sus pasos. Las tareas V86 son identificadas por el 80386 a través del campo VM encontrado en su registro EFLAGS. Una tarea con VM=1 será tratada por el 80386 como una tarea V86. El procesador conmuta a modo V86 para ejecutar una tarea V86 y luego conmuta a modo protegido para ejecutar el código del programa monitor u otra tarea 80386. Para ejecutar con éxito el modo V86, un programa 8086 necesita lo siguiente: • Un monitor de V86. • Servicios del sistema operativo. El monitor de V86 es un código en modo protegido del 80386 que se ejecuta en el nivel de prioridad cero. El monitor consiste principalmente en procedimientos de inicialización y gestión de excepciones. El monitor necesita tener acceso a todo el espacio de memoria de la tarea V86 para poder examinar su tabla de vectores de interrupción u otras partes del programa V86. Hay dos formas de implementar el monitor para un Multitasker bajo MS−DOS utilizando el modo V86: • El monitor de V86 del Multitasker realiza llamadas a los servicios que ofrece el MS−DOS realizando diversas estrategias. • El monitor de V86 del Multitasker implementa todos los servicios que ofrece el MS−DOS. La primera de las dos opciones es la que se ha escogido en DMT debido a que la segunda es muy difícil de 1
conseguir, ya que habría que conocer todos los detalles internos de MS−DOS y habría una gran dependencia del software con respecto a la máquina. • Cómo accede una tarea V86 a memoria Cómo hemos comentado anteriormente, una tarea V86 no direcciona la memoria igual que una tarea en modo protegido. Las tareas en modo protegido están ligadas íntimamente a la tabla de descriptores global (GDT) para formar la dirección lineal, que pasará al mecanismo de paginado, siempre que este activo, para formar la dirección física final. Si el mecanismo de paginado no está activo, la dirección lineal obtenida a través de la GDT será la dirección física final. Una tarea V86 no accede a la GDT para obtener la dirección lineal. Esta dirección lineal es conseguida a través de la dirección lógica dada por la tarea V86. Una dirección lógica en V86, al igual que en modo real, está formada por dos pares dados, esto es, segmento:desplazamiento, cuya transformación a lineal se puede dar matemáticamente como segmento*16 + desplazamiento. Veamos un ejemplo de transformación de dirección lógica a lineal desde V86. Si la tarea A intenta acceder a un dato y da la dirección lógica hexadecimal 0A000h:1234h, el 80386 convertirá dicha dirección en 0A000h*16 + 1234h, o lo que es lo mismo, 0A1234h. La dirección lineal obtenida en V86 es usada para acceder al mecanismo de paginado, es decir, dicha dirección dependerá del directorio de páginas y tablas de páginas. Con esto, podemos hacer que una tarea V86 se crea que se está ejecutando en el primer Mbyte de memoria, tal como lo hace un programa DOS, y a través del mecanismo de paginado podemos colocar la tarea V86 en cualquier lugar de la memoria sin que ésta se entere de si la paginación está activa o no. Con esto, podemos tener varias tareas V86 en memoria, cada una de ellas creyendo que se ejecutan en el primer Mbyte de memoria, pero cada una de ellas con un espacio de direcciones físicas diferentes. En la figura 5.1 mostramos gráficamente todo lo expuesto anteriormente. • Gestión de una tarea V86 Un sistema operativo 80386 puede crear una tarea V86 directamente, o puede crear una tarea en modo protegido que se transformará a una tarea V86. Para crear una tarea que empieza su ejecución en modo V86, su TSS debe ser inicializado como sigue: • Poner el bit VM de EFLAGS a 1. • Establecer el campo del selector CS para que al ser desplazado a la izquierda en cuatro lugares (multiplicar por 16), el resultado sea la dirección base lineal del segmento de código inicial de la tarea. 7 Figura 5.1. Tareas V86 en memoria • Establecer el campo IP al punto de entrada de la tarea. • Establecer IOPL a 3 (en el campo EFLAGS) • Poner el campo selector LDT a nulo. • Inicializar el mapa de permiso de E/S para conceder o denegar el acceso a puertos de E/S. En los demás aspectos, la creación de una tarea V86 es idéntica a la creación de una tarea en modo protegido. Cuando el TSS del V86 es la nueva tarea en una conmutación de tarea, el 80386 carga EFLAGS; puesto que VM esta puesto a 1, el 80386 cambia a modo virtual 8086. El procesador interpreta los restantes campos del 2
TSS como contenido de valores para V86 y los carga adecuadamente. La segunda manera de crear una tarea en V86, y es la que se ha utilizado en DMT, es crear una tarea en modo protegido que pasará a ser posteriormente una tarea V86. Para lograr esto, debemos poner en el campo EFLAGS del TSS el bit VM a cero, los registros de segmentos han de contener valores de selectores para la GDT y recargar los demás registros según vayan a ser utilizados. Cuando se produce una conmutación de tarea y se referencia al TSS anterior, el procesador conmuta a modo protegido. La tarea en modo protegido empieza a ejecutarse y posteriormente habrá una instrucción que mete el contenido de EFLAGS en la pila con VM puesto a 1. Luego se introducirá en la pila el valor de CS e IP para la tarea V86 y finalmente ejecutamos la instrucción IRET (retorno de interrupción). El procesador sacará EFLAGS de la pila y al ver que el bit VM está a 1 conmutará a modo virtual 8086 posteriormente sacará el registro CS e IP con valores correctos para el V86. • Interrupciones y excepciones en V86 En modo virtual 8086, el procesador trata interrupciones y excepciones como si estuviese ejecutándose en modo protegido, excepto que el procesador cambia de modo V86 a protegido antes de llamar a la rutina de tratamiento. Cuando al final del tratamiento de la interrupción se ejecuta la instrucción IRET, el procesador volverá a pasar a modo V86 y continuará ejecutando la tarea V86. Cuando ocurre una interrupción o excepción en V86, el procesador mirará la entrada correspondiente según el tipo de interrupción en la IDT. En la IDT encontrará la dirección de un segmento donde se encuentra el tratamiento para dicha interrupción. El procesador almacena a continuación todos los registros del procesador de la tarea V86 en la pila y recarga los registros CS y EIP con la dirección de la rutina de interrupción (los demás registros de segmento serán puestos a cero). En la rutina de tratamiento de interrupción se deberá de poder acceder a la zona de memoria de la tarea V86 que provocó la interrupción, para mirar que instrucción provocó la interrupción y para acceder o manipular datos de la tarea V86. Al final de la rutina de tratamiento de excepción se ha de incrementar el valor de registro IP de la tarea V86 que se encuentra en la pila, para que al hacer el IRET final, se ejecute la instrucción siguiente a la que provocó la excepción. • Cómo se pueden llamar los servicios del DOS desde V86 Un programa de MS−DOS utiliza la instrucción INT n para acceder a los servicios que ofrece el DOS. Una instrucción de esta en modo V86 desembocará en una excepción de protección general si el IOPL de la tarea V86 es menor que 3. Si la tarea V86 posee un IOPL igual a 3, la ejecución de la instrucción INT n llamará a la rutina de tratamiento de excepción que se encuentra en la entrada n de la IDT. No obstante, en DMT no se ha creado una entrada en la IDT para cada tipo de interrupción desde V86, sino que las entradas que se encuentran en la IDT contienen segmentos de nivel de prioridad cero, con lo que cualquier acceso a la IDT desde V86 desembocará en una excepción de protección general. Para tratar todas las llamadas al sistema operativo desde V86, en DMT se ha anclado el monitor V86 en la entrada 13 falta de protección general de la IDT. Así, cualquier excepción por falta de protección el procesador llamará al monitor V86 para que trate dicha excepción. Cuando una tarea V86 ejecuta la instrucción INT n se producirá una falta de protección general, el monitor toma a continuación el control del procesador y examinará la instrucción que provocó tal excepción. El monitor, al observar que se intentaba solicitar un servicio del sistema operativo, colocará en la pila la dirección del servicio solicitado además del registro EFLAGS con VM puesto a 1. Tras hacer esto y varias comprobaciones más, ejecutará la instrucción IRET que tras sacar EFLAGS de la pila y observar que VM está a 1, colocará el procesador en V86 y seguidamente sacará de la pila CS e IP que contendrá la dirección del servicio del sistema operativo solicitado. Cuando en el servicio solicitado se ejecuta la instrucción IRET, el monitor V86 tomará nuevamente el control 3
del procesador, observará que se ha concluido un servicio que fue llamado por él (al ofrecer el servicio a la tarea V86) y devolverá el control a la tarea V86 que solicitó el servicio al MS−DOS. Todo el proceso anterior se puede resumir en los siguientes puntos: • Meter una copia del marco de la pila de la tarea V86 (sus registros de segmento, puntero de pila, EFLAGS y dirección de retorno) en la pila protegida. • Cambiar la dirección de retorno en el marco copiado al punto de entrada del servicio solicitado. • Simular la introducción de la instrucción INT del 8086, de los FLAGS de la tarea V86, CS e IP en la pila de la tarea V86. • Ejecutar una instrucción IRET para cambiar al modo virtual 8086 y transferir al punto de entrada del servicio solicitado. • Una vez que ha concluido el servicio solicitado, se encontrará una instrucción IRET. • El monitor V86 toma nuevamente el control. • El monitor V86 reajusta los valores que se encuentran en la pila para que al hacer un nuevo IRET se pase el control a la tarea V86 que solicitó el servicio. • Incrementa EIP en la pila de la tarea V86 para que apunte a la instrucción siguiente a la que solicitó el servicio, es decir, para saltarse la instrucción INT n. • Ejecutar la instrucción IRET y la tarea V86 tomará nuevamente el control. • Entrada y Salida en V86 En modo protegido, una tarea tiene acceso a un puerto de E/S si su nivel de privilegio es mayor al que hay en el campo IOPL de su registro EFLAGS o también tendrá acceso si en el mapa de bits de E/S del TSS hay un valor 0 para el bit que mapea dicho puerto. Una tarea V86, sin embargo, dependerá sólo del mapa de bits del TSS para acceder a un puerto. Así, una tarea V86, podrá acceder a un puerto específico si en el mapa de bits de su TSS hay un valor 0 para ese puerto. En caso de que una tareaV86 acceda a un puerto de E/S al que no tenga derecho de acceso, el monitor V86 tomará el control sobre dicha tarea y él decidirá que hacer con esa tarea. En el Capitulo 8 se puede observar como en DMT se ha denegado el acceso a las tareas V86 para acceder a diversos puertos de E/S, como por ejemplo a los puertos de la tarjeta de vídeo o a los puertos del DMA. Modo Virtual del 8086 42 37 Dir. Tarea A T. Pag. A Dir. Tarea B T.Pag. B Dir. Tarea C T.Pag. C Tarea A Tarea B Libre Área de 4
memoria Tarea C Área de memoria Tarea B Área de memoria Tarea A 3er. Mbyte 4º Mbyte 5º Mbyte 2do. Mbyte Tarea C Código de DMT (DOS− BIOS) Primer Mbyte
5