summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/boot.asm11
-rw-r--r--kernel/main.c95
-rw-r--r--link.ld6
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();
}
diff --git a/link.ld b/link.ld
index 11536c8..6721c00 100644
--- a/link.ld
+++ b/link.ld
@@ -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);
}