13 pontos por GN⁺ 2025-06-11 | 1 comentários | Compartilhar no WhatsApp
  • Sistema operacional experimental com interface gráfica, totalmente implementado em Rust, que usa um design de unikernel e um modelo de segurança com sandboxing baseado em WASM
  • O kernel, o motor WASM e todos os apps ficam embutidos em um binário EFI, oferecendo uma estrutura minimizada e uma interface de chamadas de sistema única
  • Funciona no QEMU por meio de drivers baseados em VirtIO, com entrada, rede e gerenciamento de GPU implementados por polling, sem interrupções
  • Suporta uma estrutura de execução simplificada e monitoramento de recursos por aplicativo por meio de um loop global de eventos e escalonamento cooperativo
  • Inclui a UI toolkit Uitk e apps integrados (navegador web, editor de texto, terminal Python), permitindo desenvolver apps WASM em várias linguagens

O que é o Munal OS

  • Munal OS é um sistema operacional experimental totalmente desenvolvido em Rust, criado para explorar um novo design de SO ao combinar uma arquitetura baseada em unikernel com sandboxing em WASM
  • O objetivo é reduzir a complexidade e aplicar apenas os elementos essenciais, buscando uma estrutura de sistema simplificada com ferramentas modernas

Principais características

  • Suporte a ambiente gráfico completo e resolução HD, com interface de mouse e teclado
  • Execução de apps em sandbox, bloqueando o acesso de aplicações de usuário à memória do kernel
  • Driver de rede e pilha TCP própria integrados
  • Inclui uma UI toolkit (Uitk) customizável, com vários widgets, layout flexível e renderização de texto
  • Apps incluídos por padrão: navegador web (com suporte a DNS, HTTPS e HTML básico), editor de texto e terminal Python

Arquitetura

  • Estrutura baseada em binário EFI

    • Executa no formato de binário EFI sem bootloader, com kernel/motor WASM/apps embutidos em um único arquivo
    • Os serviços de boot do UEFI são encerrados o mais rápido possível, sem uso adicional além do relógio do sistema
  • Gerenciamento de espaço de endereçamento

    • Não usa espaço de endereçamento virtual, reutilizando diretamente os endereços identity-mapped deixados pelo UEFI
    • Sem alterações na tabela de páginas. A proteção direta da memória do kernel é complementada pelo sandboxing em WASM
  • Drivers e suporte a hardware

    • Em vez de PS/2 ou VGA, implementa diretamente drivers PCI usando a especificação VirtIO 1.1
      • Há drivers para teclado, mouse, rede e GPU
    • Não usa interrupções; todos os drivers foram projetados com polling
    • Não oferece suporte para execução em hardware físico além do QEMU, exigindo desenvolvimento adicional no futuro
  • Loop de eventos e escalonamento

    • Sem suporte a multicore/interrupções, toda a execução acontece de forma linear em um único loop global de eventos
      • A cada loop, faz polling dos drivers de rede/entrada, executa a UI do desktop e os apps, e atualiza o framebuffer da GPU
    • Facilita a análise de desempenho, permitindo medir o tempo de cada ciclo do loop
    • Os apps precisam liberar o uso da CPU diretamente, e tarefas longas precisam ceder explicitamente
    • É baseado em escalonamento cooperativo, mas pode oferecer suporte ao encerramento forçado de apps com mau funcionamento por meio do recurso de limite de fuel do motor Wasmi (não implementado)

Estrutura de execução de aplicações

  • Inclui o [motor WASM Wasmi], oferecendo sandboxing completo e separação do kernel ao executar apps
  • Fornece uma API de chamadas de sistema no nível do kernel, permitindo que apps consultem eventos de mouse/teclado, usem sockets TCP e escrevam no framebuffer
  • O resultado de renderização dos apps é composto pelo SO e exibido no desktop
  • Também é possível criar apps em linguagens além de Rust; se houver suporte a build para WASM, não há restrição de uso
  • A compatibilidade com WASI é parcial. Não há conformidade completa; inclui apenas a implementação mínima para uso de dependências externas importantes
  • Cada app tem seu fluxo de logs dedicado (semelhante a stdout), que pode ser visto junto com o uso de recursos na visualização de “auditoria” do desktop

