Conceptos básicos

Dual Mode y Protección

La barrera de seguridad del hardware. User Mode vs. Kernel Mode y los anillos de protección.

Dual Mode Operation

Concepto fundamental de seguridad
Si no existiera el Dual Mode, un while(1) mal programado en tu navegador congelaría toda la computadora y tendrías que reiniciarla físicamente. El Dual Mode es lo que evita que un programa estúpido destruya el sistema.

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:

AnilloNombrePrivilegios¿Quién vive aquí?
Ring 0Kernel ModeIlimitados. 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 3User ModeRestringidos. 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:

  1. I/O Directo: Escribir en un puerto de hardware o leer del disco.
  2. Gestión de Memoria: Modificar la tabla de páginas (Page Table) o limpiar la caché (TLB Flush).
  3. Control de Interrupciones: Desactivar las interrupciones (CLI en Assembly) para que nadie te detenga.
  4. Cambio de Modo: Intentar cambiar el Mode Bit de 1 a 0 manualmente.
¿Por qué printf funciona?
Si `printf` escribe en la pantalla (I/O), y el I/O es privilegiado, ¿por qué no crashea? Porque `printf` es una función de la librería estándar (libc) que internamente hace una **System Call**. Pide permiso al Kernel para imprimir.

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 read de 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.