diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c index 54eb216..02256e7 100644 --- a/arch/x86_64/init.c +++ b/arch/x86_64/init.c @@ -13,9 +13,9 @@ #include #include #include +#include #include #include -#include #ifdef KEXT_NET_DOORSTUCK_SOCKS_ACPI #include @@ -25,6 +25,10 @@ #include #endif +#ifdef KEXT_NET_DOORSTUCK_SOCKS_SERIALCON +#include +#endif + #define PTR32(x) ((void *)((uintptr_t)(x))) static ml_cpu_block g_bootstrap_cpu = {0}; @@ -54,6 +58,28 @@ static void early_vm_init(void) printk("memblock: reserved bios+kernel at [0x%016llx-0x%016llx]", 0, (uintptr_t)__pend); } +void early_console_init(void) +{ + const char *dest = arg_value("kernel.early-console"); + if (!dest) { + return; + } + +#ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON + if (!strcmp(dest, "tty0")) { + early_vgacon_init(); + } +#endif + +#ifdef KEXT_NET_DOORSTUCK_SOCKS_SERIALCON + if (!strncmp(dest, "ttyS0", 5)) { + /* TODO allow specifying baud rate from command line */ + unsigned int baud = 115200; + early_serialcon_init(baud); + } +#endif +} + static void init_bootfb(multiboot_info_t *mb) { __bootfb_varinfo.fb_xres = mb->framebuffer_width; @@ -109,11 +135,10 @@ int ml_init(uintptr_t arg) init_bootfb(mb); bootstrap_cpu_init(); -#ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON - early_vgacon_init(); -#endif clock_calibrate(500); + early_console_init(); + print_kernel_banner(); early_vm_init(); diff --git a/include/socks/tty.h b/include/socks/tty.h index f3ed714..be46123 100644 --- a/include/socks/tty.h +++ b/include/socks/tty.h @@ -113,6 +113,9 @@ struct tty_device { char *tty_linebuf; }; +extern void register_tty_console(void); +extern void redirect_printk_to_tty(struct device *dest); + extern kern_status_t tty_bootstrap(void); extern struct tty_ldisc *tty_default_line_discipline(void); diff --git a/init/main.c b/init/main.c index 723bac1..15fd9fe 100644 --- a/init/main.c +++ b/init/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -10,6 +11,7 @@ #include #include #include +#include #include #include @@ -29,7 +31,7 @@ void print_kernel_banner(void) static void hang(void) { while (1) { - //printk("tick"); + printk("%d: tick", this_cpu()); milli_sleep(2000); } } @@ -37,10 +39,10 @@ static void hang(void) void background_thread(void) { printk("background_thread() running on processor %u", this_cpu()); - milli_sleep(500); + milli_sleep(1000); while (1) { - //printk("tock"); + printk("%d: tock", this_cpu()); milli_sleep(2000); } } @@ -99,6 +101,26 @@ void kernel_init(uintptr_t arg) tty_set_foreground(cast_to_device(tty0)); } + const char *console_tty_name = arg_value("kernel.console"); + if (!console_tty_name) { + console_tty_name = "tty0"; + } + + char console_tty_path[128]; + snprintf(console_tty_path, sizeof console_tty_path, "/dev/tty/%s", console_tty_name); + + struct object *console_tty = NULL; + status = object_get(console_tty_path, &console_tty); + + if (status == KERN_OK) { + register_tty_console(); + struct device *console_tty_device = cast_to_device(console_tty); + redirect_printk_to_tty(console_tty_device); + object_deref(console_tty); + } else { + printk("console tty '%s' is unavailable.", console_tty_name); + } + create_kernel_thread(background_thread); struct object *kbd; diff --git a/kernel/tty/device.c b/kernel/tty/device.c index 1a9d5ff..53f87dc 100644 --- a/kernel/tty/device.c +++ b/kernel/tty/device.c @@ -9,10 +9,13 @@ static struct char_device_ops tty_ops = { .write = tty_write, }; -static spin_lock_t foreground_lock; +static spin_lock_t foreground_lock = SPIN_LOCK_INIT; static struct device *foreground = NULL; static struct device *foreground_input = NULL; +static spin_lock_t kernel_console_tty_lock = SPIN_LOCK_INIT; +static struct device *kernel_console_tty = NULL; + static void tty_input_hook_callback(struct device *dev, struct input_event *ev, enum input_event_hook_flags *flags, void *arg) { struct device *fg_tty = foreground; @@ -31,9 +34,9 @@ static struct input_event_hook foreground_input_hook = { static void tty_console_write(struct console *con, const char *s, unsigned int len) { - if (foreground) { + if (kernel_console_tty) { size_t nr_written; - tty_write(foreground, s, 0, len, &nr_written, 0); + tty_write(kernel_console_tty, s, 0, len, &nr_written, 0); } } @@ -42,6 +45,26 @@ static struct console tty_console = { .c_write = tty_console_write, }; +void register_tty_console(void) +{ + console_register(&tty_console); +} + +void redirect_printk_to_tty(struct device *dest) +{ + unsigned long flags; + spin_lock_irqsave(&kernel_console_tty_lock, &flags); + + if (kernel_console_tty) { + device_deref(kernel_console_tty); + kernel_console_tty = NULL; + } + + kernel_console_tty = device_ref(dest); + + spin_unlock_irqrestore(&kernel_console_tty_lock, flags); +} + struct device *tty_device_create(void) { struct char_device *cdev = char_device_create(); @@ -94,17 +117,17 @@ kern_status_t tty_device_register(struct device *dev, struct tty_driver *owner, void tty_set_foreground(struct device *tty) { - bool console_init = false; + unsigned long flags; + spin_lock_irqsave(&foreground_lock, &flags); + if (foreground) { - console_init = true; device_deref(foreground); + foreground = NULL; } foreground = device_ref(tty); - if (!console_init) { - console_register(&tty_console); - } + spin_unlock_irqrestore(&foreground_lock, flags); } kern_status_t tty_connect_foreground_input_device(struct device *input) diff --git a/kexts/drivers/tty/serialcon/serial.h b/kexts/drivers/tty/serialcon/include/socks/serialcon.h similarity index 91% rename from kexts/drivers/tty/serialcon/serial.h rename to kexts/drivers/tty/serialcon/include/socks/serialcon.h index 8daaa8b..2c5da92 100644 --- a/kexts/drivers/tty/serialcon/serial.h +++ b/kexts/drivers/tty/serialcon/include/socks/serialcon.h @@ -18,7 +18,7 @@ extern char serial_recv_byte(int device); extern int serial_rcvd(int device); -extern void serialcon_init(int baud); +extern void early_serialcon_init(int baud); #ifdef __cplusplus } diff --git a/kexts/drivers/tty/serialcon/main.c b/kexts/drivers/tty/serialcon/main.c index e364991..18576eb 100644 --- a/kexts/drivers/tty/serialcon/main.c +++ b/kexts/drivers/tty/serialcon/main.c @@ -5,7 +5,7 @@ #include #include #include -#include "serial.h" +#include #define COM1 0x3F8 #define COM2 0x2F8 @@ -155,7 +155,7 @@ static struct irq_hook irq1_hook = { .irq_callback = serial_irq1, }; -void serialcon_init(int baud) +void early_serialcon_init(int baud) { hook_irq(IRQ4, &irq1_hook); init_serial_port(COM1, baud);