diff options
author | Aiden Gall <aiden@aidengall.xyz> | 2024-05-26 22:22:14 +0100 |
---|---|---|
committer | Aiden Gall <aiden@aidengall.xyz> | 2024-05-26 22:22:14 +0100 |
commit | ad8ab9b672d9f040f84b9933878b22fb291e41e7 (patch) | |
tree | 8bc093e045723f8f5c234150a407760189ce8e05 | |
parent | 5ebc67833086eccb3c3b1708745c927d5bcfd811 (diff) |
-rw-r--r-- | boot/boot.asm | 11 | ||||
-rw-r--r-- | kernel/main.c | 95 | ||||
-rw-r--r-- | link.ld | 6 |
3 files changed, 72 insertions, 40 deletions
diff --git a/boot/boot.asm b/boot/boot.asm index eedde07..62f80f8 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -1,5 +1,7 @@ format ELF64 +extrn kmain + PML4_TABLE = 0x1000 E820_MMAP = 0xf000 @@ -9,7 +11,7 @@ include 'bios.inc' include 'page.inc' include 'segdesc.inc' -section '.text.boot' executable +section '.boot' executable writeable org 0x7c00 use16 @@ -104,12 +106,17 @@ longmode: xor ecx, ecx xor edx, edx xor edi, edi + xor esi, esi ; put stack at top of addressable memory mov esp, 0x200000 mov ebp, esp - jmp 0x100000 + ; manually encoded 'jmp rel32', fasm throws an 'invalid use of symbol' + ; error when generating code for a jmp to an external symbol after + ; setting code origin with 'org' directive or a 'virtual at X' block. + db 0xe9 + dd kmain-$-4 align 4 dw 0 diff --git a/kernel/main.c b/kernel/main.c index 0633254..a4a905c 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -14,56 +14,72 @@ struct e820_entry { STATIC_ASSERT(sizeof(struct e820_entry) == 24, e820_entry); -static uint64_t * -memsetu64(uint64_t *const dst, const uint64_t c, const uint64_t n) +struct vga_term { + uint16_t *buf; + uint16_t column; + uint16_t line; +}; + +static void +vga_term_scroll(const struct vga_term *const term) { - for (uint64_t i = 0; i < n; ++i) dst[i] = c; - return dst; + for (int i = 0; i < VGA_HEIGHT-1; ++i) + for (int j = 0; j < VGA_WIDTH; ++j) + term->buf[i*VGA_WIDTH+j] = term->buf[(i+1)*VGA_WIDTH+j]; + for (int i = 0; i < VGA_WIDTH; ++i) + term->buf[(VGA_HEIGHT-1)*VGA_WIDTH+i] = 0x0f20; } -static uint16_t * -print_hex(uint16_t *dst, uint64_t num) +static void +vga_term_newline(struct vga_term *const term) { - dst[0] = 0x0f00 | '0'; - dst[1] = 0x0f00 | 'x'; + if (term->line < VGA_HEIGHT-1) + ++term->line; + else + vga_term_scroll(term); - dst += 2; - - for (int i = 0; i < 16; ++i) { - uint16_t x = (num >> 60); + term->column = 0; - *(dst++) = 0x0f00 | (x < 0xa ? x+'0' : x+'a'-0xa); + return; +} - num <<= 4; +static void +vga_term_putc(struct vga_term *const term, const char c, const uint8_t color) +{ + if (c == '\n') { + vga_term_newline(term); + return; } - return dst; + if (term->column >= VGA_WIDTH) + vga_term_newline(term); + + term->buf[term->line*VGA_WIDTH+(term->column++)] = (color<<8)|(c); } -static uint16_t * -puts(uint16_t *dst, const char *str) +static void +vga_term_puts(struct vga_term *const term, const char *const str, const uint8_t color) { - for (; *str; ++str, ++dst) *dst = 0x0f00|(*str); - return dst; + for (int i = 0; str[i]; ++i) + vga_term_putc(term, str[i], color); } -static uint16_t * -print_e820_table(uint16_t *dst, const struct e820_entry *const entries, const uint16_t count) +static void +vga_term_print_hex(struct vga_term *const term, uint64_t num, const uint8_t color) { - for (uint16_t i = 0; i < count; ++i, dst += VGA_WIDTH) { - uint16_t *cursor; + vga_term_putc(term, '0', color); + vga_term_putc(term, 'x', color); - cursor = print_hex(dst, entries[i].base); + for (int i = 0; i < 16; ++i) { + char c; - *(cursor++) = 0x0f00 | '-'; + c = (num >> 60); + c = (c < 0xa) ? (c + '0') : (c + 'a' - 0xa); - cursor = print_hex(cursor, entries[i].base + entries[i].length - 1); + vga_term_putc(term, c, color); - ++cursor; - cursor = puts(cursor, entries[i].type == 1 ? "available" : "reserved"); + num <<= 4; } - - return dst; } void @@ -71,16 +87,25 @@ kmain(void) { vga_cursor_hide(); - uint16_t *const vga_memory = (uint16_t *)0xb8000; - memsetu64((uint64_t *)vga_memory, 0x0f200f200f200f20, (VGA_WIDTH*VGA_HEIGHT*sizeof(uint16_t))/sizeof(uint64_t)); + struct vga_term term = {(uint16_t *)0xb8000, 0, 0}; + + for (int i = 0; i < VGA_WIDTH*VGA_HEIGHT; ++i) + term.buf[i] = 0x0f20; - puts(vga_memory, "ProvidenceOS v0.1"); - puts(vga_memory+VGA_WIDTH*2, "e820 memory map:"); + vga_term_puts(&term, "ProvidenceOS v0.1\n\ne820 memory map:\n", 0x0f); const uint16_t e820_size = *(uint16_t *)0xf000; const struct e820_entry *const e820_mmap = (struct e820_entry *)0xf008; - print_e820_table(vga_memory+(VGA_WIDTH*3), e820_mmap, e820_size); + for (uint16_t i = 0; i < e820_size; ++i) { + vga_term_print_hex(&term, e820_mmap[i].base, 0x0f); + vga_term_putc(&term, '-', 0x0f); + + vga_term_print_hex(&term, e820_mmap[i].base + e820_mmap[i].length - 1, 0x0f); + vga_term_putc(&term, ' ', 0x0f); + + vga_term_puts(&term, e820_mmap[i].type == 1 ? "available\n" : "reserved\n", 0x0f); + } halt(); } @@ -6,15 +6,15 @@ KERNEL_VMA = 0x100000; SECTIONS { . = 0x7c00; - .text.boot : { - boot/boot.o (.text.boot) + .boot : { + boot/boot.o (.boot) _boot_end = .; } . = KERNEL_VMA; .text : AT(_boot_end) { - *(.text.startup) *(.text) + *(.text.*) *(.rodata*) . = ALIGN(0x1000); } |