Refactoring debug terminal

This commit is contained in:
Thomas Lovén 2022-01-08 23:09:52 +01:00
parent a09c160bcb
commit 38181eb728
14 changed files with 198 additions and 162 deletions

View File

@ -4,7 +4,7 @@ endif
CC := ${TARGET}-gcc CC := ${TARGET}-gcc
SRC := $(wildcard **/*.[cS]*) SRC := $(shell find -type f -name '*.[cS]*')
OBJ := $(patsubst %, %.o, $(basename $(basename $(SRC)))) OBJ := $(patsubst %, %.o, $(basename $(basename $(SRC))))
CFLAGS := -Wall -Wextra -pedantic -ffreestanding -mcmodel=large CFLAGS := -Wall -Wextra -pedantic -ffreestanding -mcmodel=large

View File

@ -1,7 +1,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <vga.h> #include <memory.h>
#include <terminal.h>
void num2str(char *buf, uint64_t num, uint64_t base) 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) void debug_putch(char c)
{ {
vga_write(c); terminal_write(c);
} }
void debug_putsn(char *s, size_t n) void debug_putsn(char *s, size_t n)

View File

@ -1,7 +1,7 @@
#include <stdint.h> #include <stdint.h>
#include <cpu.h> #include <cpu.h>
#include <memory.h> #include <memory.h>
#include <vga.h> #include <terminal.h>
#include <debug.h> #include <debug.h>
#include <multiboot.h> #include <multiboot.h>
#include <interrupts.h> #include <interrupts.h>
@ -10,15 +10,19 @@ struct kernel_boot_data_st kernel_boot_data;
void kmain(uint64_t multiboot_magic, void *multiboot_data) void kmain(uint64_t multiboot_magic, void *multiboot_data)
{ {
debug_info("Started kernel\n");
multiboot_init(multiboot_magic, P2V(multiboot_data)); 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(); cpu_init();
debug_info("Set up boot CPU\n");
memory_init(); memory_init();
debug_info("Set up memory management\n");
vga_init(); terminal_init();
debug_info("Set up debug terminal\n");
debug("Started kernel\n");
debug_info("Kernel loaded with command line: \"%s\" by <%s>\n", kernel_boot_data.commandline, kernel_boot_data.bootloader);
debug_info("Boot complete\n"); debug_info("Boot complete\n");

View File

@ -16,7 +16,6 @@ Multiboot2Header:
.long 0 .long 0
.long 0 .long 0
.long 0 .long 0
.long 0 //; Pad to multiple of 8 bytes .long 0 //; Pad to multiple of 8 bytes
.short 0 //; End tag .short 0 //; End tag

View File

@ -2,7 +2,6 @@
#include <memory.h> #include <memory.h>
#include <multiboot.h> #include <multiboot.h>
#include <framebuffer.h> #include <framebuffer.h>
#include <vga.h>
gfx_context kernel_fb; gfx_context kernel_fb;
gfx_context subcontext; gfx_context subcontext;
@ -19,21 +18,9 @@ void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr)
*fb = 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; gfx_context *out = &subcontext;
uint64_t loc = \ uint64_t loc = \
@ -50,7 +37,7 @@ gfx_context *make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t
return out; return out;
} }
gfx_context *framebuffer_init(struct fbinfo *fbinfo) void framebuffer_init(struct fbinfo *fbinfo)
{ {
kernel_fb.width = fbinfo->framebuffer_width; kernel_fb.width = fbinfo->framebuffer_width;
kernel_fb.height = fbinfo->framebuffer_height; 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); 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;
} }

View File

@ -1,5 +1,5 @@
#include <stdint.h> #include <stdint.h>
#include <vga.h> #include <terminal.h>
#include <framebuffer.h> #include <framebuffer.h>
#include <memory.h> #include <memory.h>
@ -102,7 +102,10 @@ char font[95][16] = {
{0x00, 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {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]; 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(uint64_t x = 0; x < ctx->width; x++)
for(int row = 0; row < rows; row++)
{ {
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);
} }
} }
} }

View File

@ -0,0 +1,71 @@
#include <stdint.h>
#include <terminal.h>
#include <memory.h>
#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;
}
}

View File

@ -0,0 +1,38 @@
#include <terminal.h>
#include <memory.h>
#include <ports.h>
#include <multiboot.h>
#include <stddef.h>
#include <debug.h>
#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);
}

View File

@ -1,94 +0,0 @@
#include <framebuffer.h>
#include <vga.h>
#include <memory.h>
#include <ports.h>
#include <multiboot.h>
#include <stddef.h>
#include <debug.h>
#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;
}
}

View File

@ -26,6 +26,7 @@
do { \ do { \
debug_printf("\n\nKERNEL PANIC!\n%s:%d\n", __FILE__, __LINE__); \ debug_printf("\n\nKERNEL PANIC!\n%s:%d\n", __FILE__, __LINE__); \
debug_printf(__VA_ARGS__); \ debug_printf(__VA_ARGS__); \
debug_printf("\n"); \
volatile int _override = 0; \ volatile int _override = 0; \
while(1) { \ while(1) { \
asm("panic_breakpoint_" S__LINE__ ":"); \ asm("panic_breakpoint_" S__LINE__ ":"); \

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <multiboot.h>
typedef struct { typedef struct {
uint32_t width; uint32_t width;
@ -12,9 +13,11 @@ typedef struct {
size_t size; size_t size;
} gfx_context; } gfx_context;
extern gfx_context kernel_fb;
#define RGB(r, g, b) (((uint32_t) (r<<16) + (g<<8) + (b))) #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); 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); void framebuffer_init(struct fbinfo *fbinfo);

View File

@ -13,6 +13,7 @@
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
struct fbinfo { struct fbinfo {
uint64_t framebuffer_addr; uint64_t framebuffer_addr;

View File

@ -0,0 +1,28 @@
#pragma once
#include <multiboot.h>
#include <framebuffer.h>
#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);

View File

@ -1,27 +0,0 @@
#pragma once
#include <memory.h>
#include <multiboot.h>
#include <framebuffer.h>
#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);