UI toolkit (uitk)

  • UI kit próprio em modo imediato, usado tanto pelo Munal OS quanto pelos apps WASM
  • Fornece widgets básicos (botões, barra de progresso, editor de texto, canvas com rolagem) e um rasterizador de triângulos
  • Estilização unificada baseada em stylesheet global, com suporte a overrides por elemento
  • Um sistema de cache eficiente evita rerenderizações desnecessárias
    • Divide cada área em “tiles” e usa um algoritmo de detecção de mudanças baseado nas regras de mutabilidade do Rust

Ambiente de build e execução

  • Pode ser compilado e executado com Rust Nightly 2025-06-01 e QEMU 10.0.0 ou superior

Principais referências e créditos

  • Tutorial de SO em Rust de Philipp Oppermann e documentação da OSDev Wiki
  • Uso de importantes projetos open source como Wasmi, smoltcp, Rustls e RustPython
  • Uso de várias fontes, ícones e wallpapers open source

Significado e vantagens do Munal OS

  • Reconsidera o paradigma tradicional de design de sistemas operacionais ao combinar uma estrutura de binário EFI único com sandboxing inovador
  • Otimizado para o ambiente QEMU, com uma estrutura singular de drivers baseados em polling e dependência mínima de hardware de sistema real
  • Oferece grande transparência no gerenciamento de recursos do sistema, com alto valor educacional e experimental graças à estrutura simples
  • Tem grande potencial para expandir o ecossistema de apps WASM sem restrições de linguagem ou ambiente

