Dual Mode y Protección
Dual Mode Operation
Para garantizar que el sistema operativo mantenga el control sobre la computadora, el hardware debe proporcionar mecanismos para diferenciar entre la ejecución de código del sistema (confiable) y el código de usuario (potencialmente peligroso o malicioso).
La solución es el Bit de Modo (Mode Bit).
Este bit se encuentra en un registro especial de la CPU (generalmente en el Program Status Word o PSW). Define en qué estado se encuentra el procesador actualmente:
- Bit 0 (Kernel Mode): Acceso total. "God Mode".
- Bit 1 (User Mode): Acceso restringido. "Sandbox".
Protection Rings (Anillos de protección)
En la arquitectura x86 (Intel/AMD), este concepto se expande a 4 niveles llamados Rings, aunque los sistemas operativos modernos (Linux, Windows) solo usan dos:
| Anillo | Nombre | Privilegios | ¿Quién vive aquí? |
|---|---|---|---|
| Ring 0 | Kernel Mode | Ilimitados. Puede ejecutar cualquier instrucción de CPU y acceder a cualquier dirección de memoria. Si el código aquí falla, el sistema colapsa (Kernel Panic o Blue Screen of Death). | El Kernel, Drivers de dispositivos, Gestor de memoria. |
| Ring 3 | User Mode | Restringidos. No puede tocar el hardware directamente. No puede acceder a la memoria de otros procesos. Si falla, el OS mata el proceso (Segfault) y el sistema sigue vivo. | Chrome, Spotify, ls, tu código en C. |
Nota curiosa: Los Rings 1 y 2 fueron diseñados para drivers de nivel intermedio, pero casi ningún OS los usa para mantener la portabilidad con otras arquitecturas (como ARM) que solo tienen dos modos.
Instrucciones Privilegiadas
La CPU tiene una lista de instrucciones que son ilegales si el Mode Bit está en User Mode. Si tu código intenta ejecutarlas, la CPU lanza una Excepción (Trap) y le pasa el control al Kernel para que decida qué hacer (usualmente, matarte).
Ejemplos de instrucciones privilegiadas:
- I/O Directo: Escribir en un puerto de hardware o leer del disco.
- Gestión de Memoria: Modificar la tabla de páginas (Page Table) o limpiar la caché (TLB Flush).
- Control de Interrupciones: Desactivar las interrupciones (
CLIen Assembly) para que nadie te detenga. - Cambio de Modo: Intentar cambiar el Mode Bit de 1 a 0 manualmente.
La transición (Context Switch)
El sistema cambia entre User Mode y Kernel Mode miles de veces por segundo. Esta transición no es gratis; tiene un costo de rendimiento alto (Overhead).
1. User -> Kernel (Entrar)
Ocurre cuando:
- El programa pide un servicio (System Call, ej:
open(),read()). - Ocurre un error (Exception, ej: división por cero).
- El hardware pide atención (Interrupt, ej: tecla presionada).
Al ocurrir esto, el hardware cambia el Mode Bit a 0 y salta a una dirección de memoria predefinida donde está el manejador de interrupciones del Kernel.
2. Kernel -> User (Salir)
Ocurre cuando:
- El OS termina de atender la System Call.
- El planificador (Scheduler) decide darle tiempo de CPU a un proceso.
El Kernel usa una instrucción especial (como IRET en x86) que restaura el estado anterior y cambia el Mode Bit de vuelta a 1.
Implicaciones para tus proyectos
Entender esto es vital para el Proyecto Final (Web Server).
Cada vez que tu servidor recibe una petición (read) o envía una respuesta (send), estás cruzando la frontera User/Kernel.
- Si haces
readde 1 byte en 1 byte, cruzas la frontera millones de veces. Lento. - Si usas un buffer grande (ej. 4KB), cruzas la frontera una vez. Rápido.
Regla de Ingeniería: Minimiza las transiciones de modo. Quedate en User Mode tanto como puedas y, cuando necesites al Kernel, pide mucho trabajo de una sola vez.
Arquitectura base
Repaso de lo visto en la materia de arquitectura de computadoras. Ciclo de instrucción, jerarquía de memoria y mecanismos de E/S (DMA vs Interrupciones).
Interrupciones (Events)
La diferencia entre eventos de hardware (asíncronos) y eventos de software (síncronos). El rol del Timer y el Vector de Interrupciones.