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: 60.317 ]

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

Detectando assalto na multidão com visão computacional

Gerencie suas contas financeiras pessoais com Terminal Finances

Reprodução de arquivos WAV com SDL_mixer e linguagem C

Utilizando a biblioteca NCURSES - Parte III

Aleatoriedade em 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