# Modo protegido

El modo protegido es un modo operacional de los CPUs compatibles x86 de la serie 80286 y posteriores.
El modo protegido tiene un número de nuevas características diseñadas para mejorar la multitarea y la estabilidad del sistema, tales como la protección de memoria, y soporte de hardware para memoria virtual como también la conmutación de tarea. A veces es abreviado como p-mode y también llamado Protected Virtual Address Mode (Modo de Dirección Virtual Protegido) en el manual de referencia de programador del iAPX 286 de Intel, (Nota, iAPX 286 es solo otro nombre para el Intel 80286). En el 80386 y procesadores de 32 bits posteriores se agregó un sistema de paginación que es parte del modo protegido.
La mayoría de los sistemas operativos x86 modernos se ejecutan en modo protegido, incluyendo GNU/Linux, FreeBSD, OpenBSD, NetBSD, Mac OS X y Microsoft Windows 3.0 y posteriores. (Windows 3.0 también se ejecutaba en el modo real para la compatibilidad con las aplicaciones de Windows 2.x).
El otro modo operacional principal del 286 y CPUs posteriores es el modo real, un modo de compatibilidad hacia atrás que desactiva las características propias del modo protegido, diseñado para permitir al software viejo ejecutarse en los chips más recientes. Como una especificación de diseño, todos los CPUs x86 comienzan en modo real en el momento de carga (boot time) para asegurar compatibilidad hacia atrás con los sistemas operativos heredados, excepto el Intel 80376 diseñado para aplicaciones en sistemas embebidos. Estos procesadores deben ser cambiados a modo protegido por un programa antes de que esté disponible cualquier característica de este modo. En computadores modernos, este cambio es generalmente una de las primeras tareas realizadas por el sistema operativo en el tiempo de carga.
Mientras que la multitarea en sistemas ejecutándose en modo real es ciertamente posible mediada por software, las características de protección de memoria del modo protegido previenen que un programa erróneo pueda dañar la memoria "propia" de otra tarea o del núcleo del sistema operativo. El modo protegido también tiene soporte de hardware para interrumpir un programa en ejecución y cambiar el contexto de ejecución a otro, permitiendo pre-emptive multitasking.

## Compatibilidad con aplicaciones de modo real

El Manual de Referencia del Programador del iAPX 286 de Intel indica que el modo protegido es solo una cubierta sobre el conjunto de instrucciones del 80186, y de hecho, para los programadores de aplicaciones, el modo protegido 80286 no agregó mucho más allá de tener acceso de hasta 16 MiB de memoria física y de 1 GiB de memoria virtual (512 MiB global, 512 MiB local). También era compatible con el código del modo real a nivel binario, así que en teoría, el código de aplicación del 8086 y 80186 podía ejecutárse en modo protegido si seguía las siguientes reglas, (aunque se ejecutaría más lento que en el modo real porque la carga de registros de segmento es más lenta):
* No aritmética de segmento
* No uso de instrucciones privilegiadas
* No acceso directo de hardware
* No escritura al segmento de código (lo que significa que código automodificable nunca está permitido)
* No ejecución de datos (eso, junto con la segmentación, proporciona una cierta protección de desbordamiento buffer)
* No presunción que los segmentos se solapan
En realidad, casi todos los programas de aplicaciones del DOS violaron estas reglas, por la carencia de reemplazo de llamadas del DOS o del BIOS, o debido al insuficiente nivel de desempeño de tales llamadas. Las violaciones más comunes eran aritmética de segmento y el acceso directo del hardware. También algunas de las interrupciones del BIOS usaban números que fueron reservados por Intel. En otras palabras, el modo protegido era menos compatible con aplicaciones de DOS que con aplicaciones de modo real y por lo tanto había una necesidad del modo 8086 virtual, que vino con el 386.

## Niveles privilegiados

