From 654934e0b5e5ef08e6fd337d5ceb864289796c66 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sun, 27 Oct 2019 13:07:06 +0100 Subject: Improved boot process and color scheme --- src/kernel/boot.asm | 10 ++------ src/kernel/gdt/gdt.c | 4 +++ src/kernel/graphics/vesa.c | 56 ++++++++++++++++++----------------------- src/kernel/graphics/vesa.h | 35 ++++++++++++++++++++++++-- src/kernel/input/ps2/keyboard.c | 1 + src/kernel/interrupts/idt.c | 2 ++ src/kernel/interrupts/irq.c | 2 ++ src/kernel/interrupts/isr.c | 2 ++ src/kernel/io/io.c | 2 ++ src/kernel/kernel.c | 11 +------- src/kernel/paging/paging.c | 1 + src/kernel/system.c | 33 +++++++++++++++++------- src/kernel/system.h | 13 ++++++++++ src/kernel/timer/timer.c | 2 ++ 14 files changed, 114 insertions(+), 60 deletions(-) diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index e3d469c..d533307 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -11,9 +11,9 @@ mboot: ; Multiboot macros MULTIBOOT_PAGE_ALIGN equ 1<<0 MULTIBOOT_MEMORY_INFO equ 1<<1 - MULTIBOOT_VIDEO_MODE equ 1<<2 + MULTIBOOT_AOUT_KLUDGE equ 1<<16 MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 - MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE + MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) EXTERN code, bss, end @@ -29,12 +29,6 @@ mboot: dd end dd start - ; Request linear graphics mode - dd 0 - dd 640 ; width - dd 480 ; height - dd 8 ; bpp - ; Endless loop stublet: extern kernel_main diff --git a/src/kernel/gdt/gdt.c b/src/kernel/gdt/gdt.c index e027fe6..a4d6a57 100644 --- a/src/kernel/gdt/gdt.c +++ b/src/kernel/gdt/gdt.c @@ -1,3 +1,5 @@ +#include + struct gdt_entry { unsigned short limit_low; unsigned short base_low; @@ -48,4 +50,6 @@ void gdt_install() { // Remove old GDT and install the new changes! gdt_flush(); + + vga_log("Installed Global Descriptor Table", 2); } \ No newline at end of file diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index 0f83afe..31ca9d2 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -9,7 +9,6 @@ void switch_to_vga() { serial_write("Force switch to VGA!\n"); - vesa_available = 0; regs16_t regs; regs.ax = 0x0003; paging_disable(); @@ -41,7 +40,6 @@ struct edid_data get_edid() { } void vbe_set_mode(unsigned short mode) { - vesa_available = 0; regs16_t regs; regs.ax = 0x4F02; regs.bx = mode; @@ -50,12 +48,11 @@ void vbe_set_mode(unsigned short mode) { int32(0x10, ®s); paging_enable(); - if (regs.ax != 0x004F) switch_to_vga(); - else vesa_available = 1; + if (regs.ax != 0x004F) + switch_to_vga(); } uint16_t *vbe_get_modes() { - vesa_available = 0; char *info_address = (char *) 0x7E00; strcpy(info_address, "VBE2"); for (int i = 4; i < 512; i++) *(info_address + i) = 0; @@ -100,7 +97,8 @@ struct vbe_mode_info *vbe_get_mode_info(uint16_t mode) { } void set_optimal_resolution() { - uint16_t *video_modes = vbe_get_modes(); // TODO: Fix mode getting and optimal resolution finder + vga_log("Switching to graphics mode", 9); + uint16_t *video_modes = vbe_get_modes(); uint16_t highest = 0; @@ -167,42 +165,32 @@ void set_optimal_resolution() { switch_to_vga(); } - serial_write("Using mode: ("); - serial_write_hex(highest); - serial_write(") "); - serial_write_dec(vbe_width); - serial_write("x"); - serial_write_dec(vbe_height); - serial_write("x"); - serial_write_dec(vbe_bpp << 3); - serial_write("\n"); + vbe_set_mode(highest); - uint32_t fb_size = vbe_width * vbe_height * vbe_bpp; - for (uint32_t z = 0; z < fb_size; z += 4096) - paging_map((uint32_t) fb + z, (uint32_t) fb + z, PT_PRESENT | PT_RW | PT_USED); + vesa_clear(); - vbe_set_mode(highest); - vesa_draw_string("Using mode: "); + info("Successfully switched to video mode!"); + + serial_write("Using mode: "); + serial_write_hex(highest); + log("Using mode: "); vesa_draw_number(vbe_width); vesa_draw_string("x"); vesa_draw_number(vbe_height); vesa_draw_string("x"); vesa_draw_number(vbe_bpp << 3); - vesa_draw_string("\n"); + + uint32_t fb_size = vbe_width * vbe_height * vbe_bpp; + for (uint32_t z = 0; z < fb_size; z += 4096) + paging_map((uint32_t) fb + z, (uint32_t) fb + z, PT_PRESENT | PT_RW | PT_USED); } uint16_t terminal_x = 1; uint16_t terminal_y = 1; -uint32_t terminal_color = 0xFFFFFF; - -void vesa_clear() { - for (int i = 0; i < vbe_width * vbe_height * vbe_bpp; i++) { - fb[i] = 0; - fb[i + 1] = 0; - fb[i + 2] = 0; - } -} +uint32_t text_color = vesa_white; +uint32_t terminal_background = vesa_black; +uint32_t terminal_color = vesa_white; void vesa_set_pixel(uint16_t x, uint16_t y, uint32_t color) { unsigned pos = x * vbe_bpp + y * vbe_pitch; @@ -228,6 +216,10 @@ void vesa_draw_rectangle(int x1, int y1, int x2, int y2, int color) { } } +void vesa_clear() { + vesa_draw_rectangle(0, 0, vbe_width, vbe_height, terminal_background); +} + void vesa_draw_char(char ch) { if (ch >= ' ') { int mask[8] = {1, 2, 4, 8, 16, 32, 64, 128}; @@ -237,6 +229,8 @@ void vesa_draw_char(char ch) { for (int cx = 0; cx < 8; cx++) { if (glyph[cy] & mask[cx]) { vesa_set_pixel(terminal_x + 8 - cx, terminal_y + 16 - cy, terminal_color); + } else { + vesa_set_pixel(terminal_x + 8 - cx, terminal_y + 16 - cy, terminal_background); } } } @@ -254,7 +248,7 @@ void vesa_draw_char(char ch) { } void vesa_keyboard_char(char ch) { - vesa_draw_rectangle(terminal_x, terminal_y, terminal_x + 8, terminal_y + 16, 0x0); + vesa_draw_rectangle(terminal_x, terminal_y, terminal_x + 8, terminal_y + 16, terminal_background); if (ch == 0x08) { if (terminal_x != 0) terminal_x -= 10; diff --git a/src/kernel/graphics/vesa.h b/src/kernel/graphics/vesa.h index daf8701..93150d4 100644 --- a/src/kernel/graphics/vesa.h +++ b/src/kernel/graphics/vesa.h @@ -4,8 +4,6 @@ #include #include -int vesa_available; - struct edid_data { uint8_t padding[8]; uint16_t manufacture_id; @@ -142,6 +140,39 @@ void vesa_draw_string(char *data); */ void vesa_draw_number(int n); +/** + * Sets the color using a rgb number + * @param color The color + */ +void vesa_set_color(uint32_t color); + +/** + * An enum with vesa colors + */ +enum vesa_color { + vesa_black = 0x1d1f24, + vesa_red = 0xE06C75, + vesa_green = 0x98C379, + vesa_yellow = 0xE5C07B, + vesa_blue = 0x61AFEF, + vesa_magenta = 0xC678DD, + vesa_cyan = 0x56B6C2, + vesa_white = 0xABB2BF, + vesa_dark_black = 0x3E4452, + vesa_dark_red = 0xBE5046, + vesa_dark_green = 0x98C379, + vesa_dark_yellow = 0xD19A66, + vesa_dark_blue = 0x61AFEF, + vesa_dark_magenta = 0xC678DD, + vesa_dark_cyan = 0x56B6C2, + vesa_dark_white = 0x5C6370, +}; + +/** + * The default text color + */ +uint32_t text_color; + /** * The current input */ diff --git a/src/kernel/input/ps2/keyboard.c b/src/kernel/input/ps2/keyboard.c index f793852..7d66ed9 100644 --- a/src/kernel/input/ps2/keyboard.c +++ b/src/kernel/input/ps2/keyboard.c @@ -56,4 +56,5 @@ void keyboard_rate() { void keyboard_install() { keyboard_rate(); irq_install_handler(1, keyboard_handler); + vga_log("Installed keyboard handler", 5); } diff --git a/src/kernel/interrupts/idt.c b/src/kernel/interrupts/idt.c index 635743d..26489c4 100644 --- a/src/kernel/interrupts/idt.c +++ b/src/kernel/interrupts/idt.c @@ -1,4 +1,5 @@ #include +#include struct idt_entry { unsigned short base_lo; @@ -41,4 +42,5 @@ void idt_install() { memory_set(&idt, 0, sizeof(struct idt_entry) * 256); idt_load(); + vga_log("Installed Interrupt Descriptor Table", 6); } diff --git a/src/kernel/interrupts/irq.c b/src/kernel/interrupts/irq.c index 39cfb23..979b25c 100644 --- a/src/kernel/interrupts/irq.c +++ b/src/kernel/interrupts/irq.c @@ -1,5 +1,6 @@ #include #include +#include extern void irq0(); @@ -86,6 +87,7 @@ void irq_install() { idt_set_gate(45, (unsigned) irq13, 0x08, 0x8E); idt_set_gate(46, (unsigned) irq14, 0x08, 0x8E); idt_set_gate(47, (unsigned) irq15, 0x08, 0x8E); + vga_log("Installed Interrupt Requests", 8); } // Handle IRQ ISRs diff --git a/src/kernel/interrupts/isr.c b/src/kernel/interrupts/isr.c index 59c6ad7..d03a6de 100644 --- a/src/kernel/interrupts/isr.c +++ b/src/kernel/interrupts/isr.c @@ -106,6 +106,8 @@ void isrs_install() { idt_set_gate(29, (unsigned) isr29, 0x08, 0x8E); idt_set_gate(30, (unsigned) isr30, 0x08, 0x8E); idt_set_gate(31, (unsigned) isr31, 0x08, 0x8E); + + vga_log("Installed Interrupt Service Routines", 7); } // Error exception messages diff --git a/src/kernel/io/io.c b/src/kernel/io/io.c index 5c0eefa..974c391 100644 --- a/src/kernel/io/io.c +++ b/src/kernel/io/io.c @@ -1,6 +1,7 @@ #include #include #include +#include uint8_t receive_b(uint16_t port) { uint8_t value; @@ -41,6 +42,7 @@ void init_serial() { send_b(0x3f8 + 2, 0xC7); send_b(0x3f8 + 4, 0x0B); serial_write("Installed serial connection!\n"); + vga_log("Installed serial connection", 3); } int is_transmit_empty() { diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index b6f0591..172ef55 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -9,12 +9,12 @@ void init() { timer_install(); gdt_install(); + init_serial(); paging_install(); keyboard_install(); idt_install(); isrs_install(); irq_install(); - init_serial(); set_optimal_resolution(); asm volatile ("sti"); } @@ -22,15 +22,6 @@ void init() { void kernel_main(void) { init(); - vesa_draw_string("This is a testing text!"); - - if (vesa_available) { - serial_write("Loaded VESA!\n"); - } else { - serial_write("VESA loading failed!\n"); - switch_to_vga(); - } - // __asm__ ("div %0" :: "r"(0)); // Exception testing x/0 loop: asm volatile ("hlt"); diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c index 3739100..02fc253 100644 --- a/src/kernel/paging/paging.c +++ b/src/kernel/paging/paging.c @@ -24,6 +24,7 @@ void paging_install() { paging_set_used(0, ((uint32_t) end >> 12) + 1); paging_enable(); + vga_log("Installed paging", 4); } int paging_enabled() { diff --git a/src/kernel/system.c b/src/kernel/system.c index 4049e27..c8f89b6 100644 --- a/src/kernel/system.c +++ b/src/kernel/system.c @@ -4,39 +4,54 @@ #include #include #include +#include + +void vga_log(char *msg, int line) { + uint16_t *terminal_buffer = (uint16_t *) 0xB8000; + for (size_t i = 0; i < strlen(msg); i++) + terminal_buffer[line * 80 + i] = (uint16_t) msg[i] | (uint16_t) 0x700; +} void kernel_time() { vesa_draw_string("\n"); vesa_draw_string("["); - vesa_draw_number(get_time()); + vesa_draw_number((int) get_time()); vesa_draw_string("] "); } +void log(char *msg) { + vesa_set_color(vesa_dark_white); + kernel_time(); + vesa_draw_string(msg); + vesa_set_color(text_color); +} + void info(char *msg) { - // terminal_set_color(9); + vesa_set_color(vesa_blue); kernel_time(); - vesa_draw_string("INFO: "); + vesa_draw_string("INFORMATION: "); vesa_draw_string(msg); - vesa_draw_string("\n"); - // terminal_set_color(7); + vesa_set_color(text_color); } void warn(char *msg) { - // terminal_set_color(6); + vesa_set_color(vesa_dark_yellow); kernel_time(); vesa_draw_string("WARNING: "); vesa_draw_string(msg); - vesa_draw_string("\n"); - // terminal_set_color(7); + vesa_set_color(text_color); } void panic(char *msg) { asm volatile ("cli"); - // terminal_set_color(4); + vesa_set_color(vesa_dark_red); kernel_time(); serial_write("PANIC: "); serial_write(msg); serial_write(" - System Halted!\n"); + vesa_draw_string("PANIC: "); + vesa_draw_string(msg); + vesa_draw_string(" - System Halted!\n"); loop: asm volatile ("hlt"); goto loop; diff --git a/src/kernel/system.h b/src/kernel/system.h index 45e88de..e6888fc 100644 --- a/src/kernel/system.h +++ b/src/kernel/system.h @@ -21,11 +21,24 @@ typedef struct __attribute__ ((packed)) { */ extern void int32(unsigned char intnum, regs16_t *regs); +/** + * Log a message before VESA has been initialized + * @param msg The message + * @param line The hardcoded linenumber + */ +void vga_log(char *msg, int line); + /** * Print the current kernel time */ void kernel_time(); +/** + * Display a general log message + * @param msg The message + */ +void log(char *msg); + /** * Display an information message * @param msg The information diff --git a/src/kernel/timer/timer.c b/src/kernel/timer/timer.c index a5dd12e..151790e 100644 --- a/src/kernel/timer/timer.c +++ b/src/kernel/timer/timer.c @@ -1,5 +1,6 @@ #include #include +#include static unsigned int timer_ticks = 0; @@ -33,4 +34,5 @@ unsigned int get_time() { void timer_install() { timer_phase(1000); irq_install_handler(0, timer_handler); + vga_log("Installed timer", 1); } \ No newline at end of file -- cgit v1.2.3