feature: log level on kprintf (color)

fix: kprintf now uses concatenated strings for the flag
This commit is contained in:
0x35c 2024-09-20 12:40:36 +02:00
parent 4cc1dba5f9
commit 2e41858c77
13 changed files with 99 additions and 81 deletions

View File

@ -2,18 +2,15 @@
#include <stdarg.h> #include <stdarg.h>
enum print_level { #define KERN_EMERG "0"
KERN_EMERG, #define KERN_ALERT "1"
KERN_ALERT, #define KERN_CRIT "2"
KERN_CRIT, #define KERN_ERR "3"
KERN_ERR, #define KERN_WARNING "4"
KERN_WARNING, #define KERN_NOTICE "5"
KERN_NOTICE, #define KERN_INFO "6"
KERN_INFO, #define KERN_DEBUG "7"
KERN_DEBUG, #define KERN_DEFAULT "8"
KERN_DEFAULT,
KERN_CONT
};
int kprintf(int level, const char *restrict format, ...); int kprintf(const char *restrict format, ...);
int kvprintf(int level, const char *restrict format, va_list ap); int kvprintf(const char *restrict format, va_list ap);

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "keyboard.h" #include "keyboard.h"
#include "kprintf.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@ -18,7 +19,7 @@ struct screen {
char line[256]; char line[256];
}; };
enum vga_color { typedef enum {
VGA_COLOR_BLACK = 0, VGA_COLOR_BLACK = 0,
VGA_COLOR_BLUE = 1, VGA_COLOR_BLUE = 1,
VGA_COLOR_GREEN = 2, VGA_COLOR_GREEN = 2,
@ -33,9 +34,9 @@ enum vga_color {
VGA_COLOR_LIGHT_CYAN = 11, VGA_COLOR_LIGHT_CYAN = 11,
VGA_COLOR_LIGHT_RED = 12, VGA_COLOR_LIGHT_RED = 12,
VGA_COLOR_LIGHT_MAGENTA = 13, VGA_COLOR_LIGHT_MAGENTA = 13,
VGA_COLOR_LIGHT_BROWN = 14, VGA_COLOR_LIGHT_YELLOW = 14,
VGA_COLOR_WHITE = 15, VGA_COLOR_WHITE = 15,
}; } vga_color;
enum cursor_direction { LEFT, RIGHT, UP, DOWN }; enum cursor_direction { LEFT, RIGHT, UP, DOWN };
@ -50,3 +51,4 @@ void terminal_clear(void);
struct key_event terminal_getkey(void); struct key_event terminal_getkey(void);
void update_cursor(void); void update_cursor(void);
void move_cursor(int direction); void move_cursor(int direction);
void set_color_level(int level);

View File

@ -34,4 +34,4 @@ int isupper_l(int c, locale_t locale);
int isxdigit_l(int c, locale_t locale); int isxdigit_l(int c, locale_t locale);
int isascii_l(int c, locale_t locale); int isascii_l(int c, locale_t locale);
*/ */

View File

@ -7,7 +7,7 @@ void print_stack(void)
(struct stackframe *)__builtin_frame_address(0); (struct stackframe *)__builtin_frame_address(0);
while (stack) { while (stack) {
kprintf(0, "fn: %d\n", stack->eip); kprintf(KERN_DEBUG "fn: %d\n", stack->eip);
stack = stack->ebp; stack = stack->ebp;
} }
} }

View File

