kernel: remove everything that is related to device/fs management

this is now a microkernel.
This commit is contained in:
2024-09-17 17:47:50 +01:00
parent 9b00f83ff1
commit 3f992d84fb
66 changed files with 213 additions and 65447 deletions

View File

@@ -1,162 +0,0 @@
#include <socks/tty.h>
#include <socks/device.h>
#include <socks/console.h>
#include <socks/input.h>
#include <socks/libc/stdio.h>
static struct char_device_ops tty_ops = {
.read = tty_read,
.write = tty_write,
};
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;
if (!fg_tty) {
return;
}
tty_report_event(fg_tty, ev);
*flags = 0;
}
static struct input_event_hook foreground_input_hook = {
.hook_callback = tty_input_hook_callback,
};
static void tty_console_write(struct console *con, const char *s, unsigned int len)
{
if (kernel_console_tty) {
size_t nr_written;
tty_write(kernel_console_tty, s, 0, len, &nr_written, 0);
}
}
static struct console tty_console = {
.c_name = "tty",
.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();
if (!cdev) {
return NULL;
}
struct tty_device *tty_dev = kmalloc(sizeof *tty_dev, VM_NORMAL);
if (!tty_dev) {
object_deref(char_device_object(cdev));
return NULL;
}
kern_status_t status = ringbuffer_init(&tty_dev->tty_input, TTY_INPUT_QUEUE_SIZE * sizeof(char));
if (status != KERN_OK) {
kfree(tty_dev);
object_deref(char_device_object(cdev));
return NULL;
}
tty_dev->tty_ldisc = tty_default_line_discipline();
cdev->c_ops = &tty_ops;
cdev->c_tty = tty_dev;
return char_device_base(cdev);
}
static kern_status_t generate_name(struct tty_driver *owner, struct device *dev, char out[DEV_NAME_MAX])
{
/* minor numbers start at 1. subtract 1 to start at 0 instead */
snprintf(out, DEV_NAME_MAX, "%s%u", owner->tty_name, dev->dev_minor - 1);
return KERN_OK;
}
kern_status_t tty_device_register(struct device *dev, struct tty_driver *owner, struct device *parent)
{
kern_status_t status = device_register(dev, tty_driver_base(owner), parent);
if (status != KERN_OK) {
return status;
}
char link_name[DEV_NAME_MAX];
generate_name(owner, dev, link_name);
char link_path[OBJECT_PATH_MAX];
snprintf(link_path, sizeof link_path, "/dev/tty/%s", link_name);
return object_namespace_create_link(global_namespace(), link_path, &dev->dev_base);
}
void tty_set_foreground(struct device *tty)
{
unsigned long flags;
spin_lock_irqsave(&foreground_lock, &flags);
if (foreground) {
device_deref(foreground);
foreground = NULL;
}
foreground = device_ref(tty);
spin_unlock_irqrestore(&foreground_lock, flags);
}
kern_status_t tty_connect_foreground_input_device(struct device *input)
{
struct input_device *inputdev = INPUT_DEVICE(input);
if (!inputdev) {
return KERN_INVALID_ARGUMENT;
}
unsigned long flags;
spin_lock_irqsave(&foreground_lock, &flags);
if (foreground_input) {
struct device *prev = foreground_input;
foreground_input = NULL;
device_lock(prev);
input_device_remove_hook(prev, &foreground_input_hook);
device_unlock(prev);
device_deref(prev);
object_deref(&prev->dev_base);
}
foreground_input = device_ref(input);
device_lock(input);
input_device_add_hook(input, &foreground_input_hook);
device_unlock(input);
spin_unlock_irqrestore(&foreground_lock, flags);
return KERN_OK;
}

View File

