diff --git a/arch/x86_64/include/socks/machine/console.h b/arch/x86_64/include/socks/machine/console.h deleted file mode 100644 index a4100a5..0000000 --- a/arch/x86_64/include/socks/machine/console.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef SOCKS_X86_64_CONSOLE_H_ -#define SOCKS_X86_64_CONSOLE_H_ - -extern void ml_console_init(void); -extern void ml_console_putchar(int c); - -#endif diff --git a/arch/x86_64/include/socks/machine/cpu.h b/arch/x86_64/include/socks/machine/cpu.h index 0d9002f..78eaa3a 100644 --- a/arch/x86_64/include/socks/machine/cpu.h +++ b/arch/x86_64/include/socks/machine/cpu.h @@ -3,6 +3,8 @@ #include +#define ml_halt_cpu() asm volatile("cli;hlt") + typedef struct ml_cpu_block { struct gdt c_gdt; struct gdt_ptr c_gdt_ptr; diff --git a/arch/x86_64/include/socks/machine/vgacon.h b/arch/x86_64/include/socks/machine/vgacon.h new file mode 100644 index 0000000..23ab01f --- /dev/null +++ b/arch/x86_64/include/socks/machine/vgacon.h @@ -0,0 +1,6 @@ +#ifndef SOCKS_X86_64_CONSOLE_H_ +#define SOCKS_X86_64_CONSOLE_H_ + +extern void vgacon_init(void); + +#endif diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c index 3dd8e14..b16211d 100644 --- a/arch/x86_64/init.c +++ b/arch/x86_64/init.c @@ -1,4 +1,5 @@ #include +#include static ml_cpu_block g_bootstrap_cpu = {0}; @@ -11,5 +12,6 @@ static void bootstrap_cpu_init(void) int ml_init(uintptr_t arg) { bootstrap_cpu_init(); + vgacon_init(); return 0; } diff --git a/arch/x86_64/console.c b/arch/x86_64/vgacon.c similarity index 84% rename from arch/x86_64/console.c rename to arch/x86_64/vgacon.c index fa00d36..dc3b652 100644 --- a/arch/x86_64/console.c +++ b/arch/x86_64/vgacon.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #define VGA_PORT_CMD 0x3D4 @@ -36,15 +38,6 @@ static void move_vga_cursor(unsigned int x, unsigned int y) outportb(VGA_PORT_DATA, (uint8_t)((offset >> 8) & 0xFF)); } -void ml_console_init(void) -{ - g_console_cursor_xpos = 0; - g_console_cursor_ypos = 5; - - init_vga_cursor(); - move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos); -} - static void scroll_display() { uint16_t *src = g_console_fb + k_console_width; @@ -79,7 +72,7 @@ static void handle_ctrl(int c) move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos); } -void ml_console_putchar(int c) +static void vgacon_putchar(int c) { if (iscntrl(c)) { handle_ctrl(c); @@ -103,3 +96,29 @@ void ml_console_putchar(int c) move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos); } + +static void vgacon_write(console_t *con, const char *s, unsigned int len) +{ + for (unsigned int i = 0; i < len; i++) { + vgacon_putchar(s[i]); + } +} + +static console_t vgacon = { + .c_name = "vgacon", + .c_flags = CON_BOOT, + .c_write = vgacon_write, + .c_lock = SPIN_LOCK_INIT, +}; + +void vgacon_init(void) +{ + g_console_cursor_xpos = 0; + g_console_cursor_ypos = 5; + + init_vga_cursor(); + move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos); + + console_register(&vgacon); + early_printk_init(&vgacon); +} diff --git a/include/socks/console.h b/include/socks/console.h index 2c3d54b..945072f 100644 --- a/include/socks/console.h +++ b/include/socks/console.h @@ -1,7 +1,29 @@ #ifndef SOCKS_CONSOLE_H_ #define SOCKS_CONSOLE_H_ -extern void console_init(void); -extern void console_putchar(int c); +#include +#include +#include + +typedef enum console_flags { + CON_BOOT = 0x01u, +} console_flags_t; + +typedef struct console { + char c_name[16]; + console_flags_t c_flags; + spin_lock_t c_lock; + + void (*c_write)(struct console *, const char *, unsigned int); + int (*c_read)(struct console *, char *, unsigned int); + + queue_entry_t c_list; +} console_t; + +extern kern_status_t console_register(console_t *con); +extern kern_status_t console_unregister(console_t *con); + +extern void console_write(console_t *con, const char *s, unsigned int len); +extern int console_read(console_t *con, char *s, unsigned int len); #endif diff --git a/include/socks/printk.h b/include/socks/printk.h index 18db15b..1b28d48 100644 --- a/include/socks/printk.h +++ b/include/socks/printk.h @@ -1,6 +1,9 @@ #ifndef SOCKS_PRINTK_H_ #define SOCKS_PRINTK_H_ +#include + +extern void early_printk_init(console_t *con); extern int printk(const char *format, ...); #endif diff --git a/include/socks/status.h b/include/socks/status.h index 6783f49..f4c3274 100644 --- a/include/socks/status.h +++ b/include/socks/status.h @@ -3,7 +3,8 @@ typedef unsigned int kern_status_t; -#define KERN_OK (0) -#define KERN_ERR_UNIMPLEMENTED (1) +#define KERN_OK (0) +#define KERN_UNIMPLEMENTED (1) +#define KERN_NAME_EXISTS (2) #endif diff --git a/init/main.c b/init/main.c index 5355764..177ceec 100644 --- a/init/main.c +++ b/init/main.c @@ -2,12 +2,15 @@ #include #include #include +#include + +extern unsigned long get_rflags(void); void kernel_init(uintptr_t arg) { ml_init(arg); - for (int i = 0; i < 8; i++) { - printk("Line %d\n", i); - } + printk("hello, world!"); + + ml_halt_cpu(); } diff --git a/kernel/console.c b/kernel/console.c index 7f218ae..eb521f9 100644 --- a/kernel/console.c +++ b/kernel/console.c @@ -1,12 +1,52 @@ #include -#include +#include +#include +#include -void console_init(void) +static queue_t consoles; +static spin_lock_t consoles_lock = SPIN_LOCK_INIT; + +kern_status_t console_register(console_t *con) { - ml_console_init(); + unsigned long flags; + spin_lock_irqsave(&consoles_lock, &flags); + + queue_foreach (console_t, cur, &consoles, c_list) { + if (!strcmp(cur->c_name, con->c_name)) { + spin_unlock_irqrestore(&consoles_lock, flags); + return KERN_NAME_EXISTS; + } + } + + queue_push_back(&consoles, &con->c_list); + spin_unlock_irqrestore(&consoles_lock, flags); + return KERN_OK; } -void console_putchar(int c) +kern_status_t console_unregister(console_t *con) { - ml_console_putchar(c); + unsigned long flags; + spin_lock_irqsave(&consoles_lock, &flags); + + queue_delete(&consoles, &con->c_list); + + spin_unlock_irqrestore(&consoles_lock, flags); + return KERN_OK; +} + +void console_write(console_t *con, const char *s, unsigned int len) +{ + if (con->c_write) { + con->c_write(con, s, len); + } +} + +int console_read(console_t *con, char *s, unsigned int len) +{ + int ret = -1; + if (con->c_read) { + ret = con->c_read(con, s, len); + } + + return ret; } diff --git a/kernel/printk.c b/kernel/printk.c index 802e8a0..c0d1d56 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1,10 +1,74 @@ +#include +#include +#include +#include +#include #define LOG_BUFFER_SIZE 0x40000 +#define LOG_MSG_SIZE 0x100 + +static console_t *early_console = NULL; + +static spin_lock_t log_buffer_lock = SPIN_LOCK_INIT; static char log_buffer[LOG_BUFFER_SIZE] = {0}; +/* index of the last character in log_buffer that has been written + to the console */ +static unsigned int log_buffer_readp = 0; +/* index of the last character in log_buffer that has been logged + (but not necessarily written to the console) */ +static unsigned int log_buffer_writep = 0; + +static void flush_log_buffer(void) +{ + if (!early_console) { + return; + } + + console_write(early_console, log_buffer + log_buffer_readp, log_buffer_writep - log_buffer_readp); + log_buffer_readp = log_buffer_writep; +} + +static void save_log_message(const char *msg) +{ + unsigned int i = 0; + while (1) { + if (log_buffer_writep == LOG_BUFFER_SIZE - 1) { + log_buffer[log_buffer_writep] = '\0'; + break; + } + + if (msg[i] == '\0') { + break; + } + + log_buffer[log_buffer_writep++] = msg[i++]; + } +} + +void early_printk_init(console_t *con) +{ + early_console = con; +} int printk(const char *format, ...) { - (void)log_buffer; - return 0; + char msg[LOG_MSG_SIZE]; + + va_list arg; + va_start(arg, format); + int len = vsnprintf(msg, sizeof msg - 1, format, arg); + va_end(arg); + + msg[len] = '\n'; + msg[len + 1] = '\0'; + + unsigned long flags; + spin_lock_irqsave(&log_buffer_lock, &flags); + save_log_message(msg); + spin_unlock_irqrestore(&log_buffer_lock, flags); + + flush_log_buffer(); + + return 0; }