From 38181eb728231e674b923effa7682d94640d7a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Sat, 8 Jan 2022 23:09:52 +0100 Subject: [PATCH] Refactoring debug terminal --- src/kernel/Makefile | 2 +- src/kernel/boot/debug.c | 5 +- src/kernel/boot/kmain.c | 14 ++- src/kernel/boot/multiboot_header.S | 1 - src/kernel/drivers/framebuffer.c | 26 +---- .../drivers/{vga2fb.c => terminal/fbterm.c} | 45 +++++++-- src/kernel/drivers/terminal/terminal.c | 71 ++++++++++++++ src/kernel/drivers/terminal/vga.c | 38 ++++++++ src/kernel/drivers/vga.c | 94 ------------------- src/kernel/include/debug.h | 1 + src/kernel/include/framebuffer.h | 7 +- src/kernel/include/multiboot.h | 1 + src/kernel/include/terminal.h | 28 ++++++ src/kernel/include/vga.h | 27 ------ 14 files changed, 198 insertions(+), 162 deletions(-) rename src/kernel/drivers/{vga2fb.c => terminal/fbterm.c} (90%) create mode 100644 src/kernel/drivers/terminal/terminal.c create mode 100644 src/kernel/drivers/terminal/vga.c delete mode 100644 src/kernel/drivers/vga.c create mode 100644 src/kernel/include/terminal.h delete mode 100644 src/kernel/include/vga.h diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 1e6a04e..436ad19 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -4,7 +4,7 @@ endif CC := ${TARGET}-gcc -SRC := $(wildcard **/*.[cS]*) +SRC := $(shell find -type f -name '*.[cS]*') OBJ := $(patsubst %, %.o, $(basename $(basename $(SRC)))) CFLAGS := -Wall -Wextra -pedantic -ffreestanding -mcmodel=large diff --git a/src/kernel/boot/debug.c b/src/kernel/boot/debug.c index 4a74efd..80977c2 100644 --- a/src/kernel/boot/debug.c +++ b/src/kernel/boot/debug.c @@ -1,7 +1,8 @@ #include #include #include -#include +#include +#include void num2str(char *buf, uint64_t num, uint64_t base) { @@ -30,7 +31,7 @@ void num2str(char *buf, uint64_t num, uint64_t base) void debug_putch(char c) { - vga_write(c); + terminal_write(c); } void debug_putsn(char *s, size_t n) diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index 47490b6..594502f 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -10,15 +10,19 @@ struct kernel_boot_data_st kernel_boot_data; void kmain(uint64_t multiboot_magic, void *multiboot_data) { + debug_info("Started kernel\n"); multiboot_init(multiboot_magic, P2V(multiboot_data)); + debug_info("Kernel loaded with command line: \"%s\" by <%s>\n", + kernel_boot_data.commandline, + kernel_boot_data.bootloader); cpu_init(); + debug_info("Set up boot CPU\n"); memory_init(); + debug_info("Set up memory management\n"); - vga_init(); - - debug("Started kernel\n"); - debug_info("Kernel loaded with command line: \"%s\" by <%s>\n", kernel_boot_data.commandline, kernel_boot_data.bootloader); + terminal_init(); + debug_info("Set up debug terminal\n"); debug_info("Boot complete\n"); diff --git a/src/kernel/boot/multiboot_header.S b/src/kernel/boot/multiboot_header.S index db382fe..0f7fca1 100644 --- a/src/kernel/boot/multiboot_header.S +++ b/src/kernel/boot/multiboot_header.S @@ -16,7 +16,6 @@ Multiboot2Header: .long 0 .long 0 .long 0 - .long 0 //; Pad to multiple of 8 bytes .short 0 //; End tag diff --git a/src/kernel/drivers/framebuffer.c b/src/kernel/drivers/framebuffer.c index e07d206..88bfad4 100644 --- a/src/kernel/drivers/framebuffer.c +++ b/src/kernel/drivers/framebuffer.c @@ -2,7 +2,6 @@ #include #include #include -#include gfx_context kernel_fb; gfx_context subcontext; @@ -19,21 +18,9 @@ void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr) *fb = clr; } -static void draw_border(gfx_context *ctx, uint32_t clr) -{ - for(uint64_t x = 0; x < ctx->width; x++) - { - putpixel(ctx, x, 0, clr); - putpixel(ctx, x, ctx->height-1, clr); - } - for(uint64_t y = 0; y < ctx->height; y++) - { - putpixel(ctx, 0, y, clr); - putpixel(ctx, ctx->width-1, y, clr); - } -} -gfx_context *make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height) + +gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height) { gfx_context *out = &subcontext; uint64_t loc = \ @@ -50,7 +37,7 @@ gfx_context *make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t return out; } -gfx_context *framebuffer_init(struct fbinfo *fbinfo) +void framebuffer_init(struct fbinfo *fbinfo) { kernel_fb.width = fbinfo->framebuffer_width; kernel_fb.height = fbinfo->framebuffer_height; @@ -63,11 +50,4 @@ gfx_context *framebuffer_init(struct fbinfo *fbinfo) { vmm_set_page(kernel_P4, (uint64_t)P2V(p), p, PAGE_WRITE | PAGE_PRESENT); } - - draw_border(&kernel_fb, RGB(0, 255, 0)); - gfx_context *sub = make_subcontext(&kernel_fb, 20, 20, 8*VGA_COLS+8, 16*VGA_ROWS+8); - draw_border(sub, RGB(255, 0, 0)); - sub = make_subcontext(&kernel_fb, 24, 24, 8*VGA_COLS, 16*VGA_ROWS); - - return sub; } \ No newline at end of file diff --git a/src/kernel/drivers/vga2fb.c b/src/kernel/drivers/terminal/fbterm.c similarity index 90% rename from src/kernel/drivers/vga2fb.c rename to src/kernel/drivers/terminal/fbterm.c index 8d45a0b..9c0b572 100644 --- a/src/kernel/drivers/vga2fb.c +++ b/src/kernel/drivers/terminal/fbterm.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -102,7 +102,10 @@ char font[95][16] = { {0x00, 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }; -void drawCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, uint32_t clr_bg, char c) +gfx_context *term_fb; +static int setup = 0; + +static void drawCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, uint32_t clr_bg, char c) { char *chr = c ? font[(int)c-0x20]: font[0]; @@ -122,14 +125,42 @@ void drawCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, ui } -void vga2fb(struct vga_cell *buffer, gfx_context *ctx, int rows, int cols) +static void draw_border(gfx_context *ctx, uint32_t clr) { - int i = 0; - for(int row = 0; row < rows; row++) + for(uint64_t x = 0; x < ctx->width; x++) { - for(int col = 0; col < cols; col++) + putpixel(ctx, x, 0, clr); + putpixel(ctx, x, ctx->height-1, clr); + } + for(uint64_t y = 0; y < ctx->height; y++) + { + putpixel(ctx, 0, y, clr); + putpixel(ctx, ctx->width-1, y, clr); + } +} + +void fbterm_init(gfx_context *ctx) +{ + term_fb = framebuffer_make_subcontext(ctx, 20, 20, 8*VGA_COLS+8, 16*VGA_ROWS+8); + draw_border(term_fb, RGB(255, 0, 0)); + term_fb = framebuffer_make_subcontext(ctx, 24, 24, 8*VGA_COLS, 16*VGA_ROWS); + setup = 1; +} + +void fbterm_movecursor(unsigned int cursor) +{ + (void) cursor; +} + +void fbterm_flush(struct vga_cell *buffer) +{ + if(!setup) return; + int i = 0; + for(int row = 0; row < VGA_ROWS; row++) + { + for(int col=0; col < VGA_COLS; col++) { - drawCharacter(ctx, col*8, row*16, 0xFFFFFF, 0, (char)buffer[i++].c); + drawCharacter(term_fb, col*8, row*16, 0xFFFFFF, 0, (char)buffer[i++].c); } } } \ No newline at end of file diff --git a/src/kernel/drivers/terminal/terminal.c b/src/kernel/drivers/terminal/terminal.c new file mode 100644 index 0000000..4b561af --- /dev/null +++ b/src/kernel/drivers/terminal/terminal.c @@ -0,0 +1,71 @@ +#include +#include +#include + +#define FRAMEBUFFER 0x1 +#define EGA_TEXT 0x2 + +#define VGA_ROW(pos) ((pos)/VGA_COLS) +#define VGA_COL(pos) ((pos)%VGA_COLS) +#define VGA_POS(row, col) ((row)*VGA_COLS + (col)) + +static struct vga_cell buffer[VGA_SIZE]; +unsigned int cursor = 0; +uint8_t format = 0x7; + +static int terminal_type; + +void terminal_init(){ + struct fbinfo *fbinfo = kernel_boot_data.fbinfo; + terminal_type = fbinfo->framebuffer_type; + + switch(terminal_type) + { + case FRAMEBUFFER: + framebuffer_init(fbinfo); + fbterm_init(&kernel_fb); + break; + case EGA_TEXT: + vga_init(fbinfo); + break; + } +} + + +static void scroll() +{ + while(cursor >= VGA_SIZE) + { + memmove(buffer, &buffer[VGA_POS(1,0)], VGA_COLS*(VGA_ROWS-1)*sizeof(struct vga_cell)); + memset(&buffer[VGA_POS(VGA_ROWS-1, 0)], 0, VGA_COLS*sizeof(struct vga_cell)); + cursor -= VGA_COLS; + } +} + +void terminal_write(char c) +{ + int doflush = 0; + switch(c) + { + case '\n': + cursor += VGA_COLS - VGA_COL(cursor); + doflush = 1; + break; + default: + buffer[cursor++] = (struct vga_cell){.c = c, .f = format}; + } + scroll(); + switch(terminal_type) + { + case FRAMEBUFFER: + if(doflush) + fbterm_flush(buffer); + fbterm_movecursor(cursor); + break; + case EGA_TEXT: + if(doflush) + vga_flush(buffer); + vga_movecursor(cursor); + break; + } +} \ No newline at end of file diff --git a/src/kernel/drivers/terminal/vga.c b/src/kernel/drivers/terminal/vga.c new file mode 100644 index 0000000..a94e49f --- /dev/null +++ b/src/kernel/drivers/terminal/vga.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include + +#define VGA_ADDRESS_PORT 0x3D4 +#define VGA_DATA_PORT 0x3D5 +#define VGA_REGISTER_CURSOR_POS_LOW 0xF +#define VGA_REGISTER_CURSOR_POS_HIGH 0xE + +static void *vidmem; + +static int setup = 0; + +void vga_init(struct fbinfo *fbinfo) +{ + (void) fbinfo; + vidmem = VGA_MEMORY; + memset(vidmem, 0, VGA_SIZE*sizeof(struct vga_cell)); + setup = 1; +} + +void vga_movecursor(unsigned int cursor) +{ + if(!setup) return; + outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_LOW); + outb(VGA_DATA_PORT, (uint8_t)(cursor & 0xFF)); + outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_HIGH); + outb(VGA_DATA_PORT, (uint8_t)((cursor >> 8) & 0xFF)); +} + +void vga_flush(struct vga_cell *buffer) +{ + if(!setup) return; + memcpy(vidmem, buffer, VGA_SIZE*2); +} diff --git a/src/kernel/drivers/vga.c b/src/kernel/drivers/vga.c deleted file mode 100644 index 002ee8a..0000000 --- a/src/kernel/drivers/vga.c +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - - -#define VGA_ROW(pos) ((pos)/VGA_COLS) -#define VGA_COL(pos) ((pos)%VGA_COLS) -#define VGA_POS(row, col) ((row)*VGA_COLS + (col)) - -#define VGA_ADDRESS_PORT 0x3D4 -#define VGA_DATA_PORT 0x3D5 -#define VGA_REGISTER_CURSOR_POS_LOW 0xF -#define VGA_REGISTER_CURSOR_POS_HIGH 0xE - -void *vidmem; - -struct vga_cell buffer[VGA_SIZE]; - -uint64_t cursor; -uint8_t format; - -static int vga_setup = 0; -static int vga_type; -gfx_context *fb_context; - -void vga_init() -{ - struct fbinfo *fbinfo = kernel_boot_data.fbinfo; - vga_type = fbinfo->framebuffer_type; - switch(vga_type) - { - case 1: - fb_context = framebuffer_init(fbinfo); - break; - case 2: - vidmem = VGA_MEMORY; - memset(vidmem, 0, VGA_SIZE*sizeof(struct vga_cell)); - format = 0x07; - break; - } - - vga_setup = 1; -} - -static void movecursor() -{ - outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_LOW); - outb(VGA_DATA_PORT, (uint8_t)(cursor & 0xFF)); - outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_HIGH); - outb(VGA_DATA_PORT, (uint8_t)((cursor >> 8) & 0xFF)); -} - -static void flush() -{ - if(vga_setup) - memcpy(vidmem, buffer, sizeof(buffer)); -} - -static void scroll() -{ - while(cursor >= VGA_SIZE) - { - memmove(buffer, &buffer[VGA_POS(1,0)], VGA_COLS*(VGA_ROWS-1)*sizeof(struct vga_cell)); - memset(&buffer[VGA_POS(VGA_ROWS-1, 0)], 0, VGA_COLS*sizeof(struct vga_cell)); - cursor -= VGA_COLS; - } -} - -void vga_write(char c) -{ - switch(c) - { - case '\n': - cursor += VGA_COLS - VGA_COL(cursor); - break; - default: - buffer[cursor++] = (struct vga_cell){.c = c, .f = format}; - } - scroll(); - switch(vga_type) - { - case 1: - vga2fb(buffer, fb_context, VGA_ROWS, VGA_COLS); - break; - case 2: - flush(); - movecursor(); - break; - } -} \ No newline at end of file diff --git a/src/kernel/include/debug.h b/src/kernel/include/debug.h index 76b29fb..73c2bf1 100644 --- a/src/kernel/include/debug.h +++ b/src/kernel/include/debug.h @@ -26,6 +26,7 @@ do { \ debug_printf("\n\nKERNEL PANIC!\n%s:%d\n", __FILE__, __LINE__); \ debug_printf(__VA_ARGS__); \ + debug_printf("\n"); \ volatile int _override = 0; \ while(1) { \ asm("panic_breakpoint_" S__LINE__ ":"); \ diff --git a/src/kernel/include/framebuffer.h b/src/kernel/include/framebuffer.h index ba721e2..9e3f424 100644 --- a/src/kernel/include/framebuffer.h +++ b/src/kernel/include/framebuffer.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include typedef struct { uint32_t width; @@ -12,9 +13,11 @@ typedef struct { size_t size; } gfx_context; +extern gfx_context kernel_fb; + #define RGB(r, g, b) (((uint32_t) (r<<16) + (g<<8) + (b))) void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr); -gfx_context *make_subarea(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height); +gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height); -void drawCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, uint32_t clr_bg, char c); \ No newline at end of file +void framebuffer_init(struct fbinfo *fbinfo); \ No newline at end of file diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 44db4ca..9433581 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -13,6 +13,7 @@ #ifndef __ASSEMBLER__ #include +#include struct fbinfo { uint64_t framebuffer_addr; diff --git a/src/kernel/include/terminal.h b/src/kernel/include/terminal.h new file mode 100644 index 0000000..8ec6475 --- /dev/null +++ b/src/kernel/include/terminal.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include + +#define VGA_COLS 80 +#define VGA_ROWS 24 +#define VGA_SIZE (VGA_COLS*VGA_ROWS) +#define VGA_MEMORY P2V(0xB8000) + +struct vga_cell { + uint8_t c; + uint8_t f; +}__attribute__((packed)); + + +// drivers/terminal/terminal.c +void terminal_init(); +void terminal_write(char c); + +// drivers/terminal/vga.c +void vga_init(); +void vga_movecursor(unsigned int cursor); +void vga_flush(struct vga_cell *buffer); + +// drivers/terminal/fbterm.c +void fbterm_init(gfx_context *ctx); +void fbterm_movecursor(unsigned int cursor); +void fbterm_flush(struct vga_cell *buffer); \ No newline at end of file diff --git a/src/kernel/include/vga.h b/src/kernel/include/vga.h deleted file mode 100644 index d0188c7..0000000 --- a/src/kernel/include/vga.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include -#include -#include - -#define VGA_MEMORY P2V(0xB8000) -#define VGA_COLS 80 -#define VGA_ROWS 24 -#define VGA_SIZE (VGA_COLS*VGA_ROWS) - -struct vga_cell{ - uint8_t c; - uint8_t f; -}__attribute__((packed)); - -// drivers/vga.c -extern struct vga_cell buffer[]; - -// drivers/vga.c -void vga_init(); -void vga_write(char c); - -// drivers/framebuffer.c -gfx_context *framebuffer_init(struct fbinfo *fbinfo); - -// drivers/vga2fb.c -void vga2fb(struct vga_cell *buffer, gfx_context *ctx, int rows, int cols); \ No newline at end of file