From ce81d4eb31577446527811678dfc3fd042fb787f Mon Sep 17 00:00:00 2001 From: slinky55 Date: Tue, 30 Jun 2026 00:03:21 -0500 Subject: [PATCH] loading initrd now... --- initrd/make_img.sh | 5 +++ kernel/drivers/cpio/cpio.c | 92 ++++++++++++++++++++++++++++++++++++++ kernel/drivers/cpio/cpio.h | 25 +++++++++++ kernel/kmain.c | 37 +++++++++++---- kernel/lib/memory.c | 8 ++++ kernel/lib/memory.h | 1 + kernel/vfs.c | 73 ++++++++++++++++++++++++++++-- kernel/vfs.h | 23 +++++++--- 8 files changed, 247 insertions(+), 17 deletions(-) create mode 100755 initrd/make_img.sh create mode 100644 kernel/drivers/cpio/cpio.c create mode 100644 kernel/drivers/cpio/cpio.h diff --git a/initrd/make_img.sh b/initrd/make_img.sh new file mode 100755 index 0000000..444456d --- /dev/null +++ b/initrd/make_img.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +mkdir -p output +rm -rf output/* +find . -depth -print | cpio -o -H newc > output/initrd.img \ No newline at end of file diff --git a/kernel/drivers/cpio/cpio.c b/kernel/drivers/cpio/cpio.c new file mode 100644 index 0000000..da39cd9 --- /dev/null +++ b/kernel/drivers/cpio/cpio.c @@ -0,0 +1,92 @@ +#include + +#include + +#define MAX_INITRD_FILES 64 +static vfs_node_t cpio_nodes[MAX_INITRD_FILES]; +static uint32_t cpio_node_count = 0; + +static uint32_t parse_hex_ascii(const char *str, int len) { + uint32_t result = 0; + for (int i = 0; i < len; i++) { + result <<= 4; + if (str[i] >= '0' && str[i] <= '9') result |= (str[i] - '0'); + else if (str[i] >= 'A' && str[i] <= 'F') result |= (str[i] - 'A' + 10); + else if (str[i] >= 'a' && str[i] <= 'f') result |= (str[i] - 'a' + 10); + } + return result; +} + +static vfs_node_t* cpio_find(vfs_node_t* _dir, const char* name) { + if (!(_dir->flags & VFS_DIRECTORY)) return NULL; + + for (uint32_t i = 0; i < cpio_node_count; i++) { + if (strcmp(cpio_nodes[i].name, name) == 0) { + return &cpio_nodes[i]; + } + } + + return NULL; // File not found +} + +static uint32_t cpio_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer) { + if (offset >= node->size) return 0; + if (offset + size > node->size) { + size = node->size - offset; + } + memcpy(buffer, (uint8_t*)(node->ptr) + offset, size); + return size; +} + +vfs_node_t* cpio_read_fs(uint32_t _vaddr) { + cpio_header_t* header = (cpio_header_t*)_vaddr; + + vfs_node_t* cpio_root = kalloc(sizeof(vfs_node_t)); + memset((uint8_t*)cpio_root, 0, sizeof(vfs_node_t)); + + strcpy(cpio_root->name, "cpio_root"); + + cpio_root->flags |= VFS_DIRECTORY; + cpio_root->finddir = cpio_find; + + uint32_t cnt = 0; + while (1) { + if (strncmp(header->c_magic, "070701", 6) != 0 && + strncmp(header->c_magic, "070702", 6) != 0) { + break; + } + + uint32_t namesize = parse_hex_ascii(header->c_namesize, 8); + uint32_t filesize = parse_hex_ascii(header->c_filesize, 8); + uint32_t mode = parse_hex_ascii(header->c_mode, 8); + + char* filename = (char*)header + sizeof(cpio_header_t); + + if (strcmp(filename, "TRAILER!!!") == 0) { + break; + } + + uint32_t file_data_offset = sizeof(cpio_header_t) + namesize; + file_data_offset = (file_data_offset + 3) & ~3; // align to 4 bytes + + uint8_t* file_data = (uint8_t*)header + file_data_offset; + + if (strcmp(".", filename) != 0 && cnt < MAX_INITRD_FILES) { + vfs_node_t* current = &cpio_nodes[cpio_node_count++]; + memset((uint8_t*)current, 0, sizeof(vfs_node_t)); + + strcpy(current->name, filename); + current->size = filesize; + + current->flags = VFS_FILE; + current->read = cpio_read; + current->ptr = (vfs_node_t*)file_data; + } + + uint32_t next_header_offset = file_data_offset + filesize; + next_header_offset = (next_header_offset + 3) & ~3; + header = (cpio_header_t*)((uint8_t*)header + next_header_offset); + } + + return cpio_root; +} \ No newline at end of file diff --git a/kernel/drivers/cpio/cpio.h b/kernel/drivers/cpio/cpio.h new file mode 100644 index 0000000..c9797a0 --- /dev/null +++ b/kernel/drivers/cpio/cpio.h @@ -0,0 +1,25 @@ +#ifndef D_CPIO_H +#define D_CPIO_H + +#include + +typedef struct { + char c_magic[6]; // "070701" or "070702" + char c_ino[8]; + char c_mode[8]; // File type & permissions + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; // File size in hex ASCII + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; // Length of filename in hex ASCII + char c_check[8]; +} __attribute__((packed)) cpio_header_t; + +vfs_node_t* cpio_read_fs(uint32_t _vaddr); + +#endif \ No newline at end of file diff --git a/kernel/kmain.c b/kernel/kmain.c index 141ee3b..f0c43b4 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -3,7 +3,7 @@ #include "gdt.h" #include "scheduler.h" #include "common.h" -#include "initrd.h" +#include "vfs.h" #include #include @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -44,12 +45,32 @@ void parse_multiboot_modules(uint32_t mbi_vaddr) { } } -void load_initrd() { +vfs_node_t* load_initrd() { multiboot_module_t* initrd_module = &multiboot_module_info_table[0]; kprintf("initrd found @ [v] 0x%x\n", initrd_module->mod_start); - kprintf("reading initrd\n"); + return cpio_read_fs(initrd_module->mod_start); +} - parse_cpio((void*)initrd_module->mod_start); +void load_origin_program() { + vfs_node_t* vfs_root = vfs_create_root(); + vfs_node_t* initrd_root = load_initrd(); + + if (initrd_root) { + mount(vfs_root, initrd_root); + kprintf("initrd read, mounted @ /\n"); + + int fd = open("/origin.elf", 0); + if (fd == -1) { + kprintf("failed to read origin program\n"); + } + + void* buf = kalloc(512); + int rd = read(fd, buf, 512); + if (rd > 0) { + kprintf("read %d bytes from origin.elf\n", rd); + } + } + exit(); } void kmain(uint32_t magic, multiboot_info* mbi) { @@ -72,12 +93,12 @@ void kmain(uint32_t magic, multiboot_info* mbi) { init_page_tables(); parse_multiboot_modules((uint32_t)mbi); - - load_initrd(); - + kprintf("basic initializations complete\n"); - disable_interrupts(); // just paranoid... do it again + disable_interrupts(); init_scheduler(); enable_interrupts(); + + create_task((uint32_t)load_origin_program, fetch_cr3()); } diff --git a/kernel/lib/memory.c b/kernel/lib/memory.c index 616879a..6fa9533 100644 --- a/kernel/lib/memory.c +++ b/kernel/lib/memory.c @@ -58,6 +58,14 @@ int strncmp(const char *s1, const char *s2, size_t n) { return 0; } +char* strcpy(char* dest, const char* src) { + char* saved_dest = dest; + + while ((*dest++ = *src++) != '\0') {} + + return saved_dest; +} + static void* kernel_heap_start = (void*)KHEAP_START; static void* kernel_heap_end = (void*)KHEAP_START; alloc_header_t* blk_list = NULL; diff --git a/kernel/lib/memory.h b/kernel/lib/memory.h index 179f52b..a8470fc 100644 --- a/kernel/lib/memory.h +++ b/kernel/lib/memory.h @@ -10,6 +10,7 @@ void memset(const uint8_t* dst, uint8_t val, size_t sz); int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); int strlen(const char* str); +char* strcpy(char* dest, const char* src); void kgrow(size_t pages); void* kalloc(size_t sz); diff --git a/kernel/vfs.c b/kernel/vfs.c index a604db5..4fa7d37 100644 --- a/kernel/vfs.c +++ b/kernel/vfs.c @@ -1,12 +1,77 @@ #include "vfs.h" + #include "lib/memory.h" -#include + +#define MAX_PROCESS_FDS 32 +file_t fd_table[MAX_PROCESS_FDS]; vfs_node_t* root = NULL; -void vfs_create_root() { +vfs_node_t* vfs_create_root() { root = kalloc(sizeof(vfs_node_t)); - memset((uint8_t*)root->name, 0, 128); - memcpy("root", root->name, 4); + memset((uint8_t*)root, 0, sizeof(vfs_node_t)); + + strcpy(root->name, "root"); + root->flags |= VFS_DIRECTORY; + root->size = 0; + root->finddir = NULL; + + return root; +} + +void mount(vfs_node_t* _mnt, vfs_node_t* _fs) { + if (!_fs || !_mnt || !(_mnt->flags & VFS_DIRECTORY)) return; + _mnt->ptr = _fs; +} + +static vfs_node_t* lookup(const char* path) { + if (path[0] != '/') return NULL; + vfs_node_t* current = root; + + if (current->ptr) { + current = current->ptr; + } + + const char* component = path + 1; + if (*component == '\0') return current; + + if (current->finddir) { + return current->finddir(current, component); + } + + return NULL; +} + +int open(const char* _path, int flags) { + vfs_node_t* file = lookup(_path); + if (!file) return -1; + for (int i = 0; i < MAX_PROCESS_FDS; i++) { + if (fd_table[i].node == NULL) { + fd_table[i].node = file; + fd_table[i].offset = 0; + fd_table[i].flags = flags; + return i; + } + } + return -1; +} + +int read(int fd, void* buf, size_t sz) { + if (fd < 0 || fd >= MAX_PROCESS_FDS || !fd_table[fd].node) { + return -1; + } + + file_t* file = &fd_table[fd]; + + if (!file->node->read) return -1; + + uint32_t bytes_read = file->node->read(file->node, file->offset, sz, buf); + file->offset += bytes_read; + + return bytes_read; +} + +int fseek(int fd) { + } \ No newline at end of file diff --git a/kernel/vfs.h b/kernel/vfs.h index b5f475d..d9059e1 100644 --- a/kernel/vfs.h +++ b/kernel/vfs.h @@ -2,9 +2,13 @@ #define KVFS_H #include +#include -#define VFS_FILE 0x01 -#define VFS_DIRECTORY 0x02 +#define VFS_FILE 0x01 +#define VFS_DIRECTORY 0x02 +#define VFS_CHARDEVICE 0x03 +#define VFS_BLOCKDEVICE 0x04 +#define VFS_PIPE 0x05 struct vfs_node; @@ -16,15 +20,24 @@ typedef struct vfs_node { char name[128]; uint32_t flags; // File, directory, device, etc. uint32_t size; // Size of file in bytes - uint32_t inode; // Unique identifier managed by the specific filesystem read_type_t read; write_type_t write; finddir_type_t finddir; - struct vfs_node* mount; + struct vfs_node* ptr; } vfs_node_t; -void vfs_create_root(); +typedef struct { + vfs_node_t* node; // The actual CPIO/VFS node + uint32_t offset; // Current read/write cursor position + uint32_t flags; // Permissions (O_RDONLY, etc.) +} file_t; + +vfs_node_t* vfs_create_root(); + +void mount(vfs_node_t* _mnt, vfs_node_t* _fs); +int open(const char* path, int flags); +int read(int fd, void* buf, size_t sz); #endif \ No newline at end of file