@@ -1,71 +0,0 @@
#include <socks/tty.h>
static struct vm_cache tty_driver_cache = {
.c_name = "tty_driver",
.c_obj_size = sizeof(struct tty_driver),
};
static struct queue tty_drivers;
static spin_lock_t tty_drivers_lock;
kern_status_t tty_bootstrap(void)
{
vm_cache_init(&tty_driver_cache);
tty_drivers = QUEUE_INIT;
tty_drivers_lock = SPIN_LOCK_INIT;
return KERN_OK;
}
struct tty_driver *tty_driver_create(struct kext *self, const char *name)
{
struct tty_driver *driver = vm_cache_alloc(&tty_driver_cache, VM_NORMAL);
if (!driver) {
return NULL;
}
kern_status_t status = driver_init(&driver->tty_base, self, name);
if (status != KERN_OK) {
vm_cache_free(&tty_driver_cache, driver);
return NULL;
}
strncpy(driver->tty_name, name, sizeof driver->tty_name - 1);
return driver;
}
kern_status_t tty_driver_destroy(struct tty_driver *driver)
{
/* TODO */
return KERN_UNIMPLEMENTED;
}
kern_status_t tty_driver_register(struct tty_driver *driver)
{
kern_status_t status = driver_register(&driver->tty_base);
if (status != KERN_OK) {
return status;
}
unsigned long flags;
spin_lock_irqsave(&tty_drivers_lock, &flags);
queue_push_back(&tty_drivers, &driver->tty_head);
spin_unlock_irqrestore(&tty_drivers_lock, flags);
return KERN_OK;
}
kern_status_t tty_driver_unregister(struct tty_driver *driver)
{
if (driver->tty_base.drv_major == DEV_MAJOR_INVALID) {
return KERN_INVALID_ARGUMENT;
}
unsigned long flags;
spin_lock_irqsave(&tty_drivers_lock, &flags);
queue_delete(&tty_drivers, &driver->tty_head);
spin_unlock_irqrestore(&tty_drivers_lock, flags);
return driver_unregister(&driver->tty_base);
}

View File

