From fb981bf9942d52f6db1b6852123a452261e20a94 Mon Sep 17 00:00:00 2001 From: Quinten Kock Date: Fri, 4 Dec 2020 21:05:20 +0100 Subject: [PATCH] improve HAL --- kernel/src/arch/i386/info.c | 1 + kernel/src/arch/{i386 => x86}/ops.c | 2 - kernel/src/arch/x86/panic.c | 9 ++ kernel/src/arch/x86/stivale2-parse.c | 153 +++++++++++++-------------- kernel/src/arch/x86/stivale2-parse.h | 1 + kernel/src/arch/x86/vga.c | 12 ++- kernel/src/arch/x86/vga.h | 1 + kernel/src/arch/x86_64/info.c | 1 + kernel/src/arch/x86_64/ops.c | 6 -- kernel/src/hal/info.c | 39 +++++++ kernel/src/hal/info.h | 37 +++++++ kernel/src/hal/ops.h | 3 +- kernel/src/main.c | 11 +- 13 files changed, 187 insertions(+), 89 deletions(-) create mode 100644 kernel/src/arch/i386/info.c rename kernel/src/arch/{i386 => x86}/ops.c (75%) create mode 100644 kernel/src/arch/x86/panic.c create mode 100644 kernel/src/arch/x86_64/info.c delete mode 100644 kernel/src/arch/x86_64/ops.c create mode 100644 kernel/src/hal/info.c create mode 100644 kernel/src/hal/info.h diff --git a/kernel/src/arch/i386/info.c b/kernel/src/arch/i386/info.c new file mode 100644 index 0000000..19ab434 --- /dev/null +++ b/kernel/src/arch/i386/info.c @@ -0,0 +1 @@ +const char *arch = "i386"; diff --git a/kernel/src/arch/i386/ops.c b/kernel/src/arch/x86/ops.c similarity index 75% rename from kernel/src/arch/i386/ops.c rename to kernel/src/arch/x86/ops.c index 6239677..55f785d 100644 --- a/kernel/src/arch/i386/ops.c +++ b/kernel/src/arch/x86/ops.c @@ -2,5 +2,3 @@ void halt_catch_fire() { asm volatile ("cli"); while(1) asm volatile ("hlt"); } - -const char *arch = "i386"; diff --git a/kernel/src/arch/x86/panic.c b/kernel/src/arch/x86/panic.c new file mode 100644 index 0000000..7ecd232 --- /dev/null +++ b/kernel/src/arch/x86/panic.c @@ -0,0 +1,9 @@ +#include "vga.h" +#include + +void panic(const char *message, const char *filename, int line) { + vga_clear(VGA_BLUE); + printf("KernOS kernel panic:\n%s\n", message); + printf("at %s:%d", filename, line); + halt_catch_fire(); +} \ No newline at end of file diff --git a/kernel/src/arch/x86/stivale2-parse.c b/kernel/src/arch/x86/stivale2-parse.c index 613a6b2..daeed79 100644 --- a/kernel/src/arch/x86/stivale2-parse.c +++ b/kernel/src/arch/x86/stivale2-parse.c @@ -1,9 +1,11 @@ #include #include +#include + #include -void parse_stivale2(struct stivale2_struct *info) { +void print_stivale2(struct stivale2_struct *info) { struct stivale2_tag *tag = (struct stivale2_tag*)(info->tags); while(tag != 0) { switch(tag->identifier) { @@ -76,81 +78,78 @@ void parse_stivale2(struct stivale2_struct *info) { tag = (struct stivale2_tag *)tag->next; } } +void parse_stivale2(struct stivale2_struct *info) { + boot_info.boot_protocol = "stivale2"; + boot_info.bootloader_name = info->bootloader_brand; + boot_info.bootloader_ver = info->bootloader_version; -// void parse_stivale2(struct stivale2_struct *info) { -// struct stivale2_tag *tag = (struct stivale2_tag*)(info->tags); -// while(tag != 0) { -// switch(tag->identifier) { -// case STIVALE2_STRUCT_TAG_CMDLINE_ID: { -// struct stivale2_struct_tag_cmdline *cmd = (struct stivale2_struct_tag_cmdline*)tag; -// printf("cmdline: %s\n", (const char*)cmd->cmdline); -// break; -// } -// case STIVALE2_STRUCT_TAG_MEMMAP_ID: { -// struct stivale2_struct_tag_memmap *m = (struct stivale2_struct_tag_memmap *)tag; -// printf("Memmap (%d entries):\n", m->entries); -// for (size_t i = 0; i < m->entries; i++) { -// struct stivale2_mmap_entry me = m->memmap[i]; -// printf("\t[%x+%x] %x\n", me.base, me.length, me.type); -// } -// break; -// } -// case STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID: { -// struct stivale2_struct_tag_framebuffer *f = (struct stivale2_struct_tag_framebuffer *)tag; -// printf("Framebuffer tag: %dx%d at %x\n", f->framebuffer_width, f->framebuffer_height, f->framebuffer_addr); -// printf("\tPitch: %d\n", f->framebuffer_pitch); -// printf("\tBPP: %d\n", f->framebuffer_bpp); -// printf("\tMemory model: %d\n", f->memory_model); -// printf("\tRed mask size: %d\n", f->red_mask_size); -// printf("\tRed mask size: %d\n", f->red_mask_shift); -// printf("\tGreen mask size: %d\n", f->green_mask_size); -// printf("\tGreen mask size: %d\n", f->green_mask_shift); -// printf("\tBlue mask size: %d\n", f->blue_mask_size); -// printf("\tBlue mask size: %d\n", f->blue_mask_shift); -// break; -// } -// case STIVALE2_STRUCT_TAG_MODULES_ID: { -// struct stivale2_struct_tag_modules *m = (struct stivale2_struct_tag_modules *)tag; -// printf("Modules tag (count: %d):", m->module_count); -// for (size_t i = 0; i < m->module_count; i++) { -// struct stivale2_module me = m->modules[i]; -// printf("\t[%x+%x] %s", me.begin, me.end, me.string); -// } -// break; -// } -// case STIVALE2_STRUCT_TAG_RSDP_ID: { -// struct stivale2_struct_tag_rsdp *r = (struct stivale2_struct_tag_rsdp *)tag; -// puts("RSDP tag:"); -// printf("\tRSDP: %x\n", r->rsdp); -// break; -// } -// case STIVALE2_STRUCT_TAG_EPOCH_ID: { -// struct stivale2_struct_tag_epoch *e = (struct stivale2_struct_tag_epoch *)tag; -// printf("Epoch: %x", e->epoch); -// break; -// } -// case STIVALE2_STRUCT_TAG_FIRMWARE_ID: { -// struct stivale2_struct_tag_firmware *f = (struct stivale2_struct_tag_firmware *)tag; -// printf("Firmware flags: %x\n", f->flags); -// break; -// } -// case STIVALE2_STRUCT_TAG_SMP_ID: { -// struct stivale2_struct_tag_smp *s = (struct stivale2_struct_tag_smp *)tag; -// printf("SMP tag (cores: %d, bootstrap: %d, flags: %x)\n", s->cpu_count, s->bsp_lapic_id, s->flags); -// for (size_t i = 0; i < s->cpu_count; i++) { -// struct stivale2_smp_info *in = &s->smp_info[i]; -// printf("\tProcessor ID: %d\n", in->processor_id); -// printf("\tLAPIC ID: %d\n", in->lapic_id); -// printf("\tTarget Stack: %x\n", in->target_stack); -// printf("\tGOTO Address: %x\n", in->goto_address); -// printf("\tExtra Argument: %x\n", in->extra_argument); -// } -// break; -// } -// default: -// printf("ERR: Unidentifier tag %x\n", tag->identifier); -// } + printf("Unrecogized tags: "); + struct stivale2_tag *tag = (struct stivale2_tag*)(info->tags); + while(tag != 0) { + switch(tag->identifier) { + case STIVALE2_STRUCT_TAG_CMDLINE_ID: { + struct stivale2_struct_tag_cmdline *cmd = (struct stivale2_struct_tag_cmdline*)tag; + set_cmdline((const char*)cmd->cmdline); + break; + } + case STIVALE2_STRUCT_TAG_MEMMAP_ID: { + struct stivale2_struct_tag_memmap *m = (struct stivale2_struct_tag_memmap *)tag; + for (size_t i = 0; i < m->entries; i++) { + struct stivale2_mmap_entry me = m->memmap[i]; + if(me.type == STIVALE2_MMAP_USABLE) { + set_memregion(me.base, me.length); + } + } + break; + } + case STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID: { + struct stivale2_struct_tag_framebuffer *f = (struct stivale2_struct_tag_framebuffer *)tag; + printf("FRAMEBUFFER (%dx%d at %x)\n", f->framebuffer_width, f->framebuffer_height, f->framebuffer_addr); + printf("\tPitch: %d\n", f->framebuffer_pitch); + printf("\tBPP: %d\n", f->framebuffer_bpp); + printf("\tMemory model: %d\n", f->memory_model); + printf("\tRed mask size: %d\n", f->red_mask_size); + printf("\tRed mask size: %d\n", f->red_mask_shift); + printf("\tGreen mask size: %d\n", f->green_mask_size); + printf("\tGreen mask size: %d\n", f->green_mask_shift); + printf("\tBlue mask size: %d\n", f->blue_mask_size); + printf("\tBlue mask size: %d\n", f->blue_mask_shift); + break; + } + case STIVALE2_STRUCT_TAG_MODULES_ID: { + struct stivale2_struct_tag_modules *m = (struct stivale2_struct_tag_modules *)tag; + printf("MODULES (%d) ", m->module_count); + for (size_t i = 0; i < m->module_count; i++) { + struct stivale2_module *me = &m->modules[i]; + printf("\t[%x+%x] %s\n", me->begin, me->end, me->string); + } + break; + } + case STIVALE2_STRUCT_TAG_RSDP_ID: { + struct stivale2_struct_tag_rsdp *r = (struct stivale2_struct_tag_rsdp *)tag; + printf("RSDP (%x) ", r->rsdp); + break; + } + case STIVALE2_STRUCT_TAG_EPOCH_ID: { + struct stivale2_struct_tag_epoch *e = (struct stivale2_struct_tag_epoch *)tag; + set_time(e->epoch); + break; + } + case STIVALE2_STRUCT_TAG_FIRMWARE_ID: { + struct stivale2_struct_tag_firmware *f = (struct stivale2_struct_tag_firmware *)tag; + printf("FW (%x) ", f->flags); + break; + } + case STIVALE2_STRUCT_TAG_SMP_ID: { + struct stivale2_struct_tag_smp *s = (struct stivale2_struct_tag_smp *)tag; + printf("SMP (%d) ", s->cpu_count); + break; + } + default: + printf("???"); + } -// tag = (struct stivale2_tag *)tag->next; -// } -// } + tag = (struct stivale2_tag *)tag->next; + } + putchar('\n'); +} diff --git a/kernel/src/arch/x86/stivale2-parse.h b/kernel/src/arch/x86/stivale2-parse.h index 4b6759d..9338fc4 100644 --- a/kernel/src/arch/x86/stivale2-parse.h +++ b/kernel/src/arch/x86/stivale2-parse.h @@ -1 +1,2 @@ +void print_stivale2(struct stivale2_struct *info); void parse_stivale2(struct stivale2_struct *info); diff --git a/kernel/src/arch/x86/vga.c b/kernel/src/arch/x86/vga.c index 8a7f0f7..128d6ef 100644 --- a/kernel/src/arch/x86/vga.c +++ b/kernel/src/arch/x86/vga.c @@ -11,6 +11,7 @@ static const size_t VGA_HEIGHT = 25; static volatile size_t terminal_row; static volatile size_t terminal_column; static volatile uint8_t current_color = VGA_WHITE; +static volatile uint8_t bg_color = VGA_BLACK; static uint16_t *terminal_buffer = (uint16_t*)0xb8000; void putchar(char c) { @@ -27,7 +28,7 @@ void vga_putc(char c) { return; } if(c != '\n' && c != '\t') - terminal_buffer[index] = (uint16_t)c | (uint16_t)(current_color) << 8; + terminal_buffer[index] = (uint16_t)c | (uint16_t)(current_color) << 8 | (uint16_t)(bg_color) << 12; if (c == '\n' || ++terminal_column == VGA_WIDTH) { terminal_column = 0; @@ -49,3 +50,12 @@ void vga_write_elsewhere(const char *c, size_t y, size_t x) { terminal_row=old_row; terminal_column=old_column; } + +void vga_clear(uint8_t color) { + bg_color = color; + for(size_t i = 0; i < VGA_WIDTH*VGA_HEIGHT; i++) { + terminal_buffer[i] = (uint16_t)(current_color) << 8 | (uint16_t)(bg_color) << 12; + } + terminal_row = 0; + terminal_column = 0; +} \ No newline at end of file diff --git a/kernel/src/arch/x86/vga.h b/kernel/src/arch/x86/vga.h index 175a1c0..b241951 100644 --- a/kernel/src/arch/x86/vga.h +++ b/kernel/src/arch/x86/vga.h @@ -22,3 +22,4 @@ void vga_putc(char c); void vga_puts(const char *c); void vga_setcolor(uint8_t color); void vga_write_elsewhere(const char *c, size_t y, size_t x); +void vga_clear(uint8_t color); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/info.c b/kernel/src/arch/x86_64/info.c new file mode 100644 index 0000000..7c64153 --- /dev/null +++ b/kernel/src/arch/x86_64/info.c @@ -0,0 +1 @@ +const char *arch = "x86_64"; diff --git a/kernel/src/arch/x86_64/ops.c b/kernel/src/arch/x86_64/ops.c deleted file mode 100644 index d087e50..0000000 --- a/kernel/src/arch/x86_64/ops.c +++ /dev/null @@ -1,6 +0,0 @@ -void halt_catch_fire() { - asm volatile ("cli"); - while(1) asm volatile ("hlt"); -} - -const char *arch = "x86_64"; diff --git a/kernel/src/hal/info.c b/kernel/src/hal/info.c new file mode 100644 index 0000000..c29c5d4 --- /dev/null +++ b/kernel/src/hal/info.c @@ -0,0 +1,39 @@ +#include "info.h" + +struct kornos_boot_info boot_info = { + .cmdline = "", + .usable = {0,0}, + .epoch = 0, + .boot_protocol = "", + .bootloader_name = "", + .bootloader_ver = "", +}; + +bool validate_boot_info() { + return boot_info.cmdline && + boot_info.usable.len > 0 && + boot_info.boot_protocol && + boot_info.bootloader_name && + boot_info.bootloader_ver; +} + +void set_time(uint64_t t) { + boot_info.epoch = t; +} + +void set_cmdline(const char *cmd) { + boot_info.cmdline = cmd; +} + +void set_boot_info(const char *protocol, const char *name, const char *version) { + boot_info.boot_protocol = protocol; + boot_info.bootloader_name = name; + boot_info.bootloader_ver = version; +} + +void set_memregion(size_t start, size_t len) { + if(len > boot_info.usable.len) { + boot_info.usable.start = start; + boot_info.usable.len = len; + } +} diff --git a/kernel/src/hal/info.h b/kernel/src/hal/info.h new file mode 100644 index 0000000..0eb4ade --- /dev/null +++ b/kernel/src/hal/info.h @@ -0,0 +1,37 @@ +#include +#include +#include + +extern const char *arch; + +struct kornos_memmap_entry { + size_t start; + size_t len; +}; + +#define KORNOS_FRAMEBUF_TEXT 1 +#define KORNOS_FRAMEBUF_RGB 2 +struct kornos_framebuf_info { + uint8_t type; + size_t addr; + size_t width; + size_t height; +}; + +struct kornos_boot_info { + const char *cmdline; + struct kornos_memmap_entry usable; + struct kornos_framebuf_info framebuf; + uint64_t epoch; + const char *boot_protocol; + const char *bootloader_name; + const char *bootloader_ver; +}; + +extern struct kornos_boot_info boot_info; + +bool validate_boot_info(); +void set_time(uint64_t); +void set_cmdline(const char *); +void set_boot_info(const char*, const char*, const char*); +void set_memregion(size_t start, size_t len); diff --git a/kernel/src/hal/ops.h b/kernel/src/hal/ops.h index f6294a9..72e0afa 100644 --- a/kernel/src/hal/ops.h +++ b/kernel/src/hal/ops.h @@ -1,3 +1,4 @@ void halt_catch_fire(); -extern const char *arch; +#define PANIC(m) panic(m, __FILE__, __LINE__) +void panic(const char *message, const char *filename, int line); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index a8b02bb..d2d1a5e 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,10 +1,17 @@ #include "arch/x86/vga.h" #include "hal/ops.h" +#include "hal/info.h" #include "print/print.h" -void kmain(int argc, char **argv) { +void kmain() { + if(!validate_boot_info()) { + PANIC("Error: boot_info not entered!"); + } printf("Kernel initialized! Platform: %s\n", arch); - printf("Bootloader type: %s (%s %s)\n", argv[0], argv[1], argv[2]); + printf("Bootloader type: %s (%s %s)\n", boot_info.boot_protocol, boot_info.bootloader_name, boot_info.bootloader_ver); + printf("System time: %d\n", boot_info.epoch); + printf("Usable memory: %h (at %x)\n", boot_info.usable.len, boot_info.usable.start); + printf("Cmdline: %s", boot_info.cmdline); vga_setcolor(VGA_DARK_GRAY); vga_write_elsewhere("(c) Quinten Kock 2020 (MIT License)", 24, 0);