> For the complete documentation index, see [llms.txt](https://stacked-rwx.gitbook.io/public/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stacked-rwx.gitbook.io/public/programming/kernel-em-c++.md).

# Kernel em C++

<figure><img src="/files/eW03H5dJ44PBQDiKj3Tv" alt=""><figcaption></figcaption></figure>

Utilizei as boas práticas de programação C++ neste projeto e mostrei que não é difícil aprender esta linguagem atraente.

Confira abaixo todo o código do meu kernel:

## boot.s

```nasm
.set MAGIC, 0x1BADB002

.set FLAGS, 0

.set CHECKSUM, -(MAGIC + FLAGS)

.section .multiboot

#define type to long for each data defined as above
.long MAGIC
.long FLAGS
.long CHECKSUM

stackBottom:
.skip 1024

#set the stack top which grows from higher to lower
stackTop:
.section .text
.global _start
.type _start, @function

_start:
	mov $stackTop, %esp
	call kernel_entry

	cli

hltLoop:
	hlt
	jmp hltLoop

.size _start, . - _start
```

## kernel.cpp

```cpp

#include "kernel.hpp"
#include <vector>

uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color) {
	uint16 ax { 0 };

	ax = back_color << 4;
	ax |= fore_color;
	ax = (ax << 8) | ch;

	return ax;
}

void clear_vga_buffer(uint16 **buffer, uint8 fore_color, uint8 back_color) {
	uint32 i;
	for(i = 0; i < BUFSIZE; i++) {
		(*buffer)[i] = vga_entry(__NULL, fore_color, back_color);
	}
}

// initialize vga buffer
void init_vga(uint8 fore_color, uint8 back_color) {
	vga_buffer = (uint16*)VGA_ADDRESS;
	clear_vga_buffer(&vga_buffer, fore_color, back_color);
}

void kernel_entry() {
	init_vga(WHITE, BLACK);

	 std::vector<char> message = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'};
	 const int message_length = message.size();

	 for (int i = 0; i < message_length; i++) {
  	 vga_buffer[i] = vga_entry(message[i], WHITE, BLACK);
	}
}

```

## kernel.hpp

```cpp
#ifndef KERNEL_H
#define KERNEL_H

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;

constexpr int VGA_ADDRESS = 0xB8000;
constexpr int BUFSIZE = 2200;

uint16* vga_buffer;

constexpr int __NULL = 0;

enum vga_color {
	BLACK,
	BLUE,
	GREEN,
	CYAN,
	RED,
	MAGENTA,
	BROWN,
	GREY,
	DARK_GREY,
	BRIGHT_BLUE,
	BRIGHT_GREEN,
	BRIGHT_CYAN,
	BRIGHT_RED,
	BRIGHT_MAGENTA,
	YELLOW,
	WHITE,
};

#endif
```

## linker.ld

```linker-script
ENTRY (_start)

SECTIONS {
	. = 1M;
	.text BLOCK(4K) : ALIGN(4K)
	{
		*(.multiboot)
		*(.text)
	}

	.rodata BLOCK(4K) : ALIGN(4K)
	{
		*(.rodata)
	}

	.data BLOCK(4K) : ALIGN(4K)
	{
		*(.data)
	}

	.bss BLOCK(4K) : ALIGN(4K)
	{
		*(COMMON)
		*(.bss)
	}
}
```

## grub.cfg

```json
menuentry "SimpleKernel" {
	multiboot /boot/SimpleKernel.bin
}
```

## build.sh

```bash
as --32 boot.S -o boot.o

g++ -c -fno-stack-protector -m32 kernel.cpp -o kernel.o -std=c++11 -ffreestanding -O2 -Wall -Wextra

ld -m -z noexecstack elf_i386 -T linker.ld kernel.o boot.o -o SimpleKernel.bin -nostdlib

grub-file --is-x86-multiboot SimpleKernel.bin

mkdir -p isodir/boot/grub
cp SimpleKernel.bin isodir/boot/grub/SimpleKernel.bin
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o SimpleKernel.iso isodir
```

Esse projeto foi criado em 2022...
