[BOOT] Print functions for debugging
This commit is contained in:
132
kernel/boot/debug.c
Normal file
132
kernel/boot/debug.c
Normal file
@@ -0,0 +1,132 @@
|
||||
#include <debug.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <vga.h>
|
||||
#include <serial.h>
|
||||
|
||||
void debug_init()
|
||||
{
|
||||
vga_init();
|
||||
serial_init(PORT_COM1);
|
||||
}
|
||||
|
||||
uint64_t num2str(uint64_t num, uint32_t base, char *buf)
|
||||
{
|
||||
// Convert a number to string
|
||||
if(num == 0)
|
||||
{
|
||||
buf[0] = '0';
|
||||
buf[1] = '\0';
|
||||
return 0;
|
||||
}
|
||||
uint32_t i=0, j=0;
|
||||
char chars[] = "0123456789ABCDEF";
|
||||
// Build the string starting with the least significant digit
|
||||
while(num > 0)
|
||||
{
|
||||
buf[i++] = chars[num%base];
|
||||
num /= base;
|
||||
}
|
||||
|
||||
// Invert the string to get digits in right order
|
||||
i--;
|
||||
j=0;
|
||||
while(j<i)
|
||||
{
|
||||
char t = buf[i];
|
||||
buf[i--] = buf[j];
|
||||
buf[j++] = t;
|
||||
}
|
||||
|
||||
// Zero terminate
|
||||
buf[i+j+1] = '\0';
|
||||
return i+j+1;
|
||||
}
|
||||
|
||||
void debug_putch(char c)
|
||||
{
|
||||
vga_printch(c);
|
||||
serial_write(PORT_COM1, c);
|
||||
}
|
||||
void debug_putsn(char *s, size_t n)
|
||||
{
|
||||
while(n--)
|
||||
debug_putch(*s++);
|
||||
}
|
||||
void debug_puts(char *s)
|
||||
{
|
||||
debug_putsn(s, strlen(s));
|
||||
}
|
||||
|
||||
void debug_vprintf(char *str, va_list args)
|
||||
{
|
||||
size_t len = 0;
|
||||
if(!(*str))
|
||||
return;
|
||||
if(*str != '%')
|
||||
{
|
||||
while(str[len] && str[len] != '%')
|
||||
len++;
|
||||
debug_putsn(str, len);
|
||||
return debug_vprintf(&str[len], args);
|
||||
}
|
||||
str++;
|
||||
char *prefix;
|
||||
uint32_t base = 0;
|
||||
#define DEBUG_VPRINTF_BASE_CHAR 255
|
||||
#define DEBUG_VPRINTF_BASE_STR 1024
|
||||
switch(*str)
|
||||
{
|
||||
case 'b':
|
||||
prefix = "0b";
|
||||
base = 2;
|
||||
break;
|
||||
case 'o':
|
||||
prefix = "0";
|
||||
base = 8;
|
||||
break;
|
||||
case 'd':
|
||||
prefix = "";
|
||||
base = 10;
|
||||
break;
|
||||
case 'x':
|
||||
prefix = "0x";
|
||||
base = 16;
|
||||
break;
|
||||
case 'c':
|
||||
prefix = "";
|
||||
base = DEBUG_VPRINTF_BASE_CHAR;
|
||||
break;
|
||||
case 's':
|
||||
prefix = "";
|
||||
base = DEBUG_VPRINTF_BASE_STR;
|
||||
break;
|
||||
case '%':
|
||||
default:
|
||||
debug_putch('%');
|
||||
break;
|
||||
}
|
||||
if(base == DEBUG_VPRINTF_BASE_STR)
|
||||
debug_puts(va_arg(args, char *));
|
||||
else if(base == DEBUG_VPRINTF_BASE_CHAR)
|
||||
debug_putch((char)va_arg(args, uint64_t));
|
||||
else if(base)
|
||||
{
|
||||
uint64_t num = va_arg(args, uint64_t);
|
||||
char buf[128];
|
||||
num2str(num, base, buf);
|
||||
debug_puts(prefix);
|
||||
debug_puts(buf);
|
||||
}
|
||||
str++;
|
||||
return debug_vprintf(str, args);
|
||||
}
|
||||
|
||||
void debug_printf(char *str, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
debug_vprintf(str, args);
|
||||
va_end(args);
|
||||
}
|
||||
@@ -1,34 +1,22 @@
|
||||
#include <mem.h>
|
||||
|
||||
#define VGA_MEMORY 0xb8000
|
||||
#define VGA_ROWS 24
|
||||
#define VGA_COLS 80
|
||||
|
||||
void clear_screen()
|
||||
{
|
||||
// Clear the video memory
|
||||
unsigned char *m = (void *)P2V(VGA_MEMORY);
|
||||
for(int i = 0; i < VGA_ROWS*VGA_COLS*2; i++)
|
||||
{
|
||||
*m++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void prints(const char *s, unsigned int row, unsigned int col)
|
||||
{
|
||||
// Very simple pure ascii string printing
|
||||
unsigned char *m = (void *)P2V(VGA_MEMORY);
|
||||
m += 2*VGA_COLS*row+2*col;
|
||||
while(*s)
|
||||
{
|
||||
*m++ = *s++;
|
||||
*m++ = 0x7;
|
||||
}
|
||||
}
|
||||
#include <debug.h>
|
||||
|
||||
int kmain(void)
|
||||
{
|
||||
clear_screen();
|
||||
prints("Hello, world!", 0, 0);
|
||||
debug_init();
|
||||
debug_ok("MITTOS64 kernel booted\n");
|
||||
debug_build_time();
|
||||
debug_git_info();
|
||||
|
||||
// Test the printf functions
|
||||
debug("binary:%b octal:%o dec:%d\n", 0xAA55, 0123, 456);
|
||||
debug("hex:%x string:%s char:%c\n", 0xabcd, "Hello", 'T');
|
||||
debug("pointer:%x\n", kmain);
|
||||
|
||||
debug_info("An information string\n");
|
||||
debug_ok("%s prints ok\n", "This string");
|
||||
debug_warning("A warning message\n");
|
||||
debug_error("%d is less than %x\n", 12, 17);
|
||||
|
||||
debug_info("BOOT COMPLETE\n");
|
||||
for(;;)asm("hlt");
|
||||
}
|
||||
|
||||
20
kernel/boot/version.c
Normal file
20
kernel/boot/version.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <debug.h>
|
||||
|
||||
char *_kernel_build_date = __DATE__;
|
||||
char *_kernel_build_time = __TIME__;
|
||||
|
||||
char *_kernel_git_hash = GITHASH;
|
||||
char *_kernel_git_date = GITDATE;
|
||||
int _kernel_git_dirty = GITDIRTY;
|
||||
char *_kernel_git_message = GITMESSAGE;
|
||||
char *_kernel_git_branch = GITBRANCH;
|
||||
|
||||
void debug_build_time()
|
||||
{
|
||||
debug_info("Kernel built: %s (%s)\n", _kernel_build_date, _kernel_build_time);
|
||||
}
|
||||
void debug_git_info()
|
||||
{
|
||||
debug_info("Kernel git: %s%s%s %s\n", _kernel_git_branch, _kernel_git_hash, (_kernel_git_dirty)?" (dirty)":"", _kernel_git_date);
|
||||
debug_info("Git message: %s\n", _kernel_git_message);
|
||||
}
|
||||
Reference in New Issue
Block a user