Desarrollando Diosix
Prioriza Seguridad > Protección > Corrección > Mantenibilidad. Escribe
Zig 0.17.0 y ensamblador RISC-V idiomáticos, autodocumentados, seguros en memoria
y estrictamente acotados para que cada cambio pase reviewing-diosix en el
primer intento sin necesidad de retrabajo previo al commit.
Mandatos Principales
- Código Funcional, Completo y Compilable (Requisito Básico): Cada cambio
debe compilar limpiamente tanto en la compilación del hipervisor/VM raíz como
en el conjunto de pruebas unitarias del host (
./scripts/build.shy./scripts/build.sh test). Nunca dejes código roto, marcadores de posiciónTODO, rutas de producción simuladas o funcionalidades implementadas parcialmente. - Límites de Línea y Archivo (Componentizar en Subcarpetas, Nunca Truncar):
Ajusta todo el código y comentarios a un máximo de <= 80 columnas.
Mantén los archivos fuente en <= 500 líneas. Cuando un archivo supere
las 500 líneas, nunca trunques su funcionalidad o pruebas; descomponlo en
una subcarpeta dedicada (
panes/vm.zig,vm/run.zig,tests/gui.zig) en lugar de proliferar archivos planosprefijo_subnombre.zig(panes_vm.zig,vm_run.zig,tests_gui.zig), y conecta cada submódulo al bloque detestdel padre (_ = @import("vm/run.zig");). - Subcarpetas sobre Nombres de Archivo con Guion Bajo Prefijo y Cero Copia-Pega:
Usa nombres de archivo concisos en
snake_casesin prefijos redundantes del proyecto, directorio o hermanos (usaapi.zig,main.c,vm/info.zigytests/nav.zig, nuncadiosix_api.zig,diosix-alsa-init.c,vm_info.zigotests_nav.zig). Nunca dupliques primitivas compartidas (comoSpinlock, matemáticas de alineación de páginas, validadores de recorrido de rutas o constantes ABI) entre módulos; impórtalas desdehypervisor/interface/,hypervisor/core/atomic.zigocommon.zig. - Despacho Idiomático: Nunca escribas cadenas
if (std.mem.eql(...)) else if (...)para comandos, banderas o claves de configuración. Define unenum, analiza constd.meta.stringToEnum(EnumType, slice)y despacha conswitch. - Tipos ABI Explícitos de Ancho Fijo, Hexadecimal en Minúsculas y Máscaras de Bits Nombradas:
Usa tipos de ancho fijo explícitos (
u64,u32,u16,u8) en todos los structs ABI/hardware (extern struct,packed struct) y en el estado de registros invitados de 64 bits; nuncausizeniunsigned longde C. Anota siempre las variables locales inicializadas desde@min/@maxcon un literal en tiempo de compilación (const w: usize = @min(n, 1280);) para que Zig no infiera un tipo entero estrecho (u11) que desborde más adelante. Escribe todos los literales hexadecimales en minúsculas (0xfff,0xffff_ffff, nunca0xFFF), y reemplaza las máscaras/desplazamientos mágicos ((vaddr & 0xfff) > 0xffc) con constantes nombradas y ayudantes autodocumentados (PAGE_OFFSET_MASK,crossesPageBoundary(vaddr, @sizeOf(u32))). - Asignación Dinámica sobre Estimación Estática: Solo el código de arranque
temprano en modo M que se ejecuta antes de la inicialización del montón puede
usar búferes estáticos fijos. Una vez que un asignador esté disponible,
asigna y crece búferes dinámicamente en lugar de estimar tamaños fijos de
búferes en la pila (por ejemplo, evita
var buf: [4096]u8). - Propiedad de Memoria y Limpieza: Empareja cada asignación (
alloc,create,dupe,print,mmap) inmediatamente condeferoerrdefer. Pon a cero las páginas de invitados liberadas y los secretos criptográficos (std.crypto.secureZero). - Aislamiento de Hipervisor Empresarial: Nunca entres en pánico en modo M
debido a entrada o estado del invitado; devuelve un error SBI o termina el
subárbol del invitado ofensor. Copia la memoria compartida del invitado una
sola vez (
@memcpy) en memoria propiedad del hipervisor antes de la validación para prevenir vulnerabilidades de doble captura (TOCTOU). - Mecanismo en Código, Política en Configuración de Compilación/Ejecución:
Nunca codifiques configuraciones de políticas o valores predeterminados
ajustables en código Zig. Mueve los ajustables y configuraciones a la
configuración en tiempo de compilación (opciones de
build.zig/boot/hypervisor.conf) o archivos de configuración en tiempo de ejecución (/etc/diosix/*.toml, manteniendokey = "value"en líneas individuales <= 80 columnas). - Compilar Binarios e Imágenes en Tiempo de Compilación, No Sobre la Marcha en Zig:
Evita ensamblar binarios ELF, shims de código máquina o imágenes de medios
palabra por palabra en tiempo de ejecución en Zig. Mantén los shims en
archivos de ensamblador o Zig compilados durante la compilación, usa
scripts dedicados para construir imágenes de medios, y nunca coloques
salidas de compilación generadas dentro de
tools/overlay-common/(usa.zig-cache/overlay-dynamic/). - Pruebas Unitarias Co-localizadas y Pruebas de Integración Separadas:
Coloca los bloques de
testunitarios dentro del archivo fuente que prueban (llamando astd.testing.refAllDecls(@This())). Coloca las pruebas de integración de múltiples componentes en directoriostests/dedicados. - Compatibilidad Hacia Atrás Sin Acumulación de Fallbacks Heredados:
Preserva la compatibilidad para contratos externos (ABI de hiperllamadas
SBI, ioctls
/dev/diosix, comandos CLIdsxdocumentados/esquemas JSON, y archivos/etc/diosix/*.tomlescritos por el usuario), pero nunca acumules arrays de fallback de múltiples rutas (DEFAULT_GUEST_CANDIDATES) para tuberías internas con versiones compartidas. Cuando el productor y el consumidor se envían juntos en este repositorio, actualiza todos los productores, consumidores y pruebas en el árbol atómicamente para usar una sola ruta o símbolo canónico, y maneja las actualizaciones de diseño de disco persistentes una vez en el límite de arranque/instalación en lugar de sondear rutas históricas para siempre. - Cuando Estés Inseguro, Detente y Pregunta al Mantenedor Principal: Nunca adivines sobre decisiones arquitectónicas, requisitos ambiguos o capacidades faltantes de subsistemas. Detente y pregunta al mantenedor principal antes de proceder.
Entornos de Ejecución Modo M vs. Modo U
| Aspecto | Hipervisor en Modo M (hypervisor/) | Herramientas en Modo U (tools/) |
|---|---|---|
| Objetivo | riscv64-freestanding-none | riscv64-linux-musl (o host en pruebas) |
| Arranque Pre-Montón | Losas estáticas por núcleo (0..31) en entry.s | N/A (entorno de proceso del sistema operativo listo en main) |
| Asignador | pcore.this().allocator.allocator() por núcleo | std.heap.SafeAllocator / page_allocator / ArenaAllocator |
| Política de Fallos | Nunca entrar en pánico por entrada del invitado; aislar y terminar la VM invitada ofensora | Devolver error descriptivo y código de salida limpio |
| Acceso a Hardware | CSR/MMIO directo (debe protegerse con if (is_test) para pruebas unitarias del host) | ioctls /dev/diosix (api.zig), DRM/evdev, llamadas al sistema de Linux |
Guías de Referencia Enfocadas
Lee el archivo de referencia relevante antes de escribir o modificar código:
- Modismos y Funciones Incorporadas de Zig 0.17.0:
Sintaxis actualizada de Zig 0.17 (
@backingInt,@splat,allocator.print,SafeAllocator,stringToEnum,@ptrCastparaextern struct, tipos ABI de ancho fijo, anotaciones de tipo@min, formato de 80 columnas con comas finales y pureza de caché de compilación). - Gestión de Memoria y Búferes Dinámicos:
Patrones de asignador en modo M vs. modo U, crecimiento dinámico de búferes,
disciplina
defer/errdefer, puesta a cero de secretos e inicialización de punteros de salida. - Arquitectura y Estilo TigerStyle: Implementación completa de funcionalidades, división modular de archivos sin perder pruebas unitarias, duplicación cero de copia- pega, bucles acotados, emparejamiento de aserciones e higiene de superposición/configuración.
- RISC-V e Hipervisor Empresarial: Convenciones de ensamblador RV64, simulación de CSR, contención de radio de explosión, patrón de prevención de doble captura, ordenamiento de spinlocks seguros para IRQ y aislamiento G-stage/PMP.