1 comentários

 
GN⁺ 2025-06-11
Comentários do Hacker News
  • Achei interessante a estrutura em que, a cada iteração, ele faz polling da rede e dos drivers de entrada, desenha a interface desktop, executa um passo de cada aplicação WASM ativa e depois descarrega o framebuffer da GPU. Fui procurar o código por curiosidade para ver como isso foi implementado com Wasmi link para o código no GitHub. Queria apontar que, nas versões mais recentes do Wasmi (v0.45+), a funcionalidade de chamadas retomáveis foi expandida para permitir yield quando o fuel se esgota link para a documentação do Wasmi. Como já está usando fuel metering, isso pode ser uma forma mais eficiente de executar por etapas. Há um exemplo de uso no exemplo do runner Wast do Wasmi

    • Mais uma vez, obrigado por criar o Wasmi. Essa novidade de poder dar yield quando o fuel acaba é realmente muito interessante. Fiquei decepcionado por não ter encontrado algo assim na documentação antiga; se isso existisse antes, a direção de design dos apps WASM teria sido diferente
    • Não sou o OP, mas não entendo muito bem por que isso ajuda. A pergunta é se isso significa que você pode transformar uma função em coroutine, iniciá-la e, se ela falhar no meio da execução por falta de memória, dar mais memória e depois fazer resume da coroutine. Se for isso, qual seria a diferença em relação ao comportamento atual? Também pergunto se não existe try/catch em WASM. Se, num estado de falha, ainda for preciso tentar o malloc de novo explicitamente, fico confuso sobre o que exatamente se ganha com isso
    • Fiquei empolgado ao ver que o Wasmi é rápido o bastante para rodar apps GUI. Estou desenvolvendo um runtime de apps para criar aplicações GUI altamente portáveis. Escolhi wasm buscando um equilíbrio entre performance e simplicidade de implementação, e espero que seja possível montar esse runtime de forma relativamente direta com uma equipe de uma pessoa ou poucas pessoas. O fato de um runtime wasm interpretado e otimizado como o Wasmi conseguir rodar apps GUI sem dificuldade me parece cheio de possibilidades
  • Como a estrutura depende de VirtIO, foi mencionado que o Munal OS ainda não roda em hardware real. Se fosse para operar em hardware real, acho que uma abordagem divertida, em vez de adicionar drivers diretamente, seria usar Linux como bootloader e executar o sistema operacional dentro de um hipervisor minimalista. Dessa forma, seria possível manter o conceito de que "VirtIO é a plataforma". A estrutura escolhe WASM para executar apps e VirtIO para a plataforma, e é elegante manter essa identidade. Mas, do ponto de vista de segurança, seria necessário usar MMU. Pelo desenho, talvez não fosse preciso introduzir memória virtual completa, mas só para usar bits de proteção já surgiriam complexidades adicionais, como tabelas de páginas e gerenciamento de TLB, o que enfraquece um pouco a simplicidade

    • Na minha última tentativa de Hackintosh, fiz algo parecido usando Linux como bootloader e hipervisor minimalista, e funcionou razoavelmente bem. A desvantagem é que, sem eventos reais da GPU, tudo fica preso à resolução e às configurações decididas pelo Linux, o que limita a liberdade. Se esse OS pudesse funcionar não como um OS de verdade, mas como um executável UEFI, talvez fosse possível fazer gráficos só com o driver de vídeo do UEFI, mas não tenho certeza se isso seria viável tentando manter funcionalidades de um sistema operacional de fato
  • Acho que a desvantagem maior, mais do que o fato de o loop principal não poder ocupar a CPU por muito tempo e de tarefas longas precisarem obrigatoriamente fazer yield de forma explícita, é que quanto mais apps você abre, mais lenta fica a taxa de processamento de cada um. Quase nunca abri mais de 10 apps ao mesmo tempo, mas já cheguei a 30 abas, e imagino que, se cada uma fosse um processo, a queda de desempenho seria bem clara. Se o hardware for rápido o suficiente, talvez não haja problema, mas em tarefas pesadas, como renderização de vídeo, por exemplo, dá para sentir facilmente a diferença entre levar 1 segundo e levar 30 segundos. Mesmo assim, implementar um OS inteiro desse jeito é algo muito inteligente, impressionante e empolgante

    • Os apps não precisam ficar mais lentos de jeito nenhum, desde que terminem o que têm para fazer a tempo. Eles executam, terminam e então esperam o próximo frame. Se faltar recurso a ponto de o tempo de espera cair para 0 ou menos, aí sim tudo desacelera, mas é um método menos elegante do que um scheduler justo mais complexo. Cada programa faz yield explicitamente quando termina de preparar seu frame, então apps sem trabalho praticamente não consomem tempo
  • Além do escalonamento cooperativo, parece difícil se defender de ataques Spectre, e fico em dúvida se dá para ter eficiência sem memória virtual. Por exemplo, ao lidar com memory.grow no WASM, se a memória de outro app estiver no caminho, pode surgir uma situação em que seja preciso fazer memmove do bloco inteiro, e fico me perguntando se isso é realmente viável. Ainda assim, é um projeto realmente impressionante

    • Se Spectre é um vetor de ataque aqui, qual é exatamente o modelo de ameaça assumido? Pela estrutura atual, todos os apps parecem ser compilados diretamente no kernel, e o navegador nem executa JavaScript, então nem parece haver um caminho de entrada para código não confiável
    • Gostaria de uma explicação mais detalhada
  • Fico curioso para saber como tentativas como essa vão mudar quando os componentes wasm se concretizarem. Gosto muito do design de unikernel, e o fato de o Munal OS já ter tanta funcionalidade também é impressionante. Espero que wasm seja usado não só para um único app grande, mas também para hospedar vários processos pequenos e subambientes. No wasi preview3, a possibilidade de coexistência entre síncrono e assíncrono deve se abrir em breve, e isso faria o wasm passar a ter praticamente todos os elementos de um runtime de propósito geral. Ainda acho uma pena que a ponte com objetos do host continue tão concentrada em JS, mas torço para que a promessa dos componentes wasm — padrão, leveza, sandbox e composição entre linguagens — se torne algo realmente executável no mundo real, como capacidade de runtime, e não apenas como um formato de distribuição. Também deixo esta palestra como referência What is a Component (and Why)

    • Ao falar desse tema, por acaso você queria mencionar este vídeo link do YouTube?
    • Comecei a fazer um app em Rust com suporte a SDL3 e V8 embutido para permitir scripting apresentação no blog. Mas algo que estou considerando seriamente é fazer um fork disso e embutir wasmtime ou wasmi para permitir scripting em qualquer linguagem. Seria possível até embutir compiladores e criar uma estrutura em que você só entrega um arquivo e ele já funciona como script. Isso porque wasmtime e wasmi são mais rápidos do que outros engines de scripting dados de comparação. O lado inconveniente é que seria preciso configurar todo o ambiente de código, então a vantagem de entrada como script fica menor. Mesmo assim, a ideia é boa demais para eu não querer tentar pelo menos uma vez
  • Vi na palestra “The Birth and Death of Javascript”, da Pycon 2014, a parte em que se apresenta um futuro em que asm.js, precursor do wasm atual, seria usado para implementar sandbox de OS, e isso me pareceu muito próximo do cerne deste projeto. Fiquei curioso se houve alguma influência link da palestra

    • Acho mais provável que a influência tenha vindo do Midori, o sistema operacional de pesquisa da Microsoft introdução ao Midori
  • Fiquei surpreso ao ver que esse OS inclui até um navegador web próprio código-fonte do navegador. No vídeo de demonstração dá para ver ele renderizando o Hacker News

    • Antes de recursos como JS, CSS e afins se acumularem nos navegadores, dava para ver a web com um navegador pequeno assim e com dependências mínimas, mas hoje isso infelizmente significa não conseguir visualizar a maior parte da web de forma útil. Acho que precisamos separar de forma mais clara a web de conteúdo da web de apps. A web de conteúdo precisa apenas de um cliente HTTP muito simples e um parser HTML; já os web apps, de forma parecida com este OS, poderiam ser baseados em wasm + um pequeno conjunto de APIs de hardware. Só que suporte a UDP seria indispensável
  • Fiquei impressionado e ao mesmo tempo curioso se esse tipo de estrutura poderia representar o futuro dos sistemas operacionais. Até o readme é bastante interessante. Também queria saber por que foi escolhido Wasmi em vez de wasmtime. Eu mesmo queria testar esse OS em uma VM e até tenho vontade de portar minha biblioteca GUI para o Munal

    • Compartilho a experiência de que compilar o wasmtime em modo no_std era trabalhoso demais, então no fim a escolha foi pelo wasmi
    • Acrescento a piada de que, quando se fala do futuro das estruturas modernas de OS, SPECTRE e MELTDOWN sempre acabam entrando na conversa
    • Também menciono que, no sentido de fazer isolamento de apps por virtualização, já estamos experimentando um futuro parecido no Qubes OS. Lá o isolamento entre apps é extremamente forte
  • Desde a época do Xerox PARC, vêm se repetindo tentativas de "transformar o user space em bytecode", e, na prática, os únicos casos que considero bem-sucedidos no mercado são IBM i, ChromeOS e Android. Ainda assim, este projeto é muito legal e espero que dê certo

    • Em toda thread sobre WebAssembly, parece que você repete essa história sobre VMs de bytecode antigas como um padrão já previsível. É sempre a mesma avaliação com o mesmo tom, mas em comunidades de desenvolvimento é inevitável que surjam tentativas variadas, erros, acertos e abordagens novas. Em vez desse reconhecimento de padrão tão básico, eu gostaria de ouvir uma opinião mais detalhada
    • Como esse conceito tem vantagens muito claras, novas tentativas inevitavelmente vão continuar surgindo até que ele se estabeleça de verdade como padrão. O wasm é bem diferente do JVM e afins justamente porque esse é, de fato, o objetivo dele
    • ChromeOS é apenas um navegador e usa V8 por acaso; e o Android teria sido bem-sucedido usando qualquer outra coisa. O sucesso desses dois sistemas não veio da tecnologia, mas do preço
  • O próprio design de um OS cliente já é surpreendente. Acho que esse tipo de estrutura também teria utilidade prática imediata em servidores. Se você reduzir o kernel ao mínimo e deixar só um app rodando, dá para diminuir fronteiras de segurança desnecessárias. Por exemplo, um key/value store parece um ótimo candidato para esse modelo. Minha curiosidade é se esse modelo de IO consegue entregar bom desempenho de rede e se, ao hospedar WASM, existe alguma técnica especial para reduzir cópias de memória desnecessárias