@ -12,7 +12,7 @@ static void set_gdt_entry_value(uint8_t *target, uint32_t base, uint32_t limit,
uint8_t access, uint8_t granularity) uint8_t access, uint8_t granularity)
{ {
if (limit > 0xFFFFF) { if (limit > 0xFFFFF) {
kprintf(KERN_ERR, kprintf(KERN_ERR
"GDT cannot encode limits larger than 0xFFFFF"); "GDT cannot encode limits larger than 0xFFFFF");
} }

View File

@ -25,25 +25,11 @@ void kernel_main(void)
terminal_initialize(); terminal_initialize();
init_gdt(); init_gdt();
init_memory(); init_memory();
char *str = kalloc_frame(104831); kprintf(KERN_CRIT "KERN_CRIT\n");
str = kalloc_frame(104831); kprintf(KERN_ALERT "KERN_ALERT\n");
str = kalloc_frame(104831); kprintf(KERN_WARNING "KERN_WARNING\n");
str = kalloc_frame(104831); kprintf(KERN_NOTICE "KERN_NOTICE\n");
str = kalloc_frame(104831); kprintf(KERN_INFO "KERN_INFO\n");
str = kalloc_frame(104831); kprintf(KERN_DEBUG "KERN_DEBUG\n");
str = kalloc_frame(104831);
str = kalloc_frame(104831);
str = kalloc_frame(104831);
str = kalloc_frame(104831);
kfree_frame(str, 104831);
str = kalloc_frame(104831);
kfree_frame(str, 104831);
str = kalloc_frame(104831);
kfree_frame(str, 104831);
str = kalloc_frame(104831);
kfree_frame(str, 104831);
str = kalloc_frame(104831);
memcpy(str, "Hello world!\n", 15);
kprintf(KERN_INFO, "%d: %s", str, str);
shell_init(); shell_init();
} }

View File

@ -1,17 +1,14 @@
#include "kprintf.h" #include "kprintf.h"
#include "ctype.h"
#include "string.h"
#include "terminal.h"
#include <stdarg.h> #include <stdarg.h>
int kprintf(int level, const char *restrict format, ...) int kprintf(const char *restrict format, ...)
{ {
va_list va; va_list va;
int i; int i;
va_start(va, format); va_start(va, format);
i = kvprintf(level, format, va); i = kvprintf(format, va);
va_end(va); va_end(va);
return i; return i;
} }

View File

@ -1,11 +1,15 @@
#include "ctype.h" #include "ctype.h"
#include "kprintf.h"
#include "stdlib.h"
#include "string.h"
#include "terminal.h" #include "terminal.h"
#include <stdarg.h> #include <stdarg.h>
static int get_level(const char *str)
{
if (!str || !isdigit(str[0]))
return 8;
return str[0] - '0';
}
static int print_flag(char flag, va_list *ap) static int print_flag(char flag, va_list *ap)
{ {
switch (flag) { switch (flag) {
@ -23,12 +27,15 @@ static int print_flag(char flag, va_list *ap)
return 0; return 0;
} }
int kvprintf(int level, const char *restrict format, va_list ap) int kvprintf(const char *restrict format, va_list ap)
{ {
const char *start = format; const char *start = format;
int ret = 0; int ret = 0;
(void)level; int level = get_level(format);
set_color_level(level);
if (level != 8)
start++;
while (*start != '\0') { while (*start != '\0') {
if (*start == '%' && *(start + 1) != '\0') { if (*start == '%' && *(start + 1) != '\0') {
ret += print_flag(*(start + 1), &ap); ret += print_flag(*(start + 1), &ap);
@ -38,6 +45,7 @@ int kvprintf(int level, const char *restrict format, va_list ap)
} }
start++; start++;
} }
set_color_level(8);
update_cursor(); update_cursor();
return ret; return ret;
} }

View File

@ -24,7 +24,7 @@ static uint32_t remaining_frames = MAX_FRAMES;
void *kalloc_frame(uint32_t nb_frames) void *kalloc_frame(uint32_t nb_frames)
{ {
if (nb_frames > remaining_frames) { if (nb_frames > remaining_frames) {
kprintf(KERN_CRIT, "Not enough frames (max: %d)\n", MAX_FRAMES); kprintf(KERN_CRIT "Not enough frames (max: %d)\n", MAX_FRAMES);
return NULL; return NULL;
} }
size_t i = 0; size_t i = 0;
@ -44,7 +44,7 @@ end:
remaining_frames -= nb_frames; remaining_frames -= nb_frames;
return &end_kernel + i * PAGE_SIZE; return &end_kernel + i * PAGE_SIZE;
} }
kprintf(KERN_WARNING, "Not enough frames available\n", MAX_FRAMES); kprintf(KERN_WARNING "Not enough frames available\n", MAX_FRAMES);
return NULL; return NULL;
} }
@ -53,13 +53,13 @@ void kfree_frame(void *frame, uint32_t nb_frames)
const uint32_t start = (frame - (void *)&end_kernel) / PAGE_SIZE; const uint32_t start = (frame - (void *)&end_kernel) / PAGE_SIZE;
if (start > MAX_FRAMES || frame < (void *)&end_kernel) { if (start > MAX_FRAMES || frame < (void *)&end_kernel) {
kprintf(KERN_WARNING, "Address out of range\n"); kprintf(KERN_WARNING "Address out of range\n");
return; return;
} else if ((uint32_t)frame % PAGE_SIZE) { } else if ((uint32_t)frame % PAGE_SIZE) {
kprintf(KERN_WARNING, "Invalid address\n"); kprintf(KERN_WARNING "Invalid address\n");
return; return;
} else if (start + nb_frames > MAX_FRAMES) { } else if (start + nb_frames > MAX_FRAMES) {
kprintf(KERN_WARNING, "Invalid number of frames\n"); kprintf(KERN_WARNING "Invalid number of frames\n");
return; return;
} }
for (size_t i = start; i < start + nb_frames; i++) for (size_t i = start; i < start + nb_frames; i++)

