diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2025-07-30 14:32:01 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2025-07-30 14:32:01 -0400 |
commit | b905869a35f062a4e5072f10bec3a2ba3db0e365 (patch) | |
tree | 0666691804878857b4bb07daca8a54f5ddb8ae0b /device | |
download | jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.tar.gz jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.tar.bz2 jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.zip |
working userland with some invoke syscalls
Diffstat (limited to 'device')
-rw-r--r-- | device/initrd.c | 116 | ||||
-rw-r--r-- | device/portio_uart.c | 68 | ||||
-rw-r--r-- | device/uart.c | 13 |
3 files changed, 197 insertions, 0 deletions
diff --git a/device/initrd.c b/device/initrd.c new file mode 100644 index 0000000..36eefc6 --- /dev/null +++ b/device/initrd.c @@ -0,0 +1,116 @@ +#if defined(ENABLE_INITRD) + +#include <stddef.h> + +#include "device/initrd.h" +#include "device/processor.h" +#include "object.h" +#include "jove.h" +#include "bootargs.h" +#include "print.h" +#include "string.h" +#include "panic.h" + +struct jove_ObjectDirectory s_initrd_dir = { + .entries = { + [0] = (objdir_entry_t){ + .type = KO_OBJECT_DIRECTORY, + .data = 1 + } + } +}; + +static uintptr_t s_initrd_getaddr(char *path); + +#if defined(__limine__) + +#include "boot/limine/limine.h" +static struct limine_module_request s_module_request = { + .id = LIMINE_MODULE_REQUEST +}; + +static uintptr_t +s_initrd_getaddr(char *path) +{ + struct limine_module_response *response = s_module_request.response; + for(size_t i = 0; i < response->module_count; i++) { + struct limine_file *module = response->modules[i]; + if(strcmp(path, module->path) == 0) + return (uintptr_t)module->address; + } + kpanic("Failed to load module at path %s\n", path); +} + + +#endif + +static size_t +s_tar_oct_dec(const char *oct) +{ + size_t r = 0; + for(; *oct; oct++) r = (r * 8) + (*oct - '0'); + return r; +} + +void +tar_parse(tar_block_t *block) +{ + while(true) { + tar_header_t *header = &block->header; + if(*header->name == 0) return; + if(s_initrd_dir.self.data == OBJECT_DIRECTORY_MAX_ENTRIES) { + klogf("More than %i files in initrd! Skipping the rest.\n", OBJECT_DIRECTORY_MAX_ENTRIES - 1); + } + + size_t file_size = s_tar_oct_dec(header->size); + s_initrd_dir.entries[s_initrd_dir.self.data++] = (objdir_entry_t) { + .type = KO_INITRD_FILE, + .data = (uintptr_t)block + }; + + klogf("Load file '%s' at %p size %x\n", block->header.name, block + 1, file_size); + + block = &block[(file_size / 512) + 1]; + if(file_size % 512) block++; + } +} + +void +initrd_setup(void) +{ + char *initrd_path = bootargs_getarg("initrd"); + if(initrd_path == 0) { + kpanic("Missing kernel commandline argument for initrd."); + } + + uintptr_t initrd_addr = s_initrd_getaddr(initrd_path); + klogf("Initrd found at %p\n", initrd_addr); + tar_parse((tar_block_t*)initrd_addr); + + size_t initrd_diri = _initDirectory.self.data++; + _initDirectory.entries[initrd_diri] = (objdir_entry_t) { + .type = KO_OBJECT_DIRECTORY, + .data = (uintptr_t)&s_initrd_dir + }; + //Add initrd dir to init object + ((init_data_t*)_initDirectory.entries[1].data)->initrd_dir = initrd_diri; +} + +int +initrd_file_size(tar_header_t *file) +{ + return s_tar_oct_dec(file->size); +} + +tar_header_t* +initrd_find_file(const char *filename) +{ + for(size_t i = 0; i < s_initrd_dir.self.data - 1; i++) { + objdir_entry_t *entry = &s_initrd_dir.entries[i+1]; + tar_header_t *file = (tar_header_t*)entry->data; + if(strcmp(file->name + 1, filename) == 0) return file; + } + return NULL; +} + +#endif diff --git a/device/portio_uart.c b/device/portio_uart.c new file mode 100644 index 0000000..00800b5 --- /dev/null +++ b/device/portio_uart.c @@ -0,0 +1,68 @@ +#ifdef ENABLE_PORTIO_UART +#include "jove.h" +#include "device/portio_uart.h" +#include "device/portio.h" + +static void +s_set_int(ioport_t dev, uint8_t enable) +{ + port_outb(PORTIO_UART_COM_IER(dev), enable); +} + +static void +s_set_baud(ioport_t dev, uint16_t baud) +{ + /* Enable DLAB */ + port_outb(PORTIO_UART_COM_LCR(dev), PORTIO_UART_COM_LCR(dev) | 0x80); + /* Write low & high. */ + port_outb(PORTIO_UART_COM_DLAB_DLL(dev), (uint8_t)(baud & 0xFF)); + port_outb(PORTIO_UART_COM_DLAB_DLH(dev), (uint8_t)((baud >> 8) & 0xFF)); + /* Disable DLAB */ + port_outb(PORTIO_UART_COM_LCR(dev), PORTIO_UART_COM_LCR(dev) & 0x7F); +} + +static void +s_set_fcr(ioport_t dev, uint8_t flg) +{ + port_outb(PORTIO_UART_COM_FCR(dev), flg); +} + +static void +s_set_lcr(ioport_t dev, uint8_t flg) +{ + port_outb(PORTIO_UART_COM_LCR(dev), flg); +} + +static void +s_set_mcr(ioport_t dev, uint8_t flg) +{ + port_outb(PORTIO_UART_COM_MCR(dev), flg); +} + +void +portio_uart_setup(void) +{ + s_set_int(PORTIO_UART_COM1, 0); + s_set_baud(PORTIO_UART_COM1, 3); + s_set_lcr(PORTIO_UART_COM1, 1 | 2); + s_set_fcr(PORTIO_UART_COM1, 1 | 2 | 4 | 0xC0); + s_set_fcr(PORTIO_UART_COM1, 1 | 2 | 8); + s_set_mcr(PORTIO_UART_COM1, 1 | 2 | 4 | 8); + + uint64_t serial_i = _initDirectory.self.data++; + _initDirectory.entries[serial_i] = (struct jove_ObjectDirectoryEntry) { + .type = KO_DEV_UART, + .data = PORTIO_UART_COM1 + }; + _initData.log_object = serial_i; +} + +void +portio_uart_write(uint64_t dev, const char *s, int n) +{ + for(int i = 0; i < n; i++) { + port_outb(dev, s[i]); + } +} + +#endif diff --git a/device/uart.c b/device/uart.c new file mode 100644 index 0000000..6728ab1 --- /dev/null +++ b/device/uart.c @@ -0,0 +1,13 @@ +#include "device/uart.h" +#include "device/portio_uart.h" + +void +uart_write(objdir_t *dir, uint64_t entryi, const char *s, size_t w) +{ + objdir_entry_t *entry = objdir_seek(dir, entryi); + if(entry == NULL || entry->type != KO_DEV_UART) return; + +#ifdef ENABLE_PORTIO_UART + portio_uart_write(entry->data, s, w); +#endif +} |