Refactoring debug terminal
This commit is contained in:
parent
a09c160bcb
commit
38181eb728
@ -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
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <vga.h>
|
||||
#include <memory.h>
|
||||
#include <terminal.h>
|
||||
|
||||
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)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <stdint.h>
|
||||
#include <cpu.h>
|
||||
#include <memory.h>
|
||||
#include <vga.h>
|
||||
#include <terminal.h>
|
||||
#include <debug.h>
|
||||
#include <multiboot.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)
|
||||
{
|
||||
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");
|
||||
|
||||
|
@ -16,7 +16,6 @@ Multiboot2Header:
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
|
||||
.long 0 //; Pad to multiple of 8 bytes
|
||||
|
||||
.short 0 //; End tag
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <memory.h>
|
||||
#include <multiboot.h>
|
||||
#include <framebuffer.h>
|
||||
#include <vga.h>
|
||||
|
||||
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;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#include <stdint.h>
|
||||
#include <vga.h>
|
||||
#include <terminal.h>
|
||||
#include <framebuffer.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},
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
71
src/kernel/drivers/terminal/terminal.c
Normal file
71
src/kernel/drivers/terminal/terminal.c
Normal 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;
|
||||
}
|
||||
}
|
38
src/kernel/drivers/terminal/vga.c
Normal file
38
src/kernel/drivers/terminal/vga.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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__ ":"); \
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
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);
|
||||
void framebuffer_init(struct fbinfo *fbinfo);
|
@ -13,6 +13,7 @@
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct fbinfo {
|
||||
uint64_t framebuffer_addr;
|
||||
|
28
src/kernel/include/terminal.h
Normal file
28
src/kernel/include/terminal.h
Normal 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);
|
@ -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);
|
Loading…
x
Reference in New Issue
Block a user