IR0 - Kernel - Overview
El propósito de esta "wiki", documentación web, guía, como le digas, es usarla como ayuda-memoria
personal
para el desarrollo del kernel.
No tiene que ser una página ultra estética, pero me estoy esforzando para que no se note que la hice
con html, css y js vanilla como la de algún proyecto aficionado
que anda por ahí.
Un kernel de sistema operativo mínimamente funcional (todo el Kernel Space más un user space mínimo)
puede andar fácilmente en las 15.000 líneas de código por lo que, como verás;
es humanamente imposible memorizar y comprender todo el flujo del kernel por mí mismo. Además son
muchos subsistemas complejos trabajando a bajo nivel juntos para intermediar entre hardware y
software.
Este cálculo es automático y se hace mediante una api que cuenta la cantidad de líneas de
código que tiene el kernel (.c, .h, .asm, .rs y .cpp)
Esto merece que dejes una estrella en el repo
¿Qué es IR0?
IR0 es un kernel de sistema operativo multipropósito desarrollado
desde cero para arquitectura x86-64 escrito en C,
C++,
Rust y ASM. El kernel core está en C, los device drivers en Rust
(para memory safety), y componentes avanzados como schedulers en C++ (para templates y RAII).
Lo estoy creando para aprender más sobre sistemas operativos y poder usarlo como materia
prima para otro proyecto que replica a WSL2 pero con mi propio kernel.
No descarto escalarlo lo suficiente como para hacerlo usable en servidores mínimos o incluso IoT,
pero entiendo que eso es al largo (larguísimo) plazo.
Este
es su Repositorio de GitHub.
Discord
community
Características Principales Implementadas
- ✅ Kernel monolítico modular para arquitectura x86-64
- ✅ Gestión completa de memoria virtual con paginación (MMU)
- ✅ Sistema completo de interrupciones y excepciones (64 vectores IDT)
- ✅ Planificador CFS (Completely Fair Scheduler) con Red-Black Tree
- ✅ Sistema de procesos completo con fork(), exit(), waitpid()
- ✅ 23 syscalls implementadas (desde básicas hasta gestión de memoria)
- ✅ Filesystem MINIX completo con VFS (Virtual File System)
- ✅ Drivers de hardware: PS/2 (teclado/mouse), ATA/IDE, Sound Blaster 16, VGA
- ✅ Shell interactivo en Ring 3 con comandos integrados
- ✅ LibC freestanding con printf(), malloc(), free()
- ✅ Sistema de compilación multi-objetivo (Desktop/Server/IoT/Embedded)
s
Estado del Proyecto
Versión: v0.0.1 pre-release candidate 1
Arquitectura: x86-64 (primaria), x86-32 (experimental), ARM (en desarrollo)
Bootloader: GRUB
Licencia: GNU GPL v3.0
Tipo: Kernel Monolítico Modular
Sintaxis ASM: Intel (NASM)
Arquitectura del Sistema
Diagrama de Arquitectura del Kernel IR0
User Space (Ring 3)
Shell Interactivo
LibC (IR0)
Programas Usuario
ELF Loader
Kernel Space (Ring 0) - IR0
Interfaz del Sistema
23 Syscalls (IR0)
INT 0x80 Handler
Init System (PID 1)
Procesos y Memoria
CFS Scheduler
Virtual Memory (MMU)
Heap Allocator
Process Manager
Sistema de Archivos
VFS Layer
MINIX Filesystem
File Operations
Drivers de Hardware
PS/2 (Teclado/Mouse)
ATA/IDE Storage
Sound Blaster 16
VGA/VBE Video
Interrupciones y Timers
IDT (64 vectores)
PIC Remapping
Timer Cascade
DMA Controller
Red (En Desarrollo)
TCP/IP Básico (IoT)
Socket Interface
Ethernet Drivers
Hardware
CPU x86-64
RAM (MMU)
ATA/IDE Disks
PS/2 Devices
Sound Blaster
VGA/VBE
User Space (Ring 3) - Shell, LibC y programas de usuario
Kernel Space (Ring 0) - Núcleo IR0 monolítico modular
Hardware - Componentes físicos soportados
Arquitectura y "Filosofía" del proyecto
A diferencia de kernels como kernel NT (Híbrido) de Microsoft, Redox-OS
(Microkernel),
o el mismo MINIX kernel (microkernel), IR0 se basa en una arquitectura más
similar a la que tiene Linux, que es monolítico.
Sin embargo, mi argumento principal es el del rendimiento. Entiendo que alguien podría venir y
señalar que, como todo monolito, si un subcomponente se rompe, se cae todo el sistema (y
tendría razón)
pero lo que respondo a eso es que "¿De qué me sirve a mí que el kernel soporte seguir sin
filesystem si no puedo hacer nada práctico sin él?", es decir, no tiene sentido que el
kernel
continúe funcionando sin uno de sus componentes clave corriendo.
Por eso no veo mejor alternativa (por ahora) que el patrón monolítico. Y además me ahorra el tener que interconectar
subsistemas clave entre sí con IPC, lo que impacta de una en el rendimiento del Sistema Operativo.
No es
perfecto, pero es estable. No es del todo trazable y requiere escalar de a poco, pero si escala bien
rinde mucho.
Sin embargo yo también tengo desacuerdos con la filosofía UNIX. Ellos (entre otras cosas y de forma resumidísima)
consideran
que si algo falla, que falle bien. Lo que en términos kernelísticos sería: Si se rompe el
scheduler, Panic() directo. Si tenés corrupción en memoria (en espacio de kernel),
Panic.
Y no es que lo cuestiono por que sí, simplemente pregunto (aunque sin soluciones todavía) "¿Por
qué no rescatar el sistema en tiempo de Panic()?, o por lo menos hacer el intento".
Mas allá del punto filosófico y para resumir, el kernel es monolítico porque es más performante y
siento que las piezas clave del núcleo deben trabajar sin overhead.
Sin embargo, si en el futuro necesitara integrar algún subsistema específico de forma híbrida,
seguramente sería pragmático.
El Kernel Space es sagrado
Yo sé que hablo como si IR0 fuera usado por miles de personas y toda la historia, pero me voy a dar
el lujo de opinar al respecto.
Entonces, el punto es que el kernel space tiene que ser sólo habitable por subsistemas
que trabajen en ese Entorno,
nada mas.
Entiendo que hayan ciertos fabricantes preocupados por la seguridad de sus
clientes que,
casualmente, tienen acceso a toda interrupción que el usuario haga (saben qué teclas presionás,
el tiempo de tu sesión cada vez que prendés la compu, etc.) Y todo eso porque tienen
software funcionando en el kernel space con todos los privilegios que eso
implica.
RING 0 es únicamente para el kernel. Todo lo que venga del RING 3
se comunica con syscalls(), fin del comunicado.
Enfoque de Red: Básico pero Funcional
Para que IR0 funcione como soporte para servidores básicos y aplicaciones IoT, necesito
soporte de red fundamental pero sin la complejidad masiva del stack completo de
Linux.
En el Kernel Linux son mas o menos 1.500.000 de líneas de código SÓLO LA PILA DE RED
COMPLETA. En lugar de intentar portar todo eso, he decidido usar un enfoque más
pragmático:
Implementación básica con librería IoT:
- Stack TCP/IP ligero y funcional
- Soporte para conectividad básica de red
- Interfaz de sockets simplificada
- Drivers Ethernet esenciales
- Enfoque minimalista que mantiene el kernel manejable
Esto me permite tener funcionalidad de red sin agregar millones de líneas de código al kernel.
Ventajas del Enfoque Básico
Este enfoque con librería IoT tiene varias ventajas:
- Mantiene el kernel ligero y manejable
- Reduce significativamente la complejidad del código
- Permite funcionalidad de red sin millones de líneas adicionales
- Es más fácil de debuggear y mantener
- Suficiente para casos de uso básicos y IoT
Estructura de Directorios
Cómo la estructura de archivos puede cambiar constantemente, prefiero que la consultes en el
Repositorio de GitHub.
Subsistemas del Kernel IR0
Estado del Proyecto
Versión: v0.0.1 pre-release candidate 1
Arquitectura: x86-64 (primaria), x86-32 (experimental), ARM (en desarrollo)
Licencia: GNU GPL v3.0
Tipo: Kernel Monolítico Modular
🏗️ Arquitectura Central
✅ Arquitectura del Kernel
- Diseño monolítico modular con abstracción HAL
- Sistema de compilación multi-objetivo (Desktop/Server/IoT/Embedded)
- Separación Ring 0 (kernel) / Ring 3 (usuario)
- Soporte primario x86-64 con framework multi-arquitectura
- Entorno C freestanding con libc personalizada
✅ Sistema de Arranque
- Cumplimiento de especificación multiboot de GRUB
- Inicialización de modo largo x86-64
- Configuración GDT (Global Descriptor Table)
- Configuración TSS (Task State Segment)
- IDT (Interrupt Descriptor Table) con 64 entradas
✅ Gestión de Memoria
- Memoria virtual con paginación (MMU)
- Asignador de heap del kernel (simple + avanzado en desarrollo)
- Protección de memoria (aislamiento Ring 0/3)
- Layout de memoria: Kernel (1MB-8MB), Heap (8MB-32MB), Usuario (1GB+)
- Manejo de fallos de página con lectura de dirección CR2
🛡️ Gestión de Memoria
Ubicación: mm/pmm.c, mm/allocator.c, mm/paging.c
El subsistema de gestión de memoria proporciona tres capas de asignación y gestión de memoria: Administrador de Memoria Física (PMM) para asignación de frames, asignador de heap para memoria dinámica del kernel, y sistema de paginación para memoria virtual y aislamiento de procesos.
Administrador de Memoria Física (PMM)
Ubicación: mm/pmm.h, mm/pmm.c
El PMM gestiona frames de memoria física (páginas de 4KB) usando un asignador basado en bitmap:
- Región de Memoria: 8MB a 32MB (24MB total, ~6000 frames)
- Algoritmo: Búsqueda first-fit en bitmap
- Operaciones:
pmm_alloc_frame() - Asigna un frame, pmm_free_frame() - Desasigna un frame
- Estadísticas:
pmm_stats() - Proporciona conteos de frames totales/usados/libres
- Codificación: 1 bit por frame de 4KB (1 = usado, 0 = libre)
Asignador de Heap
Ubicación: includes/ir0/kmem.h, mm/allocator.c
Asignación dinámica de memoria para código del kernel usando una free-list con boundary tags:
- Algoritmo: Free-list con boundary tags para coalescencia eficiente
- Asignación: Búsqueda first-fit con división de bloques
- Desasignación: Coalescencia hacia adelante y hacia atrás (operaciones O(1))
- API:
kmalloc(), kmalloc_aligned(), krealloc(), kfree(), kfree_aligned()
- Estructura: Cada bloque tiene header (inicio) y footer (fin) con tamaño y estado libre
Sistema de Paginación
Ubicación: mm/paging.h, mm/paging.c
Gestión de memoria virtual y aislamiento de procesos a través de directorios de página separados:
- Tamaños de Página: Páginas de 4KB (estándar), páginas de 2MB (mapeo idéntico), páginas de 1GB (definidas pero no usadas)
- Estructura x86-64: PML4 → PDPT → PD → PT (paginación de 4 niveles)
- Banderas de Página: PRESENT, RW, USER, WRITETHROUGH, CACHE_DISABLE, ACCESSED, DIRTY, SIZE_2MB, GLOBAL
- Aislamiento de Proceso: Cada proceso tiene su propio directorio de página (registro CR3)
- Mapeo Idéntico: Primeros 16MB usando páginas de 2MB para espacio del kernel
- Operaciones:
map_page(), unmap_page(), create_process_page_directory()
Regiones de Memoria
Mapa de Memoria del Kernel
0x000000 - 0x100000 Código de arranque, código del kernel
0x100000 - 0x800000 Heap del kernel (crece hacia arriba)
0x800000 - 0x2000000 Frames gestionados por PMM (8MB-32MB, 24MB)
0x2000000+ Datos del kernel, stacks
Layout de Memoria del Proceso
- Segmento de Código - Binario ELF cargado en espacio de usuario
- Stack - 8KB por defecto, crece hacia abajo desde dirección alta
- Heap - Crece hacia arriba desde dirección baja, gestionado por syscall
brk()
- Directorio de Página - Espacio de direcciones virtuales aislado
Notas de Implementación
- Sin Copy-on-Write: Operaciones fork no usan COW (limitación intencional)
- Sin Swap: Toda la memoria es física (sin intercambio a disco)
- Algoritmos Simples: First-fit tanto para PMM como heap (no optimizado)
- Sin NUMA: Asume acceso uniforme a memoria
- CPU Única: Sin gestión de memoria consciente de SMP
⚙️ Gestión de Procesos
Ubicación: kernel/process.c, kernel/process.h
El subsistema de gestión de procesos maneja el ciclo de vida completo de los procesos en el kernel IR0, incluyendo creación, ejecución, terminación y relaciones padre-hijo. Proporciona aislamiento de procesos a través de directorios de página separados y soporta comunicación entre procesos basada en señales.
Estructura de Proceso
Cada proceso está representado por una estructura process_t que contiene:
- Contexto de Tarea - Estado de registros CPU (RAX, RBX, RCX, RDX, RSI, RDI, RSP, RBP, RIP, RFLAGS, segmentos)
- ID de Proceso - Identificador único (comienza desde PID 2, PID 1 es init)
- ID de Proceso Padre - Identificador del proceso padre
- Estado del Proceso - READY, RUNNING, BLOCKED, o ZOMBIE
- Modo de Ejecución - KERNEL_MODE o USER_MODE
- Directorio de Página - Aislamiento de memoria virtual (tablas de página separadas por proceso)
- Layout de Memoria - Límites de stack y heap, y mapeos de memoria
- Descriptores de Archivo - Tabla de descriptores de archivo abiertos (máx. 32 por proceso)
- Señal Pendiente - Máscara de bits de señales pendientes
Estados de Proceso
- PROCESS_READY (0) - Proceso está listo para ejecutar, esperando ser planificado
- PROCESS_RUNNING (1) - Proceso está ejecutándose actualmente en CPU
- PROCESS_BLOCKED (2) - Proceso está esperando I/O u otros eventos
- PROCESS_ZOMBIE (3) - Proceso ha terminado pero el padre no ha llamado
wait() todavía
Ciclo de Vida del Proceso
Creación de Proceso
process_spawn() - Crea un nuevo proceso determinísticamente con un punto de entrada y nombre especificados:
- Crea proceso aislado con directorio de página separado
- Asigna stack de 8KB
- Configura contexto CPU para modo usuario (Ring 3)
- Registra proceso en planificador
- Asigna PID secuencial (comenzando desde 2)
- Establece padre al proceso actual
Terminación de Proceso
process_exit() - Termina el proceso actual:
- Establece estado del proceso a ZOMBIE
- Almacena código de salida
- Reasigna procesos hijos huérfanos a init (PID 1)
- Envía señal SIGCHLD al proceso padre
- Detiene ejecución hasta ser limpiado por el padre
Espera de Proceso
process_wait() - Espera a que un proceso hijo termine y recupera su estado de salida:
- Busca proceso hijo zombie con PID coincidente
- Recupera código de salida y elimina de la lista de procesos
- Devuelve PID del hijo en éxito
Integración de Señales
El subsistema de procesos se integra con el sistema de señales para comunicación entre procesos y manejo de errores:
- Excepciones CPU → Señales: SIGSEGV (fallo de página), SIGFPE (división por cero), SIGILL (opcode inválido)
- Señales de Terminación: SIGKILL, SIGTERM, SIGINT, SIGQUIT
- Control de Proceso: SIGCHLD (hijo terminado), SIGSTOP, SIGCONT
- Las señales se manejan antes de cada cambio de contexto
- Las señales fatales terminan el proceso
Aislamiento de Memoria de Proceso
Cada proceso tiene su propio directorio de página (registro CR3) para aislamiento de memoria:
- Espacio del Kernel - Compartido entre todos los procesos (mapeado idéntico)
- Espacio de Usuario - Espacio de direcciones virtuales específico del proceso
- Stack - Stack privado de 8KB por proceso
- Heap - Gestionado por syscall
brk() (heap por proceso)
🔧 Llamadas al Sistema
✅ Interfaz de Syscalls (23 syscalls implementadas)
SYS_EXIT(0) - Terminación de proceso
SYS_WRITE(1) - Escribir a descriptor de archivo
SYS_READ(2) - Leer de descriptor de archivo
SYS_GETPID(3) - Obtener ID de proceso
SYS_GETPPID(4) - Obtener ID de proceso padre
SYS_LS(5) - Listar contenidos de directorio
SYS_MKDIR(6) - Crear directorio
SYS_PS(7) - Mostrar lista de procesos
SYS_WRITE_FILE(8) - Escribir archivo al filesystem
SYS_CAT(9) - Mostrar contenidos de archivo
SYS_TOUCH(10) - Crear archivo vacío
SYS_RM(11) - Eliminar archivo
SYS_FORK(12) - Crear proceso hijo
SYS_WAITPID(13) - Esperar proceso hijo
SYS_RMDIR(40) - Eliminar directorio
SYS_MALLOC_TEST(50) - Test de asignación de memoria
SYS_BRK(51) - Cambiar break del heap
SYS_SBRK(52) - Incrementar break del heap
SYS_MMAP(53) - Mapeo de memoria
SYS_MUNMAP(54) - Desmapear memoria
SYS_MPROTECT(55) - Cambiar protección de memoria
SYS_EXEC(56) - Ejecutar programa
✅ Mecanismo de Syscalls
- Interfaz de interrupción de software INT 0x80
- Paso de parámetros basado en registros
- Transición modo kernel/usuario
- Manejo de errores y valores de retorno
⚡ Sistema de Interrupciones
✅ Manejo de Interrupciones
- Configuración completa IDT con 64 vectores de interrupción
- Remapeo PIC (Programmable Interrupt Controller)
- ISR (Interrupt Service Routines) en ensamblador
- Manejo IRQ para dispositivos de hardware
- Integración de interrupción de timer
- Interrupción de teclado (IRQ 1)
- Interrupción de mouse (IRQ 12)
- Interrupción de audio (IRQ 5)
✅ Manejo de Excepciones
- Manejador de fallos de página con lectura de dirección CR2
- Manejo de fallo de protección general
- Excepción de división por cero
- Excepción de código de operación inválido
- Manejo de fallo de pila
🖥️ Controladores de Hardware
✅ Dispositivos de Entrada
- Driver de teclado PS/2 con buffer circular
- Driver de mouse PS/2 con soporte 3/5 botones + rueda de desplazamiento
- Detección de tipo de mouse (estándar/rueda/5 botones)
- Tasas de muestreo y resolución configurables
✅ Dispositivos de Almacenamiento
- Driver de disco duro ATA/IDE
- Soporte CD-ROM
- Operaciones básicas de E/S de disco
- Lectura/escritura basada en sectores
✅ Sistema de Audio
- Driver Sound Blaster 16
- Soporte de audio 8-bit/16-bit
- Reproducción Mono/Estéreo
- Transferencia de audio basada en DMA (canales 1 y 5)
- Control de volumen (master y PCM)
- Configuración de tasa de muestreo
- Detección de formato de audio
✅ Sistema de Video
- Modo texto VGA (80x25)
- Soporte gráfico VBE (VESA BIOS Extensions)
- Acceso a framebuffer
- Primitivas gráficas básicas
✅ Comunicación Serie
- Drivers de puerto serie COM1/COM2
- Salida de debug vía serie
- Tasas de baudios configurables
- Manejo de interrupciones serie
✅ Sistemas de Timer
- PIT (Programmable Interval Timer)
- RTC (Real Time Clock)
- HPET (High Precision Event Timer)
- LAPIC (Local APIC Timer)
- Abstracción de sistema de reloj unificado
- Cascada de timer con selección del mejor timer disponible
✅ Controlador DMA
- Soporte DMA de 8 canales (0-7)
- Modos de transferencia 8-bit y 16-bit
- Integración DMA de audio
- Control de habilitación/deshabilitación de canales
📁 Sistema de Archivos
✅ Sistema de Archivos Virtual (VFS)
- Capa de abstracción de filesystem unificada
- Framework de soporte para múltiples filesystems
- Operaciones estándar de archivo (open, read, write, close)
- Operaciones de directorio (mkdir, rmdir, ls)
- Manejo de metadatos de archivo
✅ Filesystem MINIX
- Implementación completa de filesystem MINIX
- Almacenamiento de archivos basado en inodos
- Soporte de estructura de directorios
- Creación, eliminación y modificación de archivos
- Integrado con capa VFS
✅ Operaciones de Archivo
- Creación de archivos (touch)
- Eliminación de archivos (rm)
- Creación de directorios (mkdir)
- Eliminación de directorios (rmdir)
- Visualización de contenido de archivos (cat)
- Listado de directorios (ls)
- Capacidades de escritura de archivos
👤 Espacio de Usuario
✅ Biblioteca C (LibC)
- Implementación de biblioteca C freestanding
- Headers estándar: stdio.h, stdlib.h, unistd.h, stdint.h, stddef.h
- Funciones de E/S: printf(), puts(), putchar()
- Funciones de memoria: malloc(), free()
- Funciones de proceso: exit(), getpid()
- Wrappers de llamadas al sistema
✅ Implementación de Printf
- Especificadores de formato: %d (enteros), %s (strings), %c (caracteres)
- Soporte de argumentos variables
- Salida a stdout
✅ Programas de Usuario
- Implementación del comando echo
- Integración shell para programas de usuario
- Cargador ELF (implementación básica)
🐚 Sistema Shell
✅ Shell Interactivo
- Interfaz de línea de comandos en Ring 3 (modo usuario)
- Comandos integrados: ls, ps, cat, mkdir, rmdir, touch, rm, fork, clear, help, exit, malloc,
sbrk, exec
✅ Características del Shell
- Análisis y ejecución de comandos
- Integración de gestión de procesos
- Soporte de operaciones de filesystem
- Testing de gestión de memoria
- Manejo de errores y retroalimentación
🌐 Sistema de Red
🔄 Stack TCP/IP Básico (En Desarrollo)
- Implementación básica usando librería IoT ligera
- Soporte TCP/IP fundamental para conectividad
- Interfaz de sockets simplificada
- Framework de drivers Ethernet básico
- Utilidad ping planificada
- Enfoque minimalista para reducir complejidad
Nota: Se optó por una implementación básica con librería IoT en lugar de
portar el stack completo de Linux (1.5M líneas) para mantener el kernel ligero y
manejable.
🔧 Sistema de Compilación
✅ Compilación Multi-Objetivo
- Objetivo Desktop (características completas, heap 256MB, 1024 procesos)
- Objetivo Server (networking optimizado, heap 1GB, 4096 procesos)
- Objetivo IoT (gestión de energía, heap 16MB, 64 procesos)
- Objetivo Embedded (características mínimas, heap 4MB, 16 procesos)
✅ Multi-Arquitectura
- Soporte de producción x86-64
- Soporte experimental x86-32
- Framework de desarrollo ARM
- Capa de abstracción de arquitectura (HAL)
⚠️ Limitaciones Actuales
❌ No Implementado Aún
- Soporte SMP (Symmetric Multiprocessing)
- Módulos dinámicos del kernel
- IPC avanzado (pipes, colas de mensajes)
- Stack de red (TCP/IP)
- Soporte USB
- GUI/Gestor de ventanas avanzado
- Manejo de señales
- Memoria copy-on-write
- Soporte de memoria swap
- Características avanzadas de filesystem (ext2/3/4)
⚠️ Problemas Conocidos
- El cambio de contexto de fork() necesita refinamiento
- Funcionalidad limitada del cargador ELF
- No hay recolección de procesos zombie en init
- Asignador de memoria básico (versiones avanzadas en desarrollo)
- Soporte de una sola CPU únicamente
📊 Especificaciones Técnicas
Layout de Memoria
Espacio Kernel: 0x100000 - 0x800000 (1MB-8MB)
Espacio Heap: 0x800000 - 0x2000000 (8MB-32MB, 24MB total)
Espacio Usuario: 0x40000000+ (1GB+)
Métricas de Rendimiento
- Tiempo de cambio de contexto: ~microsegundos (optimizado en ensamblador)
- Complejidad del planificador: O(log n) con Red-Black Tree
- Asignación de memoria: O(1) para asignador simple
- Latencia de interrupción: Mínima con ISRs optimizados
Límites de Recursos (Objetivo Desktop)
- Procesos máximos: 1024
- Threads máximos: 4096
- Tamaño de heap: 256MB
- Quantum del planificador: 10ms
- Tamaño de buffer E/S: 64KB
🎯 Hoja de Ruta
Corto Plazo (Próximo Release)
- Arreglar problemas de cambio de contexto de fork()
- Implementar recolección adecuada de zombies
- Integrar stack TCP/IP básico con librería IoT
- Mejorar cargador ELF
- Agregar framework USB
Mediano Plazo
- Soporte SMP
- Sistema GUI avanzado
- Expansión del networking básico (más protocolos, optimizaciones)
- Módulos dinámicos del kernel
- Mecanismos IPC avanzados
Largo Plazo
- Soporte de aplicaciones nativas (Doom, GCC, Bash)
- Compatibilidad POSIX completa
- Soporte avanzado de filesystem
- Mejoras de abstracción de hardware
- Optimizaciones de rendimiento
Guía de Desarrollo
- Esta sección es por si alguien se interesa en contribuir al proyecto. No
son
reglas estrictas, son simplemente recomendaciones
para que sea mas llevadero.
¿Qué hay que saber para contribuir?
Más que nada lo siguiente:
Saber programación estructurada/funcional/orientada a objetos según sea necesario por el lenguaje.
Conocer C o C++ o Rust.
Assembly si contribuís en subsistemas muy pegados al hard, pero recomiendo conocer los básicos para
saber cómo funcionan panic(), boot.asm, etc.
Conocer cómo funciona un makefile, como compilar los subsistemas por partes, por
qué
hay que compilar los subsistemas por separado con su propio makefile
Herramientas de desarrollo general: GIT/GitHub, como crear, cambiar, pullear y
lanzar
PR's entre ramas
QEMU básico. Cómo funciona la VM, como se le carga la imagen generada al compilar
el
kernel.
Conocer Bash es un plus para los testeos rápidos, ya que podés iniciar QEMU con un
script sin repetir el comando completo.
Comunicación. Argumentar decisiones sobre las PR's, debatir sanamente al respecto.
Saber utilizar IA's en general para optimizar el debug y adaptarlo a las convenciones de código.
Saber que, al contribuir, podés ser manteiner del subsistema al que aportaste. Y si
no
podés dar mantenimiento
recurrente al subsistema, dejarlo bien documentado.
De igual forma,
no hay que ser un experto para contribuir al kernel. Simplemente con tener ganas
de
aprender/estudiar sobre lo que vayas a contribuir es más que suficiente.
Configuración del Entorno
Dependencias Requeridas:
Básicamente tener instalado: el compilador de C/Cpp (gcc/g++), el compilador de asm (nasm), make
para la
compilación y
QEMU como vm de prueba.
Te daría los comandos o las webs para instalar, pero chatgpt te lo puede resolver mejor.
NOTA: Como este proyecto es un kernel, es Freestanding. Eso quiere decir que
vos
no podés incluir librerías como
stdio.h para hacer un print(), write(), etc. por que no hay sistema operativo que
responda a esas funciones . Vos sos el
sistema operativo. por eso, en el repo tengo la carpeta de dependencias "includes".
Cómo escribo código?
Convenciones de Nombres:
- Funciones:
snake_case()
- Macros:
UPPER_CASE
- Structs:
struct_name_t
- Variables globales:
g_variable_name
- Constantes:
CONSTANT_NAME
- includes:
#INCLUDE -ir0/Lib.h - (se estan migrando a ese formato)
Estilo de Código y Convenciones:
Intentamos seguir el estilo de código del kernel Linux, pero con algunas adaptaciones específicas
para este proyecto.
Estas son convenciones deseables, no reglas estrictas (excepto por el estilo de
llaves).
- Llaves estilo Allman (Importante): Usamos el estilo Allman (llaves en una nueva
línea). Esta es la regla de formato más importante.
- Comentarios: Preferimos comentarios multilínea
/* ... */ sobre los
de una línea //.
- Condicionales: Los
if de una sola línea no deben usar llaves.
- Manejo de Errores: Usamos
goto para lógica de limpieza cuando
múltiples puntos de salida comparten el mismo código de limpieza.
/*
* Ejemplo de una función siguiendo las convenciones de IR0
* Note las llaves estilo Allman y los comentarios multilínea
*/
int process_data(struct data_t *data)
{
if (!data)
return -1; /* If de una línea sin llaves */
char *buffer = kmalloc(1024);
if (!buffer)
{
/*
* Se usan llaves aquí porque el bloque
* contiene múltiples líneas o es complejo
*/
return -ENOMEM;
}
if (prepare_buffer(buffer) < 0)
goto cleanup; /* Uso de goto para manejo de errores/limpieza */
/* ... lógica de procesamiento ... */
kfree(buffer);
return 0;
cleanup:
kfree(buffer);
return -1;
}
Archivos de Cabecera (.h):
Los archivos de cabecera deben contener prototipos de funciones, definiciones de estructuras y
documentación detallada en comentarios.
#ifndef _IR0_EXAMPLE_H
#define _IR0_EXAMPLE_H
/*
* struct example_t - Representa una estructura de ejemplo
* @id: Identificador único
* @value: Valor asociado
*/
typedef struct
{
int id;
int value;
} example_t;
/*
* process_example - Procesa la estructura de ejemplo
* @ex: Puntero a la estructura
* Retorna: 0 en éxito, código de error negativo en fallo
*/
int process_example(example_t *ex);
#endif
🔧 Setup y Compilación
Verificación de Dependencias
IMPORTANTE: Antes de compilar, se recomienda verificar que todas las dependencias
estén correctamente instaladas:
Este comando verificará la presencia de todas las herramientas necesarias:
- Herramientas Esenciales: GCC, NASM, LD, Make, QEMU, GRUB
- Multi-Language Compilers (REQUERIDO): G++/Clang++, Rustc, Cargo, rust-src
- Cross-Compilation: MinGW-w64 (para compilar a Windows desde Linux)
- Python: Python 3, tkinter, PIL/Pillow
El script detecta automáticamente tu plataforma y proporciona instrucciones específicas de
instalación si falta alguna herramienta.
Herramientas Requeridas
Esenciales:
- GCC - Compilador C
- NASM - Ensamblador
- LD - Enlazador ELF x86-64
- Make - Automatización de compilación
Runtime:
- QEMU (qemu-system-x86_64) - Emulador
- GRUB (grub-mkrescue) - Creación de ISO booteable
Opcionales:
- Python 3 - Sistema de configuración del kernel
Multi-Language Support (REQUERIDO desde v0.0.1-pre.1):
- G++ / Clang++ - Compilador C++ (para componentes avanzados del kernel)
- Rustc + Cargo - Compilador Rust (para device drivers)
- rust-src - Componente de Rust para desarrollo no_std
Soporte Multi-Lenguaje
IR0 ahora soporta desarrollo en tres lenguajes:
- C - Kernel core, memory management, system calls
- Rust - Device drivers (network, storage, USB) con memory safety
- C++ - Componentes avanzados (schedulers, protocol stacks) con templates y RAII
Instalación de Rust:
# Instalar Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Agregar componentes necesarios
rustup component add rust-src
rustup target add x86_64-unknown-none
# Verificar instalación
rustc --version
cargo --version
Instalación de C++:
# Debian/Ubuntu
sudo apt-get install g++
# Arch Linux
sudo pacman -S gcc
# Verificar instalación
g++ --version
Instalación en Linux
# Debian/Ubuntu
sudo apt-get install build-essential nasm qemu-system-x86 grub-pc-bin python3
# Arch Linux
sudo pacman -S base-devel nasm qemu grub python
Comandos de Compilación
| Comando |
Descripción |
make ir0 |
Compilación completa: kernel ISO + programas userspace |
make kernel-x64.bin |
Compilar solo el binario del kernel |
make kernel-x64.iso |
Crear imagen ISO booteable |
make userspace-programs |
Compilar solo programas de userspace |
make clean |
Limpiar todos los artefactos de compilación |
make userspace-clean |
Limpiar solo programas userspace |
Ejecución en QEMU
| Comando |
Descripción |
make run |
Ejecutar con GUI + disco virtual (recomendado) |
make run-debug |
Ejecutar con GUI + salida de debug serial |
make debug |
Ejecutar con logging detallado de QEMU |
make run-nodisk |
Ejecutar sin disco virtual |
make run-console |
Ejecutar en modo consola (sin GUI) |
Configuración QEMU:
- Memoria: 512MB
- Display: GTK (configurable a SDL2)
- Serial: stdio (para debug)
- Flags:
-no-reboot -no-shutdown
- Debug log:
qemu_debug.log
Gestión de Disco Virtual
| Comando |
Descripción |
make create-disk |
Crear imagen de disco virtual (disk.img) |
make delete-disk |
Eliminar imagen de disco virtual |
Especificaciones del disco:
- Tamaño: 100MB (configurable)
- Formato: RAW
- Filesystem: MINIX
- Script:
scripts/create_disk.sh
Comandos de Utilidades
| Comando |
Descripción |
make deptest |
Verificar todas las dependencias del sistema |
make help |
Mostrar ayuda completa del Makefile |
make menuconfig |
Lanzar configuración del kernel (ncurses) |
make unibuild FILE=<archivo> |
Compilar archivo individual |
Sistema unibuild - Compilación Multi-Lenguaje:
El sistema unibuild ahora soporta compilar archivos en C, C++, y Rust con flags específicos:
# Compilar archivos C (por defecto)
make unibuild FILE=kernel/memory/kmalloc.c
# Compilar archivos C++
make unibuild -cpp FILE=kernel/scheduler/advanced_sched.cpp
# Compilar drivers Rust
make unibuild -rust FILE=drivers/network/rtl8139.rs
# Cross-compilación a Windows (desde Linux)
make unibuild -win FILE=kernel/file.c
make unibuild -win -cpp FILE=kernel/component.cpp
make unibuild -win -rust FILE=drivers/driver.rs
# Compilar múltiples archivos
make unibuild FILES="fs/ramfs.c fs/vfs.c"
Flags disponibles:
-cpp - Usar compilador C++ (g++)
-rust - Usar compilador Rust (rustc)
-win - Cross-compilar a Windows usando MinGW-w64
Los flags se pueden combinar para diferentes casos de uso (ej: -win -cpp para
cross-compilar C++ a Windows).
Flujo de Trabajo Recomendado
- Verificar dependencias:
make deptest
- Compilar el kernel:
make ir0
- Crear disco virtual:
make create-disk (primera vez)
- Ejecutar en QEMU:
make run
- Para debugging:
make run-debug
Subsistemas del Kernel
- En esta sección se detallan los principales subsistemas que componen el kernel
IR0,
su estado actual de desarrollo y las características técnicas de cada uno.
La mejor forma de entender el funcionamiento interno es revisando el código fuente en el
Repositorio de GitHub.
🔄 Scheduler (Planificador)
Ubicación: kernel/rr_sched.c, kernel/rr_sched.h
El subsistema de planificación gestiona la asignación de tiempo de CPU entre procesos. IR0 implementa actualmente un planificador Round-Robin simple que proporciona tiempo compartido justo entre todos los procesos listos. El planificador se integra con los subsistemas de gestión de procesos y manejo de señales.
Algoritmo Round-Robin
El planificador Round-Robin mantiene una lista enlazada circular de procesos:
- Cola de Procesos: Lista enlazada de nodos
rr_task_t, cada uno contiene un process_t*
- Puntero Actual: Apunta al nodo del proceso que se está ejecutando actualmente
- Selección Circular: Cada cambio de contexto avanza al siguiente nodo, volviendo a la cabeza al llegar a la cola
Operaciones
Agregar Procesos
rr_add_process() - Agrega un proceso a la cola del planificador:
- Valida puntero de proceso
- Asigna nuevo nodo
rr_task_t
- Establece estado del proceso a PROCESS_READY
- Añade a la cola de la cola
Planificar Siguiente Proceso
rr_schedule_next() - Realiza cambio de contexto al siguiente proceso:
- Selección: Avanza al siguiente nodo (vuelve a la cabeza si está en la cola)
- Actualización de Estado: Anterior → PROCESS_READY, Siguiente → PROCESS_RUNNING
- Manejo de Señales: Llama
handle_signals() antes del cambio de contexto
- Cambio de Contexto: Primer cambio usa
jmp_ring3(), subsiguientes usan switch_context_x64()
Cambio de Contexto
El cambio de contexto guarda/restaura el estado CPU (kernel/scheduler/switch/switch_x64.asm):
- Registros Guardados: RAX-R15, RSP, RBP, RIP, RFLAGS, segmentos (CS, DS, ES, FS, GS, SS)
- Aislamiento de Memoria: Cambia directorio de página (registro CR3) para aislamiento de proceso
- Proceso: Guarda actual → Carga CR3 → Carga segmentos → Carga registros → Ejecuta IRETQ
Particion de Tiempo
Implementación actual:
- Sin partición de tiempo explícita - Los procesos se ejecutan hasta que ceden voluntariamente, se bloquean en I/O, salen, o reciben una señal que los bloquea/termina
- Futuro: Integración con interrupciones de timer para planificación preventiva con particiones de tiempo (ej: 10ms por proceso)
Integración de Señales
El planificador llama handle_signals() antes de cada cambio de contexto:
- Verifica señales pendientes en el proceso actual
- Maneja señales en orden de prioridad (SIGKILL, excepciones CPU, señales de terminación)
- Limpia máscara de bits de señales después del manejo
- Asegura que las señales se procesen síncronamente antes de que continúe la ejecución del proceso
Limitaciones
- Sin Prioridades: Todos los procesos tienen igual prioridad
- Sin Valores Nice: No se puede ajustar la prioridad del proceso
- Multitarea Cooperativa: Los procesos deben ceder voluntariamente
- Sin Prevención: Las interrupciones de timer no disparan cambios de contexto
- Cola Simple: Lista enlazada, no optimizada para muchos procesos
- Sin Balanceo de Carga: Solo una CPU (sin soporte SMP)
💾 Filesystem (Sistema de Archivos)
Sistema de archivos propio basado en EXT2 pero con innovaciones modernas. La característica distintiva
es la integración de una base de datos vectorial para optimizar las operaciones de búsqueda y
indexación de archivos.
Características Técnicas:
- Estructura de directorios jerárquica
- Soporte para archivos de hasta 2TB
- Journaling para recuperación ante fallos
- Compresión transparente de archivos
- Indexación vectorial para búsquedas rápidas
Innovaciones:
- Integración con libvictor para búsquedas semánticas
- Cache inteligente basado en patrones de acceso
- Soporte para metadata extendida
- Encriptación a nivel de archivo
Estado: En desarrollo activo
Archivos: fs/ext2.c, fs/victor_index.c, fs/journal.c
⚡ Sistema de Interrupciones
Sistema robusto de manejo de interrupciones y excepciones que garantiza la estabilidad del kernel
y proporciona una interfaz limpia para el manejo de eventos de hardware y software.
Componentes Principales:
- IDT (Interrupt Descriptor Table): Tabla de 256 entradas para mapear
interrupciones
- ISR (Interrupt Service Routines): Handlers optimizados en ensamblador
- Exception Handler: Manejo de excepciones del procesador
- IRQ Manager: Gestión de interrupciones de hardware
Características:
- Manejo completo de page faults con recovery automático
- Interrupciones anidadas con prioridades
- Deferred interrupt processing
- Interrupt coalescing para optimización
Archivos: interrupt/idt.c, interrupt/interrupt.asm, interrupt/isr_handlers.c,
interrupt/irq.c
🚀 Subsistema de Arranque
Sistema de inicialización que prepara el entorno para la ejecución del kernel, manejando la
transición desde el bootloader hasta el espacio de usuario.
Fases de Arranque:
- Fase 1: Inicialización del procesador y modo protegido
- Fase 2: Configuración de paginación y memoria virtual
- Fase 3: Inicialización de subsistemas críticos
- Fase 4: Carga del primer proceso (init)
Características:
- Soporte para múltiples arquitecturas (x86-64, ARM64)
- Bootloader independiente con soporte para UEFI
- Recuperación automática ante fallos de arranque
- Modo de recuperación integrado
Archivos: boot/boot.asm, boot/kmain.c, boot/arch.c, boot/kernel_start.c
🛡️ Gestión de Memoria
Sistema avanzado de gestión de memoria que proporciona aislamiento entre procesos, optimización
de rendimiento y protección contra accesos no autorizados.
Componentes:
- Memory Manager: Gestión de páginas físicas y virtuales
- Page Allocator: Asignación eficiente de memoria
- Slab Allocator: Optimización para objetos pequeños
- Memory Protection: Control de acceso y permisos
Características:
- Paginación de 4 niveles (48-bit addressing)
- Memory compression transparente
- NUMA awareness para sistemas multi-socket
- Memory deduplication
Archivos: mm/page_alloc.c, mm/slab.c, mm/vmalloc.c, mm/protection.c
🌐 Subsistema de Red
Pila de red completa basada en Linux pero optimizada para el kernel IR0, proporcionando
soporte para protocolos modernos y optimizaciones específicas.
Protocolos Soportados:
- TCP/IP stack completo
- UDP con optimizaciones de latencia
- HTTP/2 y HTTP/3
- QUIC para conexiones rápidas
- IPv6 con transición automática
Optimizaciones:
- Zero-copy networking
- Kernel bypass para aplicaciones de alto rendimiento
- Network function virtualization (NFV)
- Load balancing inteligente
Estado: Integración con Linux networking stack
Archivos: net/tcp.c, net/udp.c, net/socket.c, net/protocols/
🔧 Subsistema de Drivers
Framework modular para el desarrollo y gestión de drivers de hardware, con soporte para
hot-plugging y gestión automática de dispositivos.
Tipos de Drivers:
- Block Devices: Discos, SSDs, dispositivos de almacenamiento
- Character Devices: Terminales, dispositivos de entrada
- Network Devices: Tarjetas de red, WiFi, Bluetooth
- Graphics: GPUs, framebuffers, aceleración por hardware
Características:
- Driver framework unificado
- Auto-detection de hardware
- Power management integrado
- Driver signing y verificación
Archivos: drivers/core.c, drivers/block/, drivers/char/, drivers/net/
🔐 Sistema de Seguridad
Framework integral de seguridad que protege el kernel y los procesos de usuarios, implementando
múltiples capas de protección y auditoría de seguridad.
Componentes de Seguridad:
- Access Control: Control de acceso basado en roles (RBAC)
- Capability System: Sistema de capacidades granular
- Seccomp: Filtrado de syscalls para sandboxing
- LSM (Linux Security Modules): Módulos de seguridad intercambiables
Características:
- ASLR (Address Space Layout Randomization)
- Stack canaries y protección contra buffer overflows
- Kernel hardening automático
- Auditoría de eventos de seguridad
- Integración con TPM para medición de integridad
Archivos: security/capability.c, security/seccomp.c, security/lsm/, security/audit.c
⚡ Power Management
Sistema avanzado de gestión de energía que optimiza el consumo de batería en dispositivos móviles
y reduce el consumo energético en servidores, manteniendo el rendimiento.
Estados de Energía:
- Suspend to RAM: Suspensión rápida con recuperación instantánea
- Suspend to Disk: Hibernación completa
- Standby: Modo de espera de bajo consumo
- Dynamic Frequency Scaling: Ajuste dinámico de frecuencia CPU
Optimizaciones:
- CPU idle management inteligente
- Wake-on-LAN y wake-on-timer
- Power capping para servidores
- Thermal management automático
- Battery health monitoring
Archivos: power/suspend.c, power/cpuidle.c, power/thermal.c, power/battery.c
🎯 Virtualización
Subsistema de virtualización que permite ejecutar múltiples sistemas operativos simultáneamente,
con soporte para contenedores y máquinas virtuales completas.
Tipos de Virtualización:
- Containers: Aislamiento ligero con namespaces y cgroups
- KVM: Kernel-based Virtual Machine para VMs completas
- Xen: Hypervisor tipo 1 para virtualización bare-metal
- Docker/OCI: Soporte para estándares de contenedores
Características:
- Hardware-assisted virtualization (Intel VT-x, AMD-V)
- Nested virtualization
- Live migration de VMs
- GPU passthrough para aceleración gráfica
- Memory ballooning y overcommit
Archivos: virt/kvm/, virt/xen/, kernel/nsproxy.c, kernel/cgroup.c
📊 Monitoring y Debugging
Sistema completo de monitoreo y debugging que proporciona visibilidad profunda del funcionamiento
del kernel y permite el diagnóstico de problemas en tiempo real.
Herramientas de Debugging:
- Kprobes: Puntos de inserción dinámicos en el kernel
- ftrace: Tracer de funciones y eventos
- perf: Profiler de rendimiento avanzado
- eBPF: Programación dinámica del kernel
Métricas y Monitoreo:
- CPU, memoria y I/O profiling
- Network packet tracing
- System call monitoring
- Kernel panic analysis
- Performance counters
Archivos: kernel/trace/, kernel/debug/, kernel/profiling/, kernel/bpf/
🔧 Device Tree
Sistema de descripción de hardware que permite al kernel descubrir y configurar automáticamente
dispositivos de hardware sin necesidad de drivers específicos hardcodeados.
Características:
- Descripción declarativa del hardware
- Soporte para múltiples arquitecturas
- Overlays dinámicos para configuración
- Compatibilidad con firmware UEFI/ACPI
Beneficios:
- Boot más rápido en sistemas embebidos
- Configuración automática de dispositivos
- Portabilidad entre plataformas
- Reducción de código específico de plataforma
Archivos: drivers/of/, drivers/acpi/, drivers/firmware/
🎮 Graphics y Multimedia
Subsistema gráfico que proporciona aceleración por hardware, soporte para múltiples monitores
y capacidades multimedia avanzadas.
Componentes Gráficos:
- DRM (Direct Rendering Manager): Gestión de gráficos modernos
- KMS (Kernel Mode Setting): Configuración de modo de pantalla
- GEM (Graphics Execution Manager): Gestión de memoria gráfica
- V4L2: Video4Linux para captura de video
Características:
- Soporte para GPUs modernas (NVIDIA, AMD, Intel)
- Hardware acceleration para video
- Multi-head display
- HDR y color management
- VR/AR support
Archivos: drivers/gpu/drm/, drivers/media/, drivers/video/
🔊 Audio Subsystem
Sistema de audio avanzado que proporciona soporte para múltiples formatos, procesamiento
de audio en tiempo real y gestión de dispositivos de audio complejos.
Componentes de Audio:
- ALSA (Advanced Linux Sound Architecture): Framework de audio principal
- PulseAudio: Servidor de sonido para usuarios
- JACK: Audio profesional de baja latencia
- ASoC (ALSA System on Chip): Audio para sistemas embebidos
Características:
- Soporte para formatos HD (24-bit, 192kHz)
- Audio surround 7.1
- Noise cancellation
- Bluetooth audio (A2DP, aptX)
- MIDI y síntesis de audio
Archivos: sound/core/, sound/soc/, sound/pci/, sound/usb/
📱 Input/Output Subsystem
Sistema unificado de entrada y salida que maneja todos los dispositivos de interfaz de usuario,
desde teclados y ratones hasta pantallas táctiles y sensores.
Tipos de Dispositivos:
- HID (Human Interface Devices): Teclados, ratones, gamepads
- Touchscreens: Pantallas táctiles capacitivas y resistivas
- Sensors: Acelerómetros, giroscopios, magnetómetros
- Haptic Feedback: Vibración y feedback táctil
Características:
- Multi-touch support
- Gesture recognition
- Accessibility features
- Hot-plugging automático
- Power management para dispositivos
Archivos: drivers/input/, drivers/hid/, drivers/iio/