Desenvolvendo o Diosix
Priorize Segurança > Correção > Manutenibilidade. Escreva
código Zig 0.17.0 idiomático e assembly RISC-V que seja autodocumentado, seguro quanto à memória e estritamente delimitado, de modo que cada alteração passe na revisão do reviewing-diosix na primeira tentativa, sem retrabalho pré-commit.
Mandamentos Centrais
- Código Funcional, Completo e Compilável (Pré-requisito Básico): Cada alteração deve compilar limpiamente tanto na construção da VM raiz/hipervisor quanto no conjunto de testes de unidade do host (
./scripts/build.she./scripts/build.sh test). Nunca deixe código quebrado, espaços reservadosTODO, caminhos de produção simulados ou funcionalidades parcialmente implementadas. - Limites de Linha e Arquivo (Componentize em Subpastas, Nunca Trunque): Quebre todo código e comentários em <= 80 colunas. Mantenha arquivos fonte <= 500 linhas. Quando um arquivo exceder 500 linhas, nunca trunque sua funcionalidade ou testes; decomponha-o em uma subpasta dedicada (
panes/vm.zig,vm/run.zig,tests/gui.zig) em vez de proliferar arquivos planosprefixo_subnome.zig(panes_vm.zig,vm_run.zig,tests_gui.zig), e conecte cada submódulo ao blocotestdo pai (_ = @import("vm/run.zig");). - Subpastas em Vez de Nomes com Prefixo-Underscore e Zero Cópia-e-Colagem: Use nomes de arquivo
snake_caseconcisos, sem prefixos redundantes de projeto, diretório ou irmãos (useapi.zig,main.c,vm/info.zigetests/nav.zig, nuncadiosix_api.zig,diosix-alsa-init.c,vm_info.zigoutests_nav.zig). Nunca duplique primitivas compartilhadas (comoSpinlock, matemática de alinhamento de página, validadores de travessia de caminho ou constantes ABI) entre módulos; importe-as dehypervisor/interface/,hypervisor/core/atomic.zigoucommon.zig. - Dispatch Idiomático: Nunca escreva cadeias de
if (std.mem.eql(...)) else if (...)para comandos, flags ou chaves de configuração. Defina umenum, analise comstd.meta.stringToEnum(EnumType, slice)e despache comswitch. - Tipos ABI Explícitos de Largura Fixa, Hexadecimais Minúsculos e Máscaras de Bits Nomeadas: Use tipos explícitos de largura fixa (
u64,u32,u16,u8) em todas as structs ABI/hardware (extern struct,packed struct) e estado de registros convidados de 64 bits — nuncausizeouunsigned longdo C. Sempre anote variáveis locais inicializadas a partir de@min/@maxcom um literal em tempo de compilação (const w: usize = @min(n, 1280);) para que o Zig não infira um tipo inteiro estreito (u11) que transborde posteriormente. Escreva todos os literais hexadecimais em minúsculas (0xfff,0xffff_ffff, nunca0xFFF), e substitua máscaras/deslocamentos mágicos ((vaddr & 0xfff) > 0xffc) por constantes nomeadas e auxiliares autodocumentados (PAGE_OFFSET_MASK,crossesPageBoundary(vaddr, @sizeOf(u32))). - Alocação Dinâmica em Vez de Suposição Estática: Apenas o código de boot em modo M, executado antes da inicialização do heap, pode usar buffers estáticos fixos. Assim que um alocador estiver disponível, aloque e cresça buffers dinamicamente em vez de adivinhar tamanhos fixos de buffer de pilha (por exemplo, evite
var buf: [4096]u8). - Propriedade e Limpeza de Memória: Emparelhe cada alocação (
alloc,create,dupe,print,mmap) imediatamente comdeferouerrdefer. Zere páginas de convidado liberadas e segredos criptográficos (std.crypto.secureZero). - Isolamento de Hipervisor Corporativo: Nunca entre em pânico no modo M devido a entrada ou estado do convidado; retorne um erro SBI ou termine a subárvore do convidado ofensora. Copie a memória do convidado compartilhada uma vez (
@memcpy) para a memória de propriedade do hipervisor antes da validação para evitar vulnerabilidades de dupla busca (TOCTOU). - Mecanismo no Código, Política na Configuração de Build/Execução: Nunca codifique configurações de nível de política ou padrões ajustáveis no código Zig. Mova ajustáveis e configurações para a configuração em tempo de build (
build.zigopções /boot/hypervisor.conf) ou arquivos de configuração em tempo de execução (/etc/diosix/*.toml, mantendochave = "valor"em linhas únicas <= 80 colunas). - Construa Binários e Imagens em Tempo de Build, Não Dinamicamente no Zig: Evite montar binários ELF, shims de código de máquina ou imagens de mídia palavra por palavra em tempo de execução no Zig. Mantenha shims em arquivos assembly ou Zig compilados durante o tempo de build, use scripts dedicados para construir imagens de mídia e nunca coloque saídas de build geradas dentro de
tools/overlay-common/(use.zig-cache/overlay-dynamic/). - Testes de Unidade Co-localizados e Testes de Integração Separados: Coloque blocos de teste
testdentro do arquivo fonte que testam (chamandostd.testing.refAllDecls(@This())). Coloque testes de integração de múltiplos componentes em diretóriostests/dedicados. - Compatibilidade Retroativa Sem Acúmulo de Fallbacks Legados: Preserve compatibilidade para contratos externos (ABI de hypercall SBI, ioctls
/dev/diosix, comandos CLIdsxdocumentados/esquemas JSON e arquivos/etc/diosix/*.tomlcriados pelo usuário), mas nunca acumule arrays de fallback de múltiplos caminhos (DEFAULT_GUEST_CANDIDATES) para encanamentos internos de versões co-versionadas. Quando produtor e consumidor são enviados juntos neste repositório, atualize todos os produtores, consumidores e testes na árvore atomicamente para usar um único caminho ou símbolo canônico, e lide com atualizações de layout de disco persistentes uma vez no limite de boot/instalação, em vez de sondar caminhos históricos para sempre. - Quando Não Tiver Certeza, Pare e Pergunte ao Mantenedor Principal: Nunca adivinhe sobre decisões arquiteturais, requisitos ambíguos ou capacidades de subsistema ausentes. Pare e pergunte ao mantenedor principal antes de prosseguir.
Ambientes de Execução Modo M vs. Modo U
| Aspecto | Modo M Hipervisor (hypervisor/) | Ferramentas Modo U (tools/) |
|---|---|---|
| Alvo | riscv64-freestanding-none | riscv64-linux-musl (ou host em testes) |
| Boot Pré-Heap | Slabs estáticos por núcleo (0..31) em entry.s | N/A (ambiente de processo do SO pronto em main) |
| Alocador | pcore.this().allocator.allocator() por núcleo | std.heap.SafeAllocator / page_allocator / ArenaAllocator |
| Política de Crash | Nunca entre em pânico com entrada do convidado; isole e termine a VM convidada ofensora | Retorne erro descritivo e código de saída limpo |
| Acesso a Hardware | CSR/MMIO direto (deve proteger com if (is_test) para testes de unidade do host) | ioctls /dev/diosix (api.zig), DRM/evdev, syscalls do Linux |
Guias de Referência Focados
Leia o arquivo de referência relevante antes de escrever ou modificar código:
- Idiomas e Builtins do Zig 0.17.0:
Sintaxe Zig 0.17 atualizada (
@backingInt,@splat,allocator.print,SafeAllocator,stringToEnum,@ptrCastparaextern struct, tipos ABI de largura fixa, anotações de tipo@min, formatação de 80 colunas com vírgulas finais, e pureza do cache de build). - Gerenciamento de Memória e Buffers Dinâmicos:
Padrões de alocador em modo M vs. modo U, crescimento de buffer dinâmico, disciplina
defer/errdefer, zeragem de segredos e inicialização de ponteiro de saída. - Arquitetura e Estilo Tiger: Implementação completa de funcionalidades, divisão modular de arquivos sem perder testes de unidade, zero duplicação por cópia e colagem, loops limitados, emparelhamento de asserções e higiene de overlay/configuração.
- RISC-V e Hipervisor Corporativo: Convenções de assembly RV64, simulação de CSR, contenção de raio de explosão, padrão de prevenção de dupla busca, ordenação de spinlock segura para IRQ e isolamento G-stage/PMP.