View File

@ -20,7 +20,7 @@ static uint8_t update_is_in_progress(void)
static uint16_t read_register(uint16_t cmos_register) static uint16_t read_register(uint16_t cmos_register)
{ {
while (update_is_in_progress()) while (update_is_in_progress())
kprintf(0, "%d\n", update_is_in_progress()); kprintf("%d\n", update_is_in_progress());
return raw_read_register(cmos_register); return raw_read_register(cmos_register);
} }

View File

@ -32,19 +32,19 @@ static void help(void)
{ {
const size_t padding = 15; const size_t padding = 15;
kprintf(0, "%s\n", BORDER); kprintf("%s\n", BORDER);
kprintf(0, " %s\n", HEADER); kprintf(" %s\n", HEADER);
kprintf(0, "%s\n", BORDER); kprintf("%s\n", BORDER);
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
kprintf(0, " %s", commands[i].name); kprintf(" %s", commands[i].name);
for (size_t j = 0; j < (padding - strlen(commands[i].name)); for (size_t j = 0; j < (padding - strlen(commands[i].name));
j++) j++)
kprintf(0, " "); kprintf(" ");
kprintf(0, ": %s\n", commands[i].description); kprintf(": %s\n", commands[i].description);
} }
kprintf(0, "%s\n", BORDER); kprintf("%s\n", BORDER);
} }
static void auto_complete(void) static void auto_complete(void)
@ -63,7 +63,7 @@ static void auto_complete(void)
return; return;
for (size_t i = len; last_match[i]; i++) { for (size_t i = len; last_match[i]; i++) {
screen->line[i] = last_match[i]; screen->line[i] = last_match[i];
kprintf(0, "%c", screen->line[i]); kprintf("%c", screen->line[i]);
} }
} }
@ -89,7 +89,7 @@ static void read_line(void)
} else if (ev.scan_code == KEY_TAB && i) { } else if (ev.scan_code == KEY_TAB && i) {
auto_complete(); auto_complete();
} else if (ev.c && i < size - 1) { } else if (ev.c && i < size - 1) {
kprintf(0, "%c", ev.c); kprintf("%c", ev.c);
buf[i++] = ev.c; buf[i++] = ev.c;
} }
if (i >= size) if (i >= size)
@ -97,14 +97,14 @@ static void read_line(void)
} }
prev_scan_code = ev.scan_code; prev_scan_code = ev.scan_code;
} }
kprintf(0, "\n"); kprintf("\n");
screen->line[i] = '\0'; screen->line[i] = '\0';
} }
void shell_init(void) void shell_init(void)
{ {
while (1) { while (1) {
kprintf(0, PROMPT); kprintf(PROMPT);
read_line(); read_line();
bool invalid = true; bool invalid = true;
for (int i = 0; i < NB_CMDS; i++) { for (int i = 0; i < NB_CMDS; i++) {
@ -115,7 +115,7 @@ void shell_init(void)
} }
} }
if (invalid && screen->line[0]) if (invalid && screen->line[0])
kprintf(0, "invalid command: %s\n", screen->line); kprintf("invalid command: %s\n", screen->line);
memset(screen->line, '\0', sizeof(screen->line)); memset(screen->line, '\0', sizeof(screen->line));
} }
} }