@@ -1,401 +0,0 @@
#include <socks/tty.h>
#include <socks/input.h>
#include <socks/libc/ctype.h>
static void default_ldisc_write(struct device *, const struct input_event *);
static kern_status_t default_ldisc_read(struct device *tty, void *buf, size_t max, size_t *nr_read, socks_flags_t flags);
static char keycode_chars[] = {
[KEY_UNKNOWN] = ' ',
[KEY_A] = 'a',
[KEY_B] = 'b',
[KEY_C] = 'c',
[KEY_D] = 'd',
[KEY_E] = 'e',
[KEY_F] = 'f',
[KEY_G] = 'g',
[KEY_H] = 'h',
[KEY_I] = 'i',
[KEY_J] = 'j',
[KEY_K] = 'k',
[KEY_L] = 'l',
[KEY_M] = 'm',
[KEY_N] = 'n',
[KEY_O] = 'o',
[KEY_P] = 'p',
[KEY_Q] = 'q',
[KEY_R] = 'r',
[KEY_S] = 's',
[KEY_T] = 't',
[KEY_U] = 'u',
[KEY_V] = 'v',
[KEY_W] = 'w',
[KEY_X] = 'x',
[KEY_Y] = 'y',
[KEY_Z] = 'z',
[KEY_KEY_1] = '1',
[KEY_KEY_2] = '2',
[KEY_KEY_3] = '3',
[KEY_KEY_4] = '4',
[KEY_KEY_5] = '5',
[KEY_KEY_6] = '6',
[KEY_KEY_7] = '7',
[KEY_KEY_8] = '8',
[KEY_KEY_9] = '9',
[KEY_KEY_0] = '0',
[KEY_ENTER] = '\n',
[KEY_ESCAPE] = 0,
[KEY_BACKSPACE] = '\b',
[KEY_TAB] = ' ',
[KEY_SPACE] = ' ',
[KEY_MINUS] = '-',
[KEY_EQUALS] = '=',
[KEY_LEFT_BRACE] = '[',
[KEY_RIGHT_BRACE] = ']',
[KEY_BACKSLASH] = '\\',
[KEY_NON_US_HASH] = 0,
[KEY_SEMICOLON] = ';',
[KEY_APOSTROPHE] = '\'',
[KEY_GRAVE_ACCENT] = 0,
[KEY_COMMA] = ',',
[KEY_DOT] = '.',
[KEY_SLASH] = '/',
[KEY_CAPS_LOCK] = 0,
[KEY_F1] = 0,
[KEY_F2] = 0,
[KEY_F3] = 0,
[KEY_F4] = 0,
[KEY_F5] = 0,
[KEY_F6] = 0,
[KEY_F7] = 0,
[KEY_F8] = 0,
[KEY_F9] = 0,
[KEY_F10] = 0,
[KEY_F11] = 0,
[KEY_F12] = 0,
[KEY_PRINT_SCREEN] = 0,
[KEY_SCROLL_LOCK] = 0,
[KEY_PAUSE] = 0,
[KEY_INSERT] = 0,
[KEY_HOME] = 0,
[KEY_PAGE_UP] = 0,
[KEY_DELETE] = 0,
[KEY_END] = 0,
[KEY_PAGE_DOWN] = 0,
[KEY_RIGHT] = 0,
[KEY_LEFT] = 0,
[KEY_DOWN] = 0,
[KEY_UP] = 0,
[KEY_NUM_LOCK] = 0,
[KEY_KEYPAD_SLASH] = '/',
[KEY_KEYPAD_ASTERISK] = '*',
[KEY_KEYPAD_MINUS] = '-',
[KEY_KEYPAD_PLUS] = '+',
[KEY_KEYPAD_ENTER] = '\n',
[KEY_KEYPAD_1] = '1',
[KEY_KEYPAD_2] = '2',
[KEY_KEYPAD_3] = '3',
[KEY_KEYPAD_4] = '4',
[KEY_KEYPAD_5] = '5',
[KEY_KEYPAD_6] = '6',
[KEY_KEYPAD_7] = '7',
[KEY_KEYPAD_8] = '8',
[KEY_KEYPAD_9] = '9',
[KEY_KEYPAD_0] = '0',
[KEY_KEYPAD_DOT] = '.',
[KEY_NON_US_BACKSLASH] = 0,
[KEY_KEYPAD_EQUALS] = '=',
[KEY_MENU] = 0,
[KEY_LEFT_CTRL] = 0,
[KEY_LEFT_SHIFT] = 0,
[KEY_LEFT_ALT] = 0,
[KEY_LEFT_META] = 0,
[KEY_RIGHT_CTRL] = 0,
[KEY_RIGHT_SHIFT] = 0,
[KEY_RIGHT_ALT] = 0,
[KEY_RIGHT_META] = 0,
[KEY_MEDIA_MUTE] = 0,
[KEY_MEDIA_VOLUME_INCREMENT] = 0,
[KEY_MEDIA_VOLUME_DECREMENT] = 0,
};
static char keycode_chars_shift[] = {
[KEY_UNKNOWN] = ' ',
[KEY_A] = 'A',
[KEY_B] = 'B',
[KEY_C] = 'C',
[KEY_D] = 'D',
[KEY_E] = 'E',
[KEY_F] = 'F',
[KEY_G] = 'G',
[KEY_H] = 'H',
[KEY_I] = 'I',
[KEY_J] = 'J',
[KEY_K] = 'K',
[KEY_L] = 'L',
[KEY_M] = 'M',
[KEY_N] = 'N',
[KEY_O] = 'O',
[KEY_P] = 'P',
[KEY_Q] = 'Q',
[KEY_R] = 'R',
[KEY_S] = 'S',
[KEY_T] = 'T',
[KEY_U] = 'U',
[KEY_V] = 'V',
[KEY_W] = 'W',
[KEY_X] = 'X',
[KEY_Y] = 'Y',
[KEY_Z] = 'Z',
[KEY_KEY_1] = '!',
[KEY_KEY_2] = '"',
[KEY_KEY_3] = 0,
[KEY_KEY_4] = '$',
[KEY_KEY_5] = '%',
[KEY_KEY_6] = '^',
[KEY_KEY_7] = '&',
[KEY_KEY_8] = '*',
[KEY_KEY_9] = '(',
[KEY_KEY_0] = ')',
[KEY_ENTER] = '\n',
[KEY_ESCAPE] = 0,
[KEY_BACKSPACE] = '\b',
[KEY_TAB] = ' ',
[KEY_SPACE] = ' ',
[KEY_MINUS] = '_',
[KEY_EQUALS] = '+',
[KEY_LEFT_BRACE] = '{',
[KEY_RIGHT_BRACE] = '}',
[KEY_BACKSLASH] = '|',
[KEY_NON_US_HASH] = 0,
[KEY_SEMICOLON] = ':',
[KEY_APOSTROPHE] = '@',
[KEY_GRAVE_ACCENT] = 0,
[KEY_COMMA] = '<',
[KEY_DOT] = '>',
[KEY_SLASH] = '?',
[KEY_CAPS_LOCK] = 0,
[KEY_F1] = 0,
[KEY_F2] = 0,
[KEY_F3] = 0,
[KEY_F4] = 0,
[KEY_F5] = 0,
[KEY_F6] = 0,
[KEY_F7] = 0,
[KEY_F8] = 0,
[KEY_F9] = 0,
[KEY_F10] = 0,
[KEY_F11] = 0,
[KEY_F12] = 0,
[KEY_PRINT_SCREEN] = 0,
[KEY_SCROLL_LOCK] = 0,
[KEY_PAUSE] = 0,
[KEY_INSERT] = 0,
[KEY_HOME] = 0,
[KEY_PAGE_UP] = 0,
[KEY_DELETE] = 0,
[KEY_END] = 0,
[KEY_PAGE_DOWN] = 0,
[KEY_RIGHT] = 0,
[KEY_LEFT] = 0,
[KEY_DOWN] = 0,
[KEY_UP] = 0,
[KEY_NUM_LOCK] = 0,
[KEY_KEYPAD_SLASH] = '/',
[KEY_KEYPAD_ASTERISK] = '*',
[KEY_KEYPAD_MINUS] = '-',
[KEY_KEYPAD_PLUS] = '+',
[KEY_KEYPAD_ENTER] = '\n',
[KEY_KEYPAD_1] = '1',
[KEY_KEYPAD_2] = '2',
[KEY_KEYPAD_3] = '3',
[KEY_KEYPAD_4] = '4',
[KEY_KEYPAD_5] = '5',
[KEY_KEYPAD_6] = '6',
[KEY_KEYPAD_7] = '7',
[KEY_KEYPAD_8] = '8',
[KEY_KEYPAD_9] = '9',
[KEY_KEYPAD_0] = '0',
[KEY_KEYPAD_DOT] = '.',
[KEY_NON_US_BACKSLASH] = 0,
[KEY_KEYPAD_EQUALS] = '=',
[KEY_MENU] = 0,
[KEY_LEFT_CTRL] = 0,
[KEY_LEFT_SHIFT] = 0,
[KEY_LEFT_ALT] = 0,
[KEY_LEFT_META] = 0,
[KEY_RIGHT_CTRL] = 0,
[KEY_RIGHT_SHIFT] = 0,
[KEY_RIGHT_ALT] = 0,
[KEY_RIGHT_META] = 0,
[KEY_MEDIA_MUTE] = 0,
[KEY_MEDIA_VOLUME_INCREMENT] = 0,
[KEY_MEDIA_VOLUME_DECREMENT] = 0,
};
static struct tty_ldisc default_ldisc = {
.name = "n_tty",
.read = default_ldisc_read,
.write = default_ldisc_write,
};
static enum tty_modifier_key get_modifier_key(const struct input_event *ev)
{
switch (ev->ev_key.key) {
case KEY_LEFT_CTRL:
case KEY_RIGHT_CTRL:
return TTY_KEY_CTRL;
case KEY_LEFT_ALT:
case KEY_RIGHT_ALT:
return TTY_KEY_ALT;
case KEY_LEFT_SHIFT:
case KEY_RIGHT_SHIFT:
return TTY_KEY_SHIFT;
default:
return TTY_KEY_OTHER;
}
}
static bool is_arrow_key(const struct input_event *ev, char *ch)
{
bool ret = false;
switch (ev->ev_key.key) {
case KEY_UP:
ret = true;
*ch = 'A';
break;
case KEY_DOWN:
ret = true;
*ch = 'B';
break;
case KEY_RIGHT:
ret = true;
*ch = 'C';
break;
case KEY_LEFT:
ret = true;
*ch = 'D';
break;
default:
ret = false;
break;
}
return ret;
}
static void handle_modifier_keys(struct device *tty, enum tty_modifier_key modkey, const struct input_event *ev)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
if (ev->ev_key.state == INPUT_KEYSTATE_DOWN) {
ttydev->tty_modstate |= modkey;
} else {
ttydev->tty_modstate &= ~modkey;
}
}
static void convert_ev_to_chars(struct device *tty, const struct input_event *ev)
{
if (ev->ev_key.state == INPUT_KEYSTATE_UP) {
return;
}
struct tty_device *ttydev = TTY_DEVICE(tty);
char echo[4];
int echo_len = 0;
char data[4];
int data_len = 0;
char c = keycode_chars[ev->ev_key.key];
if (ttydev->tty_modstate & TTY_KEY_CTRL) {
if (!isalpha(c)) {
return;
}
echo[0] = '^';
echo[1] = toupper(c);
echo_len = 2;
c = tolower(c);
c -= 97;
c++;
data[0] = c;
data_len = 1;
} else if (ttydev->tty_modstate & TTY_KEY_SHIFT) {
c = keycode_chars_shift[ev->ev_key.key];
echo[0] = c;
echo_len = 1;
data[0] = c;
data_len = 1;
} else if (is_arrow_key(ev, &c)) {
echo[0] = '^';
echo[1] = '[';
echo[2] = '[';
echo[3] = c;
echo_len = 4;
data[0] = 0x1b;
data[1] = '[';
data[2] = c;
data_len = 3;
} else if (c != 0) {
echo[0] = c;
echo_len = 1;
data[0] = c;
data_len = 1;
}
if (data_len == 0) {
return;
}
ringbuffer_write(&ttydev->tty_input, data_len, data, S_NOBLOCK);
size_t nr_written;
tty_write(tty, echo, 0, echo_len, &nr_written, S_NOBLOCK);
}
static kern_status_t canonical_read(struct device *tty, void *buf, size_t max, size_t *nr_read, socks_flags_t flags)
{
//struct tty_device *ttydev = TTY_DEVICE(tty);
//struct termios backup = ttydev
//char *linebuf = ttydev->tty_linebuf;
//unsigned int pos = 0, len = 0;
return KERN_OK;
}
static kern_status_t non_canonical_read(struct device *tty, void *buf, size_t max, size_t *nr_read, socks_flags_t flags)
{
return KERN_OK;
}
static kern_status_t default_ldisc_read(struct device *tty, void *buf, size_t max, size_t *nr_read, socks_flags_t flags)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
if (ttydev->tty_config.c_lflag & ICANON) {
return canonical_read(tty, buf, max, nr_read, flags);
} else {
return non_canonical_read(tty, buf, max, nr_read, flags);
}
return KERN_OK;
}
static void default_ldisc_write(struct device *tty, const struct input_event *ev)
{
enum tty_modifier_key modkeys = get_modifier_key(ev);
if (modkeys != TTY_KEY_OTHER) {
handle_modifier_keys(tty, modkeys, ev);
} else {
convert_ev_to_chars(tty, ev);
}
}
struct tty_ldisc *tty_default_line_discipline(void)
{
return &default_ldisc;
}

