commit 7caa808d2a4d0445f97db3fc4e2af1ba8f1cbe9d Author: Mika Westphal Date: Thu Jan 19 19:35:53 2023 +0100 Init diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..89a021a --- /dev/null +++ b/.gdb_history @@ -0,0 +1,27 @@ +remote localhost:1234 +target remote localhost:1234 +kill +target remote localhost:1234 +symbol-file build/kernel +symbol-file build/kernel.elf +d main +disassemble main +list +p VGA +p *(VGA) +b _ZN3VGA20terminal_writestringEPKc +n +line +list +n +list +c +list +b VGA::linebreak +c +c +c +d VGA::linebreak +disassemble VGA::linebreak +list +list VGA::linebreak diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d3bf705 --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +LINKFILE=linker.ld +QEMU=qemu-system-i386 +BUILDPATH=build +SOURCEPATH=src +CC=i686-elf-g++ +CFLAGS=-m32 -c -Wmultichar -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti -Wwrite-strings -fpermissive -g +#OBJ=$(BUILDPATH)/boot.o $(BUILDPATH)/kernel.o $(BUILDPATH)/kernel/vga.o $(BUILDPATH)/kernel/keyboard.o $(BUILDPATH)/kernel/idt.o +OBJ=$(BUILDPATH)/boot.o $(BUILDPATH)/kernel.o $(BUILDPATH)/kernel/vga.o +ASMC=i686-elf-as +LD=ld +LDFLAGS=-m elf_i386 -T $(LINKFILE) -z muldefs -g + +all: $(BUILDPATH)/kernel.elf + $(QEMU) -kernel $(BUILDPATH)/kernel.elf + +debug: $(BUILDPATH)/kernel.elf + $(QEMU) -s -S -kernel $(BUILDPATH)/kernel.elf + +$(BUILDPATH)/boot.o: $(SOURCEPATH)/boot.asm + $(ASMC) $(SOURCEPATH)/boot.asm -o $(BUILDPATH)/boot.o + +$(BUILDPATH)/kernel.o: $(SOURCEPATH)/kernel.* + $(CC) $(CFLAGS) $(SOURCEPATH)/kernel.cpp -o $(BUILDPATH)/kernel.o + +$(BUILDPATH)/kernel/vga.o: $(SOURCEPATH)/kernel/vga.* + $(CC) $(CFLAGS) $(SOURCEPATH)/kernel/vga.cpp -o $(BUILDPATH)/kernel/vga.o + +$(BUILDPATH)/kernel/keyboard.o: $(SOURCEPATH)/kernel/keyboard.* $(BUILDPATH)/boot.o + $(CC) $(CFLAGS) $(SOURCEPATH)/kernel/keyboard.cpp -o $(BUILDPATH)/kernel/keyboard.o + +$(BUILDPATH)/kernel/idt.o: $(SOURCEPATH)/kernel/idt.* $(BUILDPATH)/boot.o + $(CC) $(CFLAGS) $(SOURCEPATH)/kernel/idt.cpp -o $(BUILDPATH)/kernel/idt.o + +$(BUILDPATH)/kernel.elf: $(OBJ) + $(LD) $(LDFLAGS) -o $(BUILDPATH)/kernel.elf $(OBJ) + +clean: + rm $(OBJ) diff --git a/build/boot.o b/build/boot.o new file mode 100644 index 0000000..3fd271c Binary files /dev/null and b/build/boot.o differ diff --git a/build/kernel.elf b/build/kernel.elf new file mode 100755 index 0000000..dc420cd Binary files /dev/null and b/build/kernel.elf differ diff --git a/build/kernel.o b/build/kernel.o new file mode 100644 index 0000000..008c1c6 Binary files /dev/null and b/build/kernel.o differ diff --git a/build/kernel/vga.o b/build/kernel/vga.o new file mode 100644 index 0000000..35f3947 Binary files /dev/null and b/build/kernel/vga.o differ diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..53f4129 --- /dev/null +++ b/linker.ld @@ -0,0 +1,26 @@ +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) + } +} diff --git a/src/boot.asm b/src/boot.asm new file mode 100644 index 0000000..90916ed --- /dev/null +++ b/src/boot.asm @@ -0,0 +1,28 @@ +.set ALIGN, 1<<0 +.set MEMINFO, 1<<1 +.set FLAGS, ALIGN | MEMINFO +.set MAGIC, 0x1BADB002 +.set CHECKSUM, -(MAGIC + FLAGS) + +.section .multiboot +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM + +.section .bss +.align 16 +stack_bottom: +.skip 16384 +stack_top: + +.section .text +.global _start +.type _start, @function +_start: + mov $stack_top, %esp + call kernel_main + cli +1: hlt + jmp 1b +.size _start, . - _start diff --git a/src/kernel.cpp b/src/kernel.cpp new file mode 100644 index 0000000..a6a7bb7 --- /dev/null +++ b/src/kernel.cpp @@ -0,0 +1,13 @@ +#include "kernel/vga.h" + +void main() { + VGA vga = VGA(); + vga.terminal_init(); + vga.terminal_writestring("Hello from kernel main\nTest\n"); + for(int i = 0; i < 80; i++) + vga.terminal_writestring("YEET\n"); +} + +extern "C" void kernel_main(void) { + main(); +} diff --git a/src/kernel/vga.cpp b/src/kernel/vga.cpp new file mode 100644 index 0000000..06a478a --- /dev/null +++ b/src/kernel/vga.cpp @@ -0,0 +1,73 @@ +#include "vga.h" + +inline uint8_t VGA::vga_entry_color(enum vga_color fg, enum vga_color bg) { + return fg | bg << 4; +} + +inline uint16_t VGA::vga_entry(unsigned char uc, uint8_t color) { + return (uint16_t) uc | (uint16_t) color << 8; +} + +size_t VGA::strlen(const char* str) { + size_t len = 0; + while (str[len]) + len++; + return len; +} + +void VGA::linebreak() { + if(terminal_row == VGA_HEIGHT) { + for(size_t row = 1; row < VGA_HEIGHT; row++) { + terminal_buffer[row - 1] = terminal_buffer[row]; + } + }else { + terminal_row++; + } + + terminal_column = 0; +} + +void VGA::terminal_setcolor(uint8_t color) { + terminal_color = color; +} + +void VGA::terminal_putentryat(char c, uint8_t color, size_t x, size_t y) { + const size_t index = y * VGA_WIDTH + x; + terminal_buffer[index] = vga_entry(c, color); +} + +void VGA::terminal_putchar(char c) { + terminal_putentryat(c, terminal_color, terminal_column, terminal_row); + if(++terminal_column == VGA_WIDTH) { + terminal_column = 0; + if(++terminal_row == VGA_HEIGHT) + terminal_row = 0; + } +} + +void VGA::terminal_write(const char* data, size_t size) { + for(size_t i = 0; i < size; i++) { + if(data[i] == '\n') { + linebreak(); + continue; + } + terminal_putchar(data[i]); + } +} + +void VGA::terminal_writestring(const char* data) { + terminal_write(data, strlen(data)); +} + +void VGA::terminal_init(void) { + terminal_row = 0; + terminal_column = 0; + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); + terminal_buffer = (uint16_t*) 0xB8000; + for (size_t y = 0; y < VGA_HEIGHT; y++) { + for(size_t x = 0; x < VGA_WIDTH; x++) { + const size_t index = y * VGA_WIDTH + x; + terminal_buffer[index] = vga_entry(' ', terminal_color); + } + } +} diff --git a/src/kernel/vga.h b/src/kernel/vga.h new file mode 100644 index 0000000..8727863 --- /dev/null +++ b/src/kernel/vga.h @@ -0,0 +1,46 @@ +#include +#include +#include + +class VGA { +protected: + static const size_t VGA_WIDTH = 80; + static const size_t VGA_HEIGHT = 80; + + size_t terminal_row; + size_t terminal_column; + uint8_t terminal_color; + uint16_t* terminal_buffer; + + void terminal_putentryat(char c, uint8_t color, size_t x, size_t y); + void terminal_putchar(char c); + void linebreak(); + +public: + enum vga_color { + VGA_COLOR_BLACK = 0, + VGA_COLOR_BLUE = 1, + VGA_COLOR_GREEN = 2, + VGA_COLOR_CYAN = 3, + VGA_COLOR_RED = 4, + VGA_COLOR_MAGENTA = 5, + VGA_COLOR_BROWN = 6, + VGA_COLOR_LIGHT_GREY = 7, + VGA_COLOR_DARK_GREY = 8, + VGA_COLOR_LIGHT_BLUE = 9, + VGA_COLOR_LIGHT_GREEN = 10, + VGA_COLOR_LIGHT_CYAN = 11, + VGA_COLOR_LIGHT_RED = 12, + VGA_COLOR_LIGHT_MAGENTA = 13, + VGA_COLOR_LIGHT_BROWN = 14, + VGA_COLOR_WHITE = 15, + }; + + static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg); + static inline uint16_t vga_entry(unsigned char uc, uint8_t color); + size_t strlen(const char* str); + void terminal_setcolor(uint8_t color); + void terminal_write(const char* data, size_t size); + void terminal_writestring(const char* data); + void terminal_init(void); +};