View File

@ -3,5 +3,5 @@
void merdella(void) void merdella(void)
{ {
kprintf(0, POOP); kprintf(POOP);
} }

View File

@ -12,7 +12,7 @@
static struct screen screens[TERM_COUNT]; static struct screen screens[TERM_COUNT];
struct screen *screen = &screens[0]; struct screen *screen = &screens[0];
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) static inline uint8_t vga_entry_color(vga_color fg, vga_color bg)
{ {
return fg | bg << 4; return fg | bg << 4;
} }
@ -33,8 +33,8 @@ void terminal_initialize(void)
for (int i = 0; i < TERM_COUNT; i++) { for (int i = 0; i < TERM_COUNT; i++) {
screens[i].row = 0; screens[i].row = 0;
screens[i].column = 0; screens[i].column = 0;
screens[i].color = vga_entry_color(VGA_COLOR_LIGHT_MAGENTA - i, screens[i].color =
VGA_COLOR_BLACK); vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
memcpy(screens[i].buffer, TERM_BUF, sizeof(screen->buffer)); memcpy(screens[i].buffer, TERM_BUF, sizeof(screen->buffer));
} }
} }
@ -46,7 +46,7 @@ void terminal_set_screen(int pos)
memcpy(TERM_BUF, screen->buffer, sizeof(screen->buffer)); memcpy(TERM_BUF, screen->buffer, sizeof(screen->buffer));
update_cursor(); update_cursor();
if (TERM_BUF[0] == vga_entry(' ', VGA_COLOR_WHITE)) if (TERM_BUF[0] == vga_entry(' ', VGA_COLOR_WHITE))
kprintf(0, PROMPT); kprintf(PROMPT);
} }
void terminal_setcolor(uint8_t color) void terminal_setcolor(uint8_t color)
@ -148,7 +148,6 @@ void update_cursor(void)
void move_cursor(int direction) void move_cursor(int direction)
{ {
switch (direction) { switch (direction) {
case LEFT: case LEFT:
if (screen->column) { if (screen->column) {
@ -175,11 +174,40 @@ void move_cursor(int direction)
default: default:
break; break;
} }
update_cursor();
uint16_t pos = screen->row * VGA_WIDTH + screen->column; }
outb(0x3D4, 0x0F); void set_color_level(int level)
outb(0x3D5, pos & 0xFF); {
outb(0x3D4, 0x0E); switch (level) {
outb(0x3D5, (pos >> 8) & 0xFF); case 0:
screen->color = VGA_COLOR_RED;
break;
case 1:
screen->color = VGA_COLOR_RED;
break;
case 2:
screen->color = VGA_COLOR_MAGENTA;
break;
case 3:
screen->color = VGA_COLOR_LIGHT_YELLOW;
break;
case 4:
screen->color = VGA_COLOR_LIGHT_YELLOW;
break;
case 5:
screen->color = VGA_COLOR_LIGHT_BLUE;
break;
case 6:
screen->color = VGA_COLOR_GREEN;
break;
case 7:
screen->color = VGA_COLOR_LIGHT_GREY;
break;
case 8:
screen->color = VGA_COLOR_WHITE;
break;
default:
break;
}
} }