loading initrd now...
This commit is contained in:
92
kernel/drivers/cpio/cpio.c
Normal file
92
kernel/drivers/cpio/cpio.c
Normal 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;
|
||||
}
|
||||
25
kernel/drivers/cpio/cpio.h
Normal file
25
kernel/drivers/cpio/cpio.h
Normal 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
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
73
kernel/vfs.c
73
kernel/vfs.c
@@ -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) {
|
||||
|
||||
}
|
||||
23
kernel/vfs.h
23
kernel/vfs.h
@@ -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
|
||||
Reference in New Issue
Block a user