loading initrd now...

This commit is contained in:
2026-06-30 00:03:21 -05:00
parent 5983212da0
commit ce81d4eb31
8 changed files with 247 additions and 17 deletions

5
initrd/make_img.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
mkdir -p output
rm -rf output/*
find . -depth -print | cpio -o -H newc > output/initrd.img

View File

@@ -0,0 +1,92 @@
#include <drivers/cpio/cpio.h>
#include <lib/memory.h>
#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;
}

View File

@@ -0,0 +1,25 @@
#ifndef D_CPIO_H
#define D_CPIO_H
#include <vfs.h>
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

View File

@@ -3,7 +3,7 @@
#include "gdt.h"
#include "scheduler.h"
#include "common.h"
#include "initrd.h"
#include "vfs.h"
#include <lib/print.h>
#include <lib/stream.h>
@@ -17,6 +17,7 @@
#include <drivers/ps2/ps2.h>
#include <drivers/pit/pit.h>
#include <drivers/vga/vga.h>
#include <drivers/cpio/cpio.h>
#include <stddef.h>
#include <stdint.h>
@@ -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());
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -1,12 +1,77 @@
#include "vfs.h"
#include "lib/memory.h"
#include <string.h>
#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) {
}

View File

@@ -2,9 +2,13 @@
#define KVFS_H
#include <stdint.h>
#include <stddef.h>
#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