Criando um sistema operacional com ASM e C++

O assunto que não é muito difundido, ganha um novo episódio. Com uma didática direcionada ao publico leigo e mediano, veja como é possível criar seu próprio núcleo básico de sistema operacional do zero, com Assembly e C++. Um desafio realmente tangível.

[ Hits: 59.486 ]

Por: Gabriel Marinho em 11/09/2013


Compilação e linkagem



Com nossos arquivos devidamente criados e com o código correto, vamos ao passo mais importante: a compilação.

Irei mostrar como compilar passo a passo, mas se quiser automatizar o processo, pode ser feito por meio de um makefile. Caso queira um pronto, fique à vontade para baixar o makefile do ErdOS e utilizar em seu SO:
Compilando nosso lançador:

nasm -f elf32 -o start.o start.asm

Note que é criado um arquivo ".o". Ele é o objeto compilado de nosso lançador. Nós faremos isto algumas vezes durante nosso processo de compilação.

Vamos compilar agora nosso arquivo principal e driver de vídeo:

g++ -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -fpermissive -m32 -c libc/io.cpp
$ g++ -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -fpermissive -m32 -c main.cpp


Finalizando a compilação de nosso código fonte, iremos precisar juntar tudo. Para isto, iremos utilizar o linker ld e nosso arquivo de configurações para ele, o "link.ld":

ld -m elf_i386 -T link.ld -o bin/kernel.bin obj/start.o obj/main.o obj/io.o

Note que, ao completar o processo de junção, você irá obter um arquivo chamado "kernel.bin" dentro do diretório bin. Isto já é seu kernel pronto.

Para ver como ficou, você pode utilizar a máquina virtual QEMU:

cd bin
$ qemu-system-i386 -kernel kernel.bin


Após o boot do QEMU, você verá o resultado de seu trabalho:
Linux: Criando um sistema operacional com ASM e C++
ErdOS rodando sob QEMU na distribuição Ubuntu


Finalização

Este é apenas o início de sua jornada com sistemas operacionais. Com este simples artigo, espero ter esclarecido algumas dúvidas e deixar um material completamente funcional em nossa língua.

Me disponho a responder dúvidas à medida do possível. Sempre mande sua dúvida, sugestão ou crítica. Fique à vontade para me dar aquele "tapa na cara", se for o caso.

Se você tem interesse em levar adiante, contribua com o projeto ErdOS no GitHub, ou caso queira fazer testes e levar para outro rumo, também fique à vontade para criar seu próprio fork:
Muito obrigado por ter prestigiado este artigo.

Me siga no Twitter: @gabrielbiga
Até a próxima.

Página anterior    

Páginas do artigo
   1. Introdução / Preparação
   2. Estrutura de arquivos
   3. Compilação e linkagem
Outros artigos deste autor

Configurando o X e a placa de vídeo NVidia no Debian Sarge

Tocando arquivos MP3 no SuSE Linux

Leitura recomendada

Substituindo a biblioteca conio.h no Linux usando ncurses curses.h

Criando aplicativos para o Mac OS X no GNU/Linux

Túnel do Tempo: a função itoa()

Utilizando a biblioteca NCURSES - Parte III

Programando com uma granada de mão: uma visão da linguagem C

  
Comentários
[1] Comentário enviado por lcavalheiro em 11/09/2013 - 04:09h

Hm... Realmente interessante

[2] Comentário enviado por zendrael em 11/09/2013 - 14:15h

Gabriel, legal o artigo!

Tem como compilar pra ARM?

[3] Comentário enviado por gabrielbiga em 11/09/2013 - 14:42h

Infelizmente não zendrael. Para rodar em ARM teriam que ser feitas algumas mudanças no lançador, meios de compilação e a troca do bootloader para um GRUB que rode em ARM. Mas está ai uma outra coisa legal a se fazer com o projeto... Um port para ARM. Voluntários? :)

[4] Comentário enviado por zendrael em 11/09/2013 - 14:59h


