La Fase 11 dio al userspace un reloj; la Fase 12, una voz. Hasta hoy renaser solo sabía dibujar para llamar la atención. - Driver `drivers/altavoz`: el canal 2 del PIT como generador de onda cuadrada + la compuerta del puerto 0x61. El canal 0 —latido del kernel— no se toca. `tono(hz)` es su única vía; un 0 la silencia. - Capacidad `sys_tono(frecuencia_hz)` — la undécima función del host. La bocina es un recurso único: pertenece a la ventana ENFOCADA, como el teclado desde la Fase 8c. Al cambiar el foco, el compositor la calla; la nueva dueña la reclama en su próximo fotograma. - App nueva `tonada` (`apps/tonada/`, wasm32): toca una escala de Do mayor y la dibuja como una escalera de barras. Junta el reloj (`sys_tiempo_mono`) y la bocina (`sys_tono`). - `GENESIS` crece de 6 a 7 apps; `tonada` es la maestra del escritorio. Verificado en QEMU. Visual: la escalera de `tonada` recorre la escala con el tiempo. Sonido: con la bocina enrutada a un WAV, el PCM capturado es una onda cuadrada oscilante de ~375 Hz — la frecuencia media de la escala de Do mayor. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
12 KiB
renaser — Hoja de ruta
Estado de las fases del proyecto. Para la arquitectura, ver ARCHITECTURE.md.
Fases completadas
Todas verificadas en QEMU (captura de pantalla incluida en su momento).
Fase 1 — el primer microsegundo
Arranque UEFI, adopción del framebuffer GOP, lienzo de doble búfer y la baliza
de pánico (franja roja al colapsar). Punto de entrada con bootloader_api.
Fase 1.5 — empaquetado y arranque
Miembro boot/: constructor de la imagen de disco UEFI (crate bootloader
0.11, vía dependencia de artefacto) y lanzador de QEMU. cargo run pasa a
compilar, forjar la imagen y arrancar, todo de un gesto.
Fase 2.0 — cimientos del manejo de fallos
GDT propia + TSS con stack de emergencia (IST) para el doble fallo. IDT con manejadores de excepción de CPU. El breakpoint es recuperable; el resto de excepciones encienden la baliza.
Fase 2.1 — interrupciones de hardware
Remapeo del PIC 8259 fuera del rango de las excepciones. Temporizador (PIT) a 100 Hz e IRQ1 de teclado. El kernel pasa de "pintar una vez" a un bucle de render despertado por el hardware.
Fase 3 — memoria dinámica y reactor asíncrono
Heap de 64 MiB con linked_list_allocator como asignador global; manejador
propio de OOM (franja naranja). Reactor cooperativo: Executor, Task,
Waker. Texto vectorial con fontdue: el texto deja de ser mapa de bits.
Fase 4 — el escudo de aislamiento WASM
Runtime wasmi no_std. Matriz de capacidades con dos funciones de host
(sys_render_frame, sys_get_scancode) y validación infranqueable de límites
de la memoria lineal. Primera app del userspace: apps/hello_wasm, un módulo
wasm32 aislado que pinta y responde al teclado.
Fase 5 — multitarea cooperativa, fuel y reloj
Unificación del reactor (Fase 3) y el runtime WASM (Fase 4). El ABI del
userspace pasa a init/tick: cada tick es un punto de cesión cooperativa.
async_system::reloj convierte la IRQ0 en el Future EsperaFrame, que marca
el compás de los fotogramas. Cada app es una AplicacionWasm persistente y una
tarea del reactor. Escudo de combustible (fuel): cada tick corre con un
presupuesto estricto; agotarlo desaloja la app sin tocar al kernel. Capacidades
ampliadas — regiones de dibujo por app y canal de teclado por app. Verificado
en QEMU con tres apps concurrentes, una de ellas díscola y desalojada en vivo.
Fase 6.0 — cuotas de memoria y ciclo de vida
Completa el aislamiento espacial del userspace. Cada AplicacionWasm instancia
su Store con un StoreLimits (techo de memoria lineal de 4 MiB, vía
Store::limiter); rebasarlo es una trampa que desaloja la app con baliza
amarilla — gemela de la púrpura del desalojo por combustible. Drop para
AplicacionWasm reconcilia el ciclo de vida: da de baja el canal de teclado de
la difusión de la IRQ1. Verificado en QEMU con cuatro apps — una díscola
(desalojo temporal) y una glotona (desalojo espacial), ambas en vivo.
Fase 6.1 — sustrato de almacenamiento (completada)
Estrategia incremental para el almacenamiento, frente al riesgo del hardware:
- 6.1a — Sonda PCI (hecha) —
drivers/pci.rsenumera el bus PCI por0xCF8/0xCFCy localiza el disco virtio-blk;bootforja el disco de pruebas y lo adjunta comovirtio-blk-pci. El muro del descubrimiento de hardware queda derribado. - 6.1b — HAL y lectura de sector (hecha) —
drivers/disco.rs: asignador de marcos «bump»,KernelHal(eltrait Haldevirtio-drivers: DMA y traducción de direcciones) ymontar_y_leer_sector0, que lee el sector 0 por sondeo. Verificado por una firma que viaja del anfitrión al disco y vuelve. - 6.1c — Grafo de objetos (hecha) —
almacen.rs: el almacenamiento como DAG direccionado por contenido —la identidad de un objeto es el hash BLAKE3 de su forma serializada (postcard); el disco se organiza como un log con superbloque e índice—, y las cinco capacidadessys_object_*que lo exponen al userspace.drivers/disco.rsgana un asignador de marcos con liberación real (mapa de bits), escritura de sectores y unVirtIOBlkpersistente. La appcronistalleva la cuenta de los arranques en el grafo: la cuenta perdura entre reinicios.
Fase 6.2 — E/S de disco asíncrona por interrupción (completada)
La Fase 6.1 hizo hablar al disco, pero por sondeo: el procesador se quedaba en espera activa vigilando el used ring de virtio. La 6.2 libera el planificador cooperativo — la E/S de bloques pasa a ser reactiva:
EsperaDisco— una transferencia de bloques comoFuturenativo, sobre la API no bloqueante devirtio-drivers(read_blocks_nb/peek_used/complete_*). Cede la CPU mientras el disco trabaja.- La IRQ del disco —
montardescubre la línea de IRQ legada del dispositivo (registro «Interrupt Line» del espacio de configuración PCI), la enruta por el 8259 y registra su manejador;atender_irqreconoce la interrupción y despierta a la tarea que aguardaba el bloque. bloquear_en— el puente para los contextos síncronos (el arranque, las capacidades WASM): duerme la CPU conhlten vez de sondear.
Decisión de ingeniería: las IRQ se enrutan por el PIC 8259 que el kernel ya gobierna, no por el IOAPIC — basta leer la línea que el firmware ya asignó. Verificado en QEMU: el disco se enruta a la IRQ 11; una tarea-sonda del reactor lee un bloque de forma asíncrona mientras las apps siguen pintando.
Fase 7 — el userspace nace del Grafo de Objetos (completada)
Hasta la Fase 6, el userspace venía empotrado en el binario del kernel:
cuatro include_bytes! de .wasm y regiones escritas a mano. La Fase 7 lo
destierra — las aplicaciones pasan a ser objetos del grafo, gobernadas por un
Manifiesto de Génesis que también vive en el grafo. Plan completo en
FASE7.md.
- 7a — el Manifiesto (completada).
manifiesto.rs: tiposManifiesto/EntradaAppy carga desde el grafo. El superbloque gana el anclamanifiesto(VERSION 1→2).kernel_mainlee el manifiesto e instancia cada app recuperando su bytecode del grafo, verificado por su hash. - 7b — la imagen sembrada por
boot(completada). Nace la crateformato, un núcleono_stdcon el formato del grafo en disco, COMPARTIDO por el kernel y el constructor de imagenboot.bootsiembra el disco virgen con el grafo ya poblado —bytecode y manifiesto—; el kernel pierde todoinclude_bytes!del userspace. Su binario ya no carga ni un.wasm. - 7c — persistencia inter-sesión (completada). La app
memoriosagraba su estado como un objeto del grafo; el kernel lo ancla en la ranuraEntradaApp.estadoy re-graba el manifiesto. Al despertar,initlo relee y la app retoma donde quedó. Capacidadessys_estado_cargar/sys_estado_guardar; el kernel custodia un manifiesto VIVO y mutable.
Fase 8 — el compositor teselante e interactivo (completada)
El kernel deja de colocar las ventanas a mano: las tesela. El motor es
mirada-layout —el mismo núcleo no_std que ordena el compositor Wayland de
brahman—, enlazado por path cruzando la frontera de workspace. Plan completo
en FASE8.md.
- 8a — el compositor tesela (completada).
compositor.rscalcula un marco por app con el algoritmoMasterStack. El kernel centra el fotograma natural de cada app dentro de su marco; las apps no cambian una instrucción.region_x/ydel manifiesto quedan vestigiales — la posición la decide el compositor. - 8b — teselado interactivo (completada).
Alt+Espaciocicla los modos de teselado en caliente. El kernel cachea el último fotograma de cada app y recompone desde la caché: las apps estáticas sobreviven al re-teselado sin enterarse del cambio. - 8c — foco y enrutamiento selectivo (completada). Una ventana enfocada,
con borde índigo;
Alt+J/Alt+Kmueven el foco entre las ventanas vivas. El teclado deja de difundir: entrega cada tecla sólo a la app enfocada. - 8d — manipulación de ventanas (completada). El orden de teselado se
separa de la identidad de las ventanas.
Alt+Enterpromueve la ventana enfocada a la celda maestra;Alt+H/Alt+Lla reordenan. El foco viaja con la ventana.
Fase 9 — orden-Z y ventanas flotantes (completada)
El teselado de la Fase 8 repartía la pantalla sin solapamiento. La Fase 9 suma
un segundo modelo de composición —el SOLAPAMIENTO—: una ventana puede abandonar
el teselado y FLOTAR sobre las demás. Verificada en QEMU (sendkey).
- El
Escritoriosepara dos capas: las ventanas TESELADAS, al fondo; y las FLOTANTES, encima, apiladas en un orden-Z (flotantes, de atrás hacia adelante). Juntas son una partición de las ventanas. Alt+Falterna la ventana enfocada entre teselada y flotante. Una flotante nace con un marco propio, en cascada, y al frente del orden-Z; al volver al teselado se reincorpora a la rejilla, que se recalcula.- Con flotantes vivas, el kernel deja de pintar ventana a ventana: RECOMPONE el escritorio entero, capa a capa de atrás hacia adelante —el solapamiento se resuelve por el orden del pintado—. Sin flotantes conserva el camino rápido de la Fase 8.
- El foco recorre todas las ventanas; al posarse en una flotante, la alza al frente: la flotante enfocada está siempre delante.
Fase 10 — alta y baja de aplicaciones en vivo (completada)
Hasta la Fase 9 el censo de aplicaciones se fijaba en el arranque. La Fase 10
lo vuelve DINÁMICO: una app puede nacer o cerrarse con el reactor ya en marcha.
Verificada en QEMU (sendkey).
- El reactor admite NACIMIENTOS en vivo: una cola que
engendraralimenta y que el ejecutor drena al inicio de cada vuelta, adoptando cada futuro como tarea. El censo de tareas deja de ser inmutable tras el arranque. Alt+Qcierra la app enfocada: una baja LIMPIA. El compositor saca la ventana del teselado y del orden-Z; la app, al advertir la baja, concluye su tarea yAplicacionWasm::droplibera su memoria, su combustible y su canal.Alt+Nlanza una app nueva:nacer_ventanala añade y entrega su índice; el orquestador instancia el WASM y engendra su tarea. Las apps de génesis dejan su bytecode cacheado como plantilla; cadaAlt+Ninstancia una en rotación.- El censo de ventanas sólo crece —los índices son la identidad, jamás se reciclan—; una ventana cerrada queda como ranura inerte, fuera del teselado.
Fase 11 — el reloj del sistema como capacidad de host (completada)
Hasta la Fase 10 una aplicación sólo sabía cuántas veces la habían llamado, no
cuánto tiempo había pasado. La Fase 11 le da al userspace un sentido del
tiempo. Verificada en QEMU (sendkey).
- Capacidad
sys_tiempo_mono: los milisegundos monótonos desde el arranque —la décima función del host—. El temporizador (PIT) ya late a 100 Hz;relojexpone esa cuenta yenvla inyecta. Lectura pura, jamás retrocede. - App nueva
pulso: un compás visual cuya escena es una función PURA del reloj del host. Dos instancias, nazcan cuando nazcan, laten al unísono — la prueba de que el tiempo es absoluto, no una cuenta de fotogramas. - El userspace de génesis crece de 5 a 6 apps.
Fase 12 — la bocina del PC como capacidad de host (completada)
La Fase 11 le dio al userspace un reloj; la Fase 12, una voz. La bocina del PC se suma a la matriz de capacidades. Verificada en QEMU.
- Driver
drivers/altavoz: el canal 2 del PIT como generador de onda cuadrada- la compuerta del puerto 0x61. El canal 0 (latido del kernel) no se toca.
- Capacidad
sys_tono(frecuencia_hz)—la undécima—. La bocina es un recurso único: pertenece a la ventana ENFOCADA, como el teclado desde la Fase 8c. Al cambiar el foco, el compositor la calla. - App nueva
tonada: toca una escala de Do mayor y la dibuja como una escalera de barras. Junta el reloj (sys_tiempo_mono) y la bocina (sys_tono). El userspace de génesis crece de 6 a 7 apps. - Verificado por captura: la onda cuadrada de la bocina, enrutada a un WAV, late a la frecuencia media de la escala.
Líneas abiertas posteriores: reciclado de las ranuras de ventana cerradas; audio con varias voces (PCM) más allá del tono único de la bocina.
Principios que persisten entre fases
- Reutilizar infraestructura madura de la comunidad antes que reinventar.
unsafemínimo, confinado y justificado.- Verificar cada fase en QEMU antes de cerrarla.
git commit+git pushtras cada iteración.