From 7f737e6f02609fd1df598ca02033dba2c7b10423 Mon Sep 17 00:00:00 2001 From: ice-bit Date: Sat, 14 Sep 2019 12:33:51 +0200 Subject: [PATCH] Added ordered_list driver and some parts of init ram disk --- kernel/drivers/initrd.c | 56 ++++++++++++++++++++++++++++ kernel/drivers/initrd.h | 29 +++++++++++++++ kernel/drivers/ordered_list.c | 69 +++++++++++++++++++++++++++++++++++ kernel/drivers/ordered_list.h | 34 +++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 kernel/drivers/initrd.c create mode 100644 kernel/drivers/initrd.h create mode 100644 kernel/drivers/ordered_list.c create mode 100644 kernel/drivers/ordered_list.h diff --git a/kernel/drivers/initrd.c b/kernel/drivers/initrd.c new file mode 100644 index 0000000..c168398 --- /dev/null +++ b/kernel/drivers/initrd.c @@ -0,0 +1,56 @@ +#include "initrd.h" + +// Declare various things +initrd_header_t *initrd_header; // Header +initrd_file_header_t *file_header; // List of headers +fs_node_t *initrd_root; // Directory root node +fs_node_t *initrd_dev; // Directory dev node(/dev) +fs_node_t *root_nodes; // List of file nodes +uint32_t nroot_nodes; + +struct dirent dirent; + +fs_node_t *init_ramdisk(uint32_t multiboot_location) { + // Initialize main and file headers + initrd_header = (initrd_header_t*)multiboot_location; + file_header = (initrd_file_header_t*)(multiboot_location+sizeof(initrd_header_t)); + // Initialize root directory + initrd_root = (fs_node_t*) + +} + +static uint32_t initrd_read(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { + initrd_file_header_t header = file_header[node->inode]; + if(offset > header.length) + return 0; + if(offset+size > header.length) + size = header.length-offset; + memcpy(buffer, (uint8_t*) (header.offset+offset), size); + return size; +} + +static struct dirent *initrd_readdir(fs_node_t *node, uint32_t index) { + if(node == initrd_root && index == 0) { + strcpy(dirent.name, "dev"); + dirent.name[3] = 0; // Add null terminator to the string + dirent.ino = 0; + return &dirent; + } + + if(index-1 >= &root_nodes) + return 0; + strcpy(dirent.name, root_nodes[index-1].name); + dirent.name[strlen(root_nodes[index-1].name)] = 0; // Add null terminator + dirent.ino = root_nodes[index-1].inode; + return &dirent; +} + +static fs_node_t *initrd_finddir(fs_node_t *node, uint8_t *name) { + if(node == initrd_root && !strcmp(name, "dev")) + return initrd_dev; + + for(uint32_t i = 0; i < nroot_nodes; i++) + if(!strcmp(name, root_nodes[i].name)) + return &root_nodes[i]; + return 0; +} \ No newline at end of file diff --git a/kernel/drivers/initrd.h b/kernel/drivers/initrd.h new file mode 100644 index 0000000..dafc785 --- /dev/null +++ b/kernel/drivers/initrd.h @@ -0,0 +1,29 @@ +#ifndef INITRD_H +#define INITRD_H +/* Ramdisk is a file system that is loaded along with the kernel + * and it usually contains configuration files or file system drivers. + * It is used BEFORE partitions are being mounted*/ + +#include +#include "../libc/string.h" +#include "fs.h" + +typedef struct { + uint32_t nfiles; // Number of files in the ramdisk +} initrd_header_t; + +typedef struct { + uint8_t magic; // Magic number for error checking + int8_t name[64]; // Filename + uint32_t offset; + uint32_t length; // Length of the file +} initrd_file_header_t; + +// Function to initialize initrd, we'll pass the multiboot +// module as parameter +fs_node_t *init_ramdisk(uint32_t multiboot_location); +static uint32_t initrd_read(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer); +static struct dirent *initrd_readdir(fs_node_t *node, uint32_t index); +static fs_node_t *initrd_finddir(fs_node_t *node, uint8_t *name); + +#endif \ No newline at end of file diff --git a/kernel/drivers/ordered_list.c b/kernel/drivers/ordered_list.c new file mode 100644 index 0000000..fdfc21f --- /dev/null +++ b/kernel/drivers/ordered_list.c @@ -0,0 +1,69 @@ +#include "ordered_list.h" + +uint8_t standard_lessthan_predicate(type_t a, type_t b) { + if(a < b) + return 1; + return 0; +} + +// Create an ordered list +ordered_list_t create_ordered_list(uint32_t max_size, lessthan_predicate_t less_than) { + ordered_list_t to_ret; + to_ret.array = (void*)kmalloc(max_size*sizeof(type_t)); + memset(to_ret.array, 0, max_size * sizeof(type_t)); + to_ret.size = 0; + to_ret.max_size = max_size; + to_ret.less_then = less_than; + return to_ret; +} + +ordered_list_t place_ordered_list(void *addr, uint32_t max_size, lessthan_predicate_t less_than) { + ordered_list_t to_ret; + to_ret.array = (type_t*)addr; + memset(to_ret.array, 0, max_size * sizeof(type_t)); + to_ret.size = 0; + to_ret.max_size = max_size; + to_ret.less_then = less_than; + return to_ret; +} + +// Destroy an ordered list +void destroy_ordered_list(ordered_list_t *array) { + // Not ready yet +} + +// Insert item into the array +void insert_ordered_list(type_t item, ordered_list_t *array) { + ASSERT(array->less_then); // TODO: implement assert + uint32_t iterator = 0; + while(iterator < array->size && array->less_then(array->array[iterator], item)) + iterator++; + if(iterator == array->size) + array->array[array->size++] = item; + else { + type_t tmp = array->array[iterator]; + array->array[iterator] = item; + while(iterator < array->size) { + iterator++; + type_t tmp2 = array->array[iterator]; + array->array[iterator] = tmp; + tmp = tmp2; + } + array->size++; + } +} + +// Find item at given index +type_t lookup_ordered_list(uint32_t i, ordered_list_t *array) { + ASSERT(i < array->size); + return array->array[i]; +} + +// Delete item from the array +void remove_ordered_list(uint32_t i, ordered_list_t *array) { + while(i < array->size) { + array->array[i] = array->array[i+1]; + i++; + } + array->size--; +} diff --git a/kernel/drivers/ordered_list.h b/kernel/drivers/ordered_list.h new file mode 100644 index 0000000..2b7668e --- /dev/null +++ b/kernel/drivers/ordered_list.h @@ -0,0 +1,34 @@ +#ifndef ORDERED_LIST +#define ORDERED_LIST + +#include +#include "../libc/string.h" + +/* Our list is always in a 'sorted state', + * it can store anything that can be casted + * to void* */ +typedef void* type_t; +/* The following predicate should return non-zero + * if the first argument is less than the second */ +typedef int8_t (*lessthan_predicate_t)(type_t, type_t); +typedef struct { + type_t *array; + uint32_t size; + uint32_t max_size; + lessthan_predicate_t less_then; +} ordered_list_t; +uint8_t standard_lessthan_predicate(type_t a, type_t b); + +// Create an ordered list +ordered_list_t create_ordered_list(uint32_t max_size, lessthan_predicate_t less_than); +ordered_list_t place_ordered_list(void *addr, uint32_t max_size, lessthan_predicate_t less_than); +// Destroy an ordered list +void destroy_ordered_list(ordered_list_t *array); +// Insert item into the array +void insert_ordered_list(type_t item, ordered_list_t *array); +// Find item at given index +type_t lookup_ordered_list(uint32_t i, ordered_list_t *array); +// Delete item from the array +void remove_ordered_list(uint32_t i, ordered_list_t *array); + +#endif \ No newline at end of file