Files
mango/init/main.c
Max Wash b0c021d4e9 kernel: add kernel.early-console and kernel.console boot args
kernel.early-console is used to specify which output device the
kernel boot log should be written to. the first thing the kernel
does on boot after initialising the bootstrap processor is initialise
the early console, making it useful for debugging problems that
occur early in the boot process. this arg accepts a list of hard-coded
values for output devices, such as tty0 for the display or ttyS0
for the serial port. the exact values supported will depend on the
platform.

once all drivers are loaded, the kernel switches to the device specified
by kernel.console for output. unlike kernel.early-console, this arg
specifies the name of a tty device in /dev/tty. this means that, not
only are more devices supported (any device provided by a tty driver),
but the kernel can also get input from the user using this console too
(not used by the kernel itself, but will be used by the user to interact
with userspace programs, like the shell).
2023-12-30 09:09:18 +00:00

160 lines
3.6 KiB
C

#include <stdint.h>
#include <socks/init.h>
#include <socks/arg.h>
#include <socks/clock.h>
#include <socks/input.h>
#include <socks/panic.h>
#include <socks/test.h>
#include <socks/printk.h>
#include <socks/device.h>
#include <socks/tty.h>
#include <socks/kext.h>
#include <socks/object.h>
#include <socks/sched.h>
#include <socks/libc/stdio.h>
#include <socks/machine/init.h>
#include <socks/cpu.h>
#ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON
#include <socks/fbcon.h>
#endif
extern unsigned long get_rflags(void);
extern char __pstart[], __pend[];
void print_kernel_banner(void)
{
printk("Socks kernel version " BUILD_ID);
}
static void hang(void)
{
while (1) {
printk("%d: tick", this_cpu());
milli_sleep(2000);
}
}
void background_thread(void)
{
printk("background_thread() running on processor %u", this_cpu());
milli_sleep(1000);
while (1) {
printk("%d: tock", this_cpu());
milli_sleep(2000);
}
}
static void putchar(char c)
{
unsigned long flags;
struct queue *consoles = get_consoles(&flags);
queue_foreach(struct console, con, consoles, c_list) {
console_write(con, &c, 1);
}
put_consoles(consoles, flags);
}
void kernel_init(uintptr_t arg)
{
ml_init(arg);
kern_status_t status;
status = scan_internal_kexts();
if (status != KERN_OK) {
panic("scan_internal_kexts() failed with code %s", kern_status_string(status));
}
status = bring_internal_kexts_online();
if (status != KERN_OK) {
panic("bring_internal_kexts_online() failed with code %s", kern_status_string(status));
}
scan_all_buses();
printk("kernel_init() running on processor %u", this_cpu());
#ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON
struct object *fb;
status = object_get("/dev/video/fb0", &fb);
if (status == KERN_OK) {
#if 0
struct framebuffer_varinfo fb_mode;
struct device *fbdev = cast_to_device(fb);
framebuffer_get_varinfo(fbdev, &fb_mode);
fb_mode.fb_xres = 1024;
fb_mode.fb_yres = 768;
fb_mode.fb_bpp = 24;
fb_mode.fb_flags = FB_MODE_RGB;
framebuffer_set_varinfo(fbdev, &fb_mode);
#endif
start_console_on_framebuffer(cast_to_device(fb));
}
#endif
struct object *tty0;
status = object_get("/dev/tty/tty0", &tty0);
if (status == KERN_OK) {
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;
run_all_tests();
status = object_get("/dev/input/input0", &kbd);
if (status == KERN_OK) {
tty_connect_foreground_input_device(cast_to_device(kbd));
}
struct object *disk;
status = object_get("/dev/block/disk0", &disk);
if (status == KERN_OK) {
unsigned char buf[32] = {0};
struct device *disk_dev = cast_to_device(disk);
size_t nread = 0;
device_lock(disk_dev);
status = device_read(disk_dev, buf, 1, 32, &nread, 0);
device_unlock(disk_dev);
if (status == KERN_OK) {
printk("read %zu bytes from /dev/block/disk0:", nread);
for (int i = 0; i < sizeof buf; i++) {
printk("%02xh", buf[i]);
}
} else {
printk("failed to read from block device (%s)", kern_status_string(status));
}
} else {
printk("cannot open block device (%s)", kern_status_string(status));
}
hang();
}