Escrevendo um OS em Rust

Philipp Oppermann's blog

Escrevendo um OS em Rust

Esta série de posts do blog cria um pequeno sistema operacional na linguagem de programação Rust. Cada post é um pequeno tutorial e inclui todo o código necessário, então você pode acompanhar se quiser. O código-fonte também está disponível no repositório Github correspondente.

Último post: Async/Await

Um Binário Rust Independente

O primeiro passo para criar nosso próprio kernel de sistema operacional é criar um executável Rust que não vincule a biblioteca padrão. Isso torna possível executar o código Rust no bare metal sem um sistema operacional subjacente.

ler mais »

Um Kernel Rust Mínimo

Neste post, criamos um kernel Rust mínimo de 64 bits para a arquitetura x86. Construímos sobre o binário Rust independente do post anterior para criar uma imagem de disco inicializável que imprime algo na tela.

ler mais »

Modo de Texto VGA

O modo de texto VGA é uma maneira simples de imprimir texto na tela. Neste post, criamos uma interface que torna seu uso seguro e simples ao encapsular toda a unsafety em um módulo separado. Também implementamos suporte para as macros de formatação do Rust.

ler mais »

Testes

Este post explora testes unitários e de integração em executáveis no_std. Usaremos o suporte do Rust para frameworks de teste customizados para executar funções de teste dentro do nosso kernel. Para reportar os resultados para fora do QEMU, usaremos diferentes recursos do QEMU e da ferramenta bootimage.

ler mais »

Exceções de CPU

Exceções de CPU ocorrem em várias situações errôneas, por exemplo, ao acessar um endereço de memória inválido ou ao dividir por zero. Para reagir a elas, precisamos configurar uma tabela de descritores de interrupção que fornece funções manipuladoras. Ao final desta postagem, nosso kernel será capaz de capturar exceções de breakpoint e retomar a execução normal posteriormente.

ler mais »

Double Faults

Esta postagem explora a exceção de double fault em detalhes, que ocorre quando a CPU falha ao invocar um manipulador de exceção. Ao manipular esta exceção, evitamos triple faults fatais que causam uma redefinição do sistema. Para prevenir triple faults em todos os casos, também configuramos uma Interrupt Stack Table para capturar double faults em uma pilha de kernel separada.

ler mais »

Interrupções de Hardware

Nesta postagem, configuramos o controlador de interrupção programável para encaminhar corretamente interrupções de hardware para a CPU. Para manipular essas interrupções, adicionamos novas entradas à nossa tabela de descritores de interrupção, assim como fizemos para nossos manipuladores de exceção. Aprenderemos como obter interrupções periódicas de timer e como obter entrada do teclado.

ler mais »

Introdução à Paginação

Esta postagem introduz paginação, um esquema de gerenciamento de memória muito comum que também usaremos para nosso sistema operacional. Ela explica por que o isolamento de memória é necessário, como segmentação funciona, o que é memória virtual, e como paginação resolve problemas de fragmentação de memória. Também explora o layout de tabelas de página multinível na arquitetura x86_64.

ler mais »

Implementação de Paginação

Esta postagem mostra como implementar suporte a paginação em nosso kernel. Ela primeiro explora diferentes técnicas para tornar os frames físicos da tabela de página acessíveis ao kernel e discute suas respectivas vantagens e desvantagens. Em seguida, implementa uma função de tradução de endereços e uma função para criar um novo mapeamento.

ler mais »

Alocação no Heap

Este post adiciona suporte para alocação no heap ao nosso kernel. Primeiro, ele fornece uma introdução à memória dinâmica e mostra como o verificador de empréstimos previne erros comuns de alocação. Em seguida, implementa a interface básica de alocação do Rust, cria uma região de memória heap e configura uma crate de alocador. Ao final deste post, todos os tipos de alocação e coleção da crate embutida alloc estarão disponíveis para o nosso kernel.

ler mais »

Designs de Alocadores

Este post explica como implementar alocadores heap do zero. Ele apresenta e discute diferentes designs de alocadores, incluindo alocação bump, alocação de lista encadeada e alocação de bloco de tamanho fixo. Para cada um dos três designs, criaremos uma implementação básica que pode ser usada para o nosso kernel.

ler mais »

Async/Await

Neste post, exploramos multitarefa cooperativa e a funcionalidade async/await do Rust. Fazemos uma análise detalhada de como async/await funciona em Rust, incluindo o design da trait Future, a transformação em máquina de estados e pinning. Então adicionamos suporte básico para async/await ao nosso kernel criando uma tarefa assíncrona de teclado e um executor básico.

ler mais »

Status Updates

These posts give a regular overview of the most important changes to the blog and the tools and libraries behind the scenes.

First Edition

You are currently viewing the second edition of “Writing an OS in Rust”. The first edition is very different in many aspects, for example it builds upon the GRUB bootloader instead of using the `bootloader` crate. In case you're interested in it, it is still available. Note that the first edition is no longer updated and might contain outdated information. read the first edition »

Apoie-me

Criar e manter este blog e as bibliotecas associadas dá muito trabalho, mas eu realmente gosto de fazê-lo. Ao me apoiar, você me permite investir mais tempo em novo conteúdo, novos recursos e manutenção contínua. A melhor forma de me apoiar é me patrocinar no GitHub. Obrigado!