En modo protegido, hay cuatro niveles de privilegio o anillos, numerados de 0 a 3. El código del núcleo (kernel) del sistema operativo, que necesita usar instrucciones privilegiadas se ejecuta en el anillo 0, y las aplicaciones del usuario se ejecutan normalmente en el anillo 3.
El sistema operativo puede asignar los anillos 1 y 2 a servicios de sistema, como protocolos de red o al gestor de ventanas, que las aplicaciones pueden llamar. El hacer esto, le permite a los servicios acceder directamente los datos de la aplicación, mientras que se protegen de éstas, así como el núcleo queda protegido de los servicios. Sin embargo, esto requiere, al sistema operativo, especificar la protección de memoria a nivel de segmento (porque en el 80386, la protección de nivel de página no puede distinguir entre los anillos 0, 1, y 2) y puede ser difícil si el sistema operativo necesita ser portable a procesadores que soporten solamente dos anillos. En lugar de ello, un sistema operativo puede alcanzar una protección equivalente o más fuerte al ejecutar los servicios en el anillo 3 pero en un diferente espacio de dirección. Sin embargo, esto cuesta más, al tener una conmutación de contexto más compleja a la hora de la llamada, a menos que al servicio le sea dado un Task State Segment (segmento de estado de tarea) separado, el procesador primero debe cambiar al anillo 0 para cambiar el espacio de dirección, y después volver al anillo 3 para ejecutar el servicio.
El procesador comprueba niveles de privilegio en las siguientes situaciones. Si el código que se ejecuta no tiene suficientes privilegios, el resultado es generalmente una excepción que el sistema operativo puede manejar; pero también están las instrucciones que hacen los mismos chequeos sin levantar excepciones.
* Instrucción privilegiada. Algunas instrucciones solo se pueden ejecutar en el anillo 0: por ejemplo LGDT (Load Global Descriptor Table) (Carga Tabla Global de Descriptores), que puede redefinir segmentos arbitrariamente y por lo tanto vencer el mecanismo de protección. POPF (Pop Flags desde la pila) siempre es permitido, pero solo puede cambiar el campo IOPL desde el anillo 0.
* Entrada/salida. El nivel de privilegio requerido para las instrucciones de E/S y para modificar el flag de interrupción es definido por medio del campo IOPL del registro EFLAGS. Incluso si el nivel actual de privilegios no es suficiente, todavía puede permitir E/S a puertos específicos vía el mapa de bits de permisos de I/O en el segmento de estado de tarea (no soportado por el 80286).
* Cargar un registro de segmento, far jumps y llamadas a subrutinas. Cada segmento tiene un descriptor que define el descriptor privilege level (DPL) (nivel de privilegio del descriptor) requerido para usar ese segmento. El valor del selector cargado en un registro de segmento también codifica un requestor's privilege level (RPL) (nivel de privilegio del solicitante), que debe ser fijado con la instrucción ARP, para marcar los selectores recibidos desde código menos privilegiado. El procesador hace diferentes comprobaciones para accesos de los datos, la conmutación de la pila, transferencias de control directas, y transferencias de control indirectas por medio de una puerta.
* Retornando a código menos privilegiado. El procesador limpia todos los registros de segmentos que contengan selectores que codifican en el nuevo nivel de privilegio que no hubieran podido cargarse allí por sí mismos.
* La paginación (no soportada por el 80286). Un bit en cada entrada de tabla de página controla si la página se puede usar solamente en los anillos 0, 1, y 2 (modo supervisor), o también en el anillo 3 (modo usuario).
El RPL en el registro CS (segmento de código) es siempre el nivel actual de privilegio. La lectura de este registro no puede ser atrapada, lo que complica la virtualización nativa de sistemas operativos, puesto que éstos normalmente esperan tener el anillo 0 para sí mismos. Ver virtualización x86.

## Extensiones del 386 al modo protegido

Éstas incluyen:
* paginación
* Offsets de segmento de 32 bits (estos segmentos y la paginación hicieron posible, en el 80386, hacer un espacio de dirección plano de 32 bits usado en sistemas operativos modernos)
* Espacio de dirección físico de 32 bits (esta extensión no está presente en los procesadores 80386 que tienen un bus tipo 80286, por ejemplo el 80386SX)
* Capacidad de retornar al modo real
* Modo 8086 virtual
* Bitmaps con permisos de I/O
Algunas de ellas usaron lo que estaba documentado como bits reservados en el anterior procesador 286 en el manual de referencia del programador del iAPX 286 de Intel.