[3] Comentário enviado por gabrielbiga em 11/09/2013 - 14:42h:

Infelizmente não zendrael. Para rodar em ARM teriam que ser feitas algumas mudanças no lançador, meios de compilação e a troca do bootloader para um GRUB que rode em ARM. Mas está ai uma outra coisa legal a se fazer com o projeto... Um port para ARM. Voluntários? :)


Opa, eu topo! Só não sei por onde começar... Hahahah!

Talvez usando o uBoot para ARM já resolva/ajude em alguma coisa!

[5] Comentário enviado por Anonymous267 em 12/09/2013 - 10:29h

Interessante e fácil de ser feito o seu tutorial vou tentar fazer aqui obrigado.

[6] Comentário enviado por dannyalisson em 12/09/2013 - 16:58h

Parabéns, excelente artigo.

[7] Comentário enviado por Buckminster em 12/09/2013 - 19:19h

Muito bom. Parabéns.

[8] Comentário enviado por lucas-lks em 16/09/2013 - 07:42h

Muito bom! Parabéns pelo artigo, muito interessante =)

[9] Comentário enviado por lucasdona em 17/09/2013 - 15:55h

Zendrael, acho que com o código para compilar, pode tentar compilar utilizando o yocto ou Ltib.
Trabalho um pouco com arm e, já consegui compilar um drive de uma tela de toque para um arm com um kernel especifico, utilizando o código fonte do kernel que incluia o driver da tala tmb (usbtouchscreen.c). Acredito que seja possível também compilar todo o kernel.

[10] Comentário enviado por c4s3 em 25/09/2013 - 12:55h

zendrael, cara muito bom o seu post. vc conheçe outros lugares onde eu possa encontrar mais info de como começar a desenvolver a minha própria distro?

[11] Comentário enviado por marceloiaverafa em 22/11/2013 - 13:36h

quando executei este comando no terminal:

$ g++ -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -fpermissive -m32 -c libc/io.cpp

ele retornou:

libc/io.cpp: Na função ‘void std::escrever(char*, int)’:
libc/io.cpp:10:20: aviso: conversão de ‘int’ para ‘char*’ inválida [-fpermissive]
libc/io.cpp:16:16: aviso: conversão de ‘char*’ para ‘char’ inválida [-fpermissive]

[12] Comentário enviado por heitor_neto em 25/02/2014 - 14:19h

Como faço para criar o meu proprio disco de boot.

[13] Comentário enviado por SirCode em 05/12/2015 - 13:30h

Pode me explicar como funciona esses códigos ?
Essa parte principalmente não entendi nada:
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_AOUT_KLUDGE equ 1<<16
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
Essa tambem:
EXTERN code, bss, end
Essa:
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM

dd multiboot
dd code
dd bss
dd end
dd start
Não entendi a ultima linha do start.asm
E não entendi o link.ld
E como que a variavel mem do io.cpp vai escrever na tela ?

[14] Comentário enviado por SirCode em 05/12/2015 - 13:44h

Pode fazer uma parte de como detectar o keypress ?

[15] Comentário enviado por Uchiha Beyond em 07/07/2016 - 05:02h

Pelo que reparei ele funciona apenas com o modulo para video, como ele funciona sem mudulo para o processador, Memoria RAM e Armazenamento de Memoria?

[16] Comentário enviado por nelsoncole em 15/06/2017 - 18:17h

Bom tutorial !

Ai porquê que ele parou simplesmente no "Hello World"?

[17] Comentário enviado por nelsoncole em 23/06/2017 - 22:15h

Vejo que o artigo foi criado 11/09/2013. Gostaria de poder contribuir com o projecto, adicionando nele os descritores de seguimento e de interrupção, fazer funcionar pelo menos 5 das IRQs e criar um biblioteca mais próxima a Libc.
Infelizmente não estou recebendo atenção do altor inicial.

[18] Comentário enviado por Ashura em 04/07/2017 - 14:09h

Amei ;)
I Love Programming!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts