Objetivos de Implementación del Sistema
Este capítulo se enfoca en desarrollar un núcleo de sistema operativo básico capaz de gestionar múltiples programas de usuario de manera segura y automatizada. Los objetivos técnicos principales son:
- Integrar el kernel y múltiples aplicaciones en un único binario ejecutable.
- Implementar un mecanismo de procesamiento por lotes para cargar y ejecutar aplicaciones secuenciamlente.
- Utilizar los niveles de privilegio del hardware para proteger el núcleo del sistema.
- Implementar transiciones entre modos de privilegio (trampas e interrupciones).
- Soportar llamadas al sistema que crucen fronteras de privilegio.
Concepto Central
Un avance conceptual fundamental en la historia de los sistemas operativos fue la idea de que una computadora puede organizar su propia carga de trabajo mediante software. Aquí, buscamos que un sistema operativo embrionario sea consciente de la existencia de varias aplicaciones, ejecutándolas una tras otra. Cuando una aplicación termina (ya sea exitosamente o por fallo), el sistema procede automáticamente con la siguiente, hasta completar todas las tareas en la cola.
Demostración Práctica
Para observar el comportamiento objetivo, utilizamos el código de referencia del capítulo correspondiente. Asumiendo que el proyecto está clonado en un directorio como /home/usuario/Proyectos/rCore-Tutorial-v3, seguimos estos pasos:
cd /home/usuario/Proyectos/rCore-Tutorial-v3
git checkout ch2
cd os
make run
La salida esperada del sistema en ejecución se muestra a continuación. Los puntos clave a observar son las líneas que contienen Loading (carga) y kill (terminación), las cuales demuestran las dos capacidades centrales:
- El sistema operativo puede autonomamente localizar, cargar y ejecutar tareas (aplicaciones).
- Si una aplicación falla (por ejemplo, violación de acceso o instrucción privilegiada ilegal), el núcleo puede terminarla de manera controlada, manteniendo su propia integridad y continuando con la siguiente tarea.
[kernel] Hello, world!
[kernel] num_app = 5
[kernel] app_0 [0x8020b038, 0x8020c330)
[kernel] Loading app_0
Hello, world!
[kernel] Application exited with code 0
[kernel] Loading app_1
Into Test store_fault, we will insert an invalid store operation...
Kernel should kill this application!
[kernel] PageFault in application, kernel killed it.
...
All applications completed!
Arquitectura del Sistema y Nuevos Componentes
Comparado con un sistema monoprograma básico, la arquitectura aquí introduce cambios significativos para soportar el procesamiento por lotes y la protección:
- Modo Usuario (U-Mode): Se introduce explícitamente la ejecución en un nivel de privilegio reducido para las aplicaciones, distinto del modo supervisor (S-Mode) del núcleo.
- Manejador de Trampas (Trap Handler): Un componente crítico que intercepta eventos excepcionales o de interrupción originados en las aplicaciones (como fallos de página o instrucciones ilgeales). Su función es salvaguardar el núcleo y tomar decisiones sobre el destino de la aplicación fallida.
- Servicio de Llamadas al Sistema (Syscall Service): Proporciona una interfaz controlada y segura para que las aplicaciones soliciten servicios del núcleo (como E/S o gestión de memoria), realizando la transición necesaria de U-Mode a S-Mode.
En sistemas convencionales (como Linux o Windows), ejecutar una aplicación implica cargar un archivo ELF, crear tablas de páginas específicas para el proceso, y mapear secciones del ejecutable. En esta etapa educativa, sin sistemas de archivos ni mecanismos avanzados de mapeo de memoria, se emplea una técnica simplificada: el enlazador incluye las aplicaciones directamente dentro de la imagen binaria del kernel. Para ejecutarlas, el núcleo simplemente salta a la región de memoria predefinida donde reside cada aplicación.