feat(renaser): Fase 7a — el userspace nace del Grafo de Objetos

El kernel deja de empotrar las apps. Las cinco aplicaciones ya no
llegan por include_bytes! en main.rs: nacen del grafo, gobernadas por
un Manifiesto de Génesis que también vive en el grafo.

- almacen: el SuperBloque gana el ancla `manifiesto: Option<Hash>`
  (gemela de `raiz`, del lado del kernel) + accesores. VERSION 1→2 —
  un disco v1 se reformatea.
- manifiesto.rs: implementados `cargar` (lee el manifiesto del grafo)
  y `sembrar_genesis` (puebla un disco virgen con las 5 apps de
  génesis). El bytecode viaja empotrado AÚN, sólo como semilla
  transitoria (la Fase 7b lo mueve al constructor de imagen `boot`).
- kernel_main: `cargar_userspace` reemplaza las 5 `encender_app`
  escritas a mano; `encender_app` recupera el bytecode del grafo —
  `recuperar` verifica el hash, un módulo corrupto se niega y el
  arranque sigue.
- wasm: el techo de memoria pasa a ser por-app (del manifiesto).

Compila limpio. Verificación en QEMU pendiente (la corre el operador):
la pantalla debe verse idéntica a la Fase 6.2 + la línea «manifiesto».

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-22 15:11:47 +00:00
parent 4f31146533
commit bce4abd8cc
6 changed files with 302 additions and 100 deletions
+14 -3
View File
@@ -35,7 +35,11 @@ const FUEL_FOTOGRAMA: u64 = 2_000_000;
/// Techo de memoria lineal por aplicacion: 4 MiB. Un modulo que intente crecer
/// su memoria mas alla es desalojado — el aislamiento ESPACIAL del userspace,
/// gemelo del techo TEMPORAL que impone el combustible.
const TECHO_MEMORIA: usize = 4 * 1024 * 1024;
///
/// Desde la Fase 7 el techo es POR-APP: cada `EntradaApp` del manifiesto
/// lleva el suyo. Esta constante es el valor por DEFECTO — el que usan las
/// apps de genesis (ver `manifiesto::genesis`).
pub(crate) const TECHO_MEMORIA: usize = 4 * 1024 * 1024;
/// Por que el kernel da por terminada —desaloja— una aplicacion WASM.
#[derive(Clone, Copy)]
@@ -88,7 +92,14 @@ impl AplicacionWasm {
/// El nuevo ABI del userspace exige dos exportaciones: `init` —invocada una
/// sola vez, aqui— y `tick` —un fotograma de trabajo, invocada despues por
/// el reactor en cada pulso del reloj.
pub fn cargar(bytecode: &[u8], region: RegionPantalla) -> Result<AplicacionWasm, FallaApp> {
///
/// `techo_memoria` es la cuota de memoria lineal de ESTA app, en bytes —
/// desde la Fase 7 la dicta su `EntradaApp` del manifiesto.
pub fn cargar(
bytecode: &[u8],
region: RegionPantalla,
techo_memoria: usize,
) -> Result<AplicacionWasm, FallaApp> {
// 1. El motor, con metricas de combustible y compilacion ANTICIPADA: la
// traduccion del modulo ocurre ahora, de modo que el `fuel` mida
// despues solo EJECUCION, jamas compilacion diferida.
@@ -106,7 +117,7 @@ impl AplicacionWasm {
// ya con la app cargada: una carga fallida no deja canales huerfanos.
let canal = crate::async_system::teclado::crear_canal();
let limites = StoreLimitsBuilder::new()
.memory_size(TECHO_MEMORIA)
.memory_size(techo_memoria)
// Una expansion denegada se convierte en TRAMPA, no en un -1 que la
// app pudiera ignorar: asi el kernel la captura y la desaloja.
.trap_on_grow_failure(true)