Pular para o conteúdo

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.
Gabriel Marinho gabrielbiga
Hits: 61.970 Categoria: C/C++ Subcategoria: Miscelânea
  • Indicar
  • Impressora
  • Denunciar
O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Parte 3: 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
O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.


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.

O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.
   1. Introdução / Preparação
   2. Estrutura de arquivos
   3. Compilação e linkagem

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

Tocando arquivos MP3 no SuSE Linux

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

Como aprender a programar e produzir aplicativos usando Euphoria

Tutorial OpenGL

Utilizando a biblioteca NCURSES - Parte II

Apreendendo a utilizar o GNU Debugger (parte 2)

#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

Entre na sua conta para comentar.