From 61b351b3b3e26eb07055b0c80cd938eaa494c115 Mon Sep 17 00:00:00 2001 From: "L. Bradley LaBoon" Date: Wed, 16 Oct 2013 13:03:05 -0400 Subject: [PATCH] First working version! Basic hello world kernel. --- boot/boot.s | 40 +++++++++++++++++++ kernel/brados.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ linker.ld | 38 ++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 boot/boot.s create mode 100644 kernel/brados.c create mode 100644 linker.ld diff --git a/boot/boot.s b/boot/boot.s new file mode 100644 index 0000000..7900d1f --- /dev/null +++ b/boot/boot.s @@ -0,0 +1,40 @@ +# Declare constants for creating a multiboot header +.set ALIGN, 1<<0 +.set MEMINFO, 1<<1 +.set FLAGS, ALIGN | MEMINFO +.set MAGIC, 0x1BADB002 +.set CHECKSUM, -(MAGIC + FLAGS) + +# Declare multiboot header +.section .multiboot +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM + +# Create a 16 KiB stack +.section .bootstrap_stack +stack_bottom: +.skip 16384 +stack_top: + +# Kernel entry point +.section .text +.global _start +.type _start, @function +_start: + # We are now in kernel mode! + # Setup the stack + movl $stack_top, %esp + + # Call the main kernel function + call brados_main + + # In case the function returns, enter an endless loop + cli + hlt +.Lhang: + jmp .Lhang + +# Set the size of the _start symbol for debugging +.size _start, . - _start diff --git a/kernel/brados.c b/kernel/brados.c new file mode 100644 index 0000000..86626a5 --- /dev/null +++ b/kernel/brados.c @@ -0,0 +1,104 @@ +#include +#include +#include + +// Make sure we are using the right compiler +#if defined(__linux__) +#error "You are using the wrong compiler." +#endif + +// Color constants +enum vgaColor +{ + COLOR_BLACK = 0, + COLOR_BLUE = 1, + COLOR_GREEN = 2, + COLOR_CYAN = 3, + COLOR_RED = 4, + COLOR_MAGENTA = 5, + COLOR_BROWN = 6, + COLOR_LIGHT_GREY = 7, + COLOR_DARK_GREY = 8, + COLOR_LIGHT_BLUE = 9, + COLOR_LIGHT_GREEN = 10, + COLOR_LIGHT_CYAN = 11, + COLOR_LIGHT_RED = 12, + COLOR_LIGHT_MAGENTA = 13, + COLOR_LIGHT_BROWN = 14, + COLOR_WHITE = 15 +}; + +uint8_t makeColor(enum vgaColor fg, enum vgaColor bg) +{ + return fg | bg << 4; +} + +uint16_t makeVGAEntry(char c, uint8_t color) +{ + uint16_t c16 = c; + uint16_t color16 = color; + return c16 | color16 << 8; +} + +size_t strlen(const char *str) +{ + size_t len = 0; + while (str[len] != 0) + len++; + return len; +} + +static const size_t VGA_WIDTH = 80; +static const size_t VGA_HEIGHT = 24; + +size_t terminalRow, terminalCol; +uint8_t terminalColor; +uint16_t *terminalBuf; + +void terminalInit() +{ + terminalRow = terminalCol = 0; + terminalColor = makeColor(COLOR_LIGHT_GREY, COLOR_BLACK); + terminalBuf = (uint16_t *) 0xB8000; + + for (size_t x = 0; x < VGA_WIDTH; x++) { + for (size_t y = 0; y < VGA_HEIGHT; y++) { + const size_t index = y * VGA_WIDTH + x; + terminalBuf[index] = makeVGAEntry(' ', terminalColor); + } + } +} + +void terminalSetColor(uint8_t color) +{ + terminalColor = color; +} + +void terminalPutEntryAt(char c, uint8_t color, size_t x, size_t y) +{ + const size_t index = y * VGA_WIDTH + x; + terminalBuf[index] = makeVGAEntry(c, color); +} + +void terminalPutChar(char c) +{ + terminalPutEntryAt(c, terminalColor, terminalCol, terminalRow); + if (terminalCol++ == VGA_WIDTH) { + terminalCol = 0; + if (terminalRow++ == VGA_HEIGHT) + terminalRow = 0; + } +} + +void terminalWriteString(const char *data) +{ + size_t dataLen = strlen(data); + for (size_t i = 0; i < dataLen; i++) + terminalPutChar(data[i]); +} + +void brados_main() +{ + terminalInit(); + terminalWriteString("Welcome to BRaDOS!\n"); +} diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..2307515 --- /dev/null +++ b/linker.ld @@ -0,0 +1,38 @@ +/* Kernel entry point */ +ENTRY(_start) + +/* Define the locations of the object file sections */ +SECTIONS +{ + /* Sections begin at 1 MiB */ + . = 1M; + + /* The multiboot header needs to come first, followed by program code */ + .text BLOCK(4K) : ALIGN(4K) + { + *(.multiboot) + *(.text) + } + + /* Read-only data */ + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + /* Initialized read-write data */ + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + /* Uninitialized read-write data and stack */ + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + *(.bootstrap_stack) + } + + /* Add other sections here */ +}