View File

@@ -1,110 +0,0 @@
#include <socks/tty.h>
#include <socks/input.h>
#include <socks/printk.h>
static void newline(struct device *tty)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
struct tty_driver_ops *ops = tty_driver->tty_ops;
ttydev->tty_xcur = 0;
ttydev->tty_ycur++;
if (ttydev->tty_ycur >= ttydev->tty_ycells) {
ttydev->tty_xcur = 0;
ttydev->tty_ycur = ttydev->tty_ycells - 1;
if (ops->tty_scroll) {
ops->tty_scroll(tty, TTY_SCROLL_DOWN, 1);
}
}
ops->tty_move_cursor(tty, ttydev->tty_xcur, ttydev->tty_ycur);
}
static void __putchar(struct device *tty, int c)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
struct tty_driver_ops *ops = tty_driver->tty_ops;
ops->tty_putc(tty, c, ttydev->tty_xcur, ttydev->tty_ycur, ttydev->tty_curattrib);
ttydev->tty_xcur++;
if (ttydev->tty_xcur >= ttydev->tty_xcells) {
ttydev->tty_xcur = 0;
ttydev->tty_ycur++;
}
if (ttydev->tty_ycur >= ttydev->tty_ycells) {
ttydev->tty_xcur = 0;
ttydev->tty_ycur = ttydev->tty_ycells - 1;
if (ops->tty_scroll) {
ops->tty_scroll(tty, TTY_SCROLL_DOWN, 1);
}
}
ops->tty_move_cursor(tty, ttydev->tty_xcur, ttydev->tty_ycur);
}
static void putchar(struct device *tty, int c)
{
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
struct tty_driver_ops *ops = tty_driver->tty_ops;
if (!ops->tty_putc) {
return;
}
if (tty_driver->tty_type == TTY_DRIVER_SIMPLE) {
ops->tty_putc(tty, c, -1, -1, 0);
return;
}
switch (c) {
case '\n':
newline(tty);
break;
default:
__putchar(tty, c);
break;
}
}
kern_status_t tty_read(struct device *tty, void *buf, size_t offset, size_t max, size_t *nr_read, socks_flags_t flags)
{
kern_status_t status = KERN_UNSUPPORTED;
struct tty_device *ttydev = TTY_DEVICE(tty);
if (ttydev->tty_ldisc || ttydev->tty_ldisc->read) {
status = ttydev->tty_ldisc->read(tty, buf, max, nr_read, flags);
}
return status;
}
kern_status_t tty_write(struct device *tty, const void *buf, size_t offset, size_t len, size_t *nr_written, socks_flags_t flags)
{
size_t r = 0;
const char *s = buf;
for (size_t i = 0; i < len; i++) {
putchar(tty, s[i]);
r++;
}
*nr_written = r;
return KERN_OK;
}
kern_status_t tty_report_event(struct device *tty, const struct input_event *ev)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
if (ttydev->tty_ldisc || ttydev->tty_ldisc->write) {
ttydev->tty_ldisc->write(tty, ev);
}
return KERN_OK;
}