loading initrd now...
This commit is contained in:
5
initrd/make_img.sh
Executable file
5
initrd/make_img.sh
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mkdir -p output
|
||||||
|
rm -rf output/*
|
||||||
|
find . -depth -print | cpio -o -H newc > output/initrd.img
|
||||||
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 "gdt.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "initrd.h"
|
#include "vfs.h"
|
||||||
|
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <drivers/ps2/ps2.h>
|
#include <drivers/ps2/ps2.h>
|
||||||
#include <drivers/pit/pit.h>
|
#include <drivers/pit/pit.h>
|
||||||
#include <drivers/vga/vga.h>
|
#include <drivers/vga/vga.h>
|
||||||
|
#include <drivers/cpio/cpio.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.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];
|
multiboot_module_t* initrd_module = &multiboot_module_info_table[0];
|
||||||
kprintf("initrd found @ [v] 0x%x\n", initrd_module->mod_start);
|
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) {
|
void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||||
@@ -72,12 +93,12 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
init_page_tables();
|
init_page_tables();
|
||||||
|
|
||||||
parse_multiboot_modules((uint32_t)mbi);
|
parse_multiboot_modules((uint32_t)mbi);
|
||||||
|
|
||||||
load_initrd();
|
|
||||||
|
|
||||||
kprintf("basic initializations complete\n");
|
kprintf("basic initializations complete\n");
|
||||||
|
|
||||||
disable_interrupts(); // just paranoid... do it again
|
disable_interrupts();
|
||||||
init_scheduler();
|
init_scheduler();
|
||||||
enable_interrupts();
|
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;
|
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_start = (void*)KHEAP_START;
|
||||||
static void* kernel_heap_end = (void*)KHEAP_START;
|
static void* kernel_heap_end = (void*)KHEAP_START;
|
||||||
alloc_header_t* blk_list = NULL;
|
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 strcmp(const char *s1, const char *s2);
|
||||||
int strncmp(const char *s1, const char *s2, size_t n);
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
int strlen(const char* str);
|
int strlen(const char* str);
|
||||||
|
char* strcpy(char* dest, const char* src);
|
||||||
|
|
||||||
void kgrow(size_t pages);
|
void kgrow(size_t pages);
|
||||||
void* kalloc(size_t sz);
|
void* kalloc(size_t sz);
|
||||||
|
|||||||
73
kernel/vfs.c
73
kernel/vfs.c
@@ -1,12 +1,77 @@
|
|||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
|
|
||||||
#include "lib/memory.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;
|
vfs_node_t* root = NULL;
|
||||||
|
|
||||||
void vfs_create_root() {
|
vfs_node_t* vfs_create_root() {
|
||||||
root = kalloc(sizeof(vfs_node_t));
|
root = kalloc(sizeof(vfs_node_t));
|
||||||
memset((uint8_t*)root->name, 0, 128);
|
memset((uint8_t*)root, 0, sizeof(vfs_node_t));
|
||||||
memcpy("root", root->name, 4);
|
|
||||||
|
strcpy(root->name, "root");
|
||||||
|
|
||||||
root->flags |= VFS_DIRECTORY;
|
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
|
#define KVFS_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#define VFS_FILE 0x01
|
#define VFS_FILE 0x01
|
||||||
#define VFS_DIRECTORY 0x02
|
#define VFS_DIRECTORY 0x02
|
||||||
|
#define VFS_CHARDEVICE 0x03
|
||||||
|
#define VFS_BLOCKDEVICE 0x04
|
||||||
|
#define VFS_PIPE 0x05
|
||||||
|
|
||||||
struct vfs_node;
|
struct vfs_node;
|
||||||
|
|
||||||
@@ -16,15 +20,24 @@ typedef struct vfs_node {
|
|||||||
char name[128];
|
char name[128];
|
||||||
uint32_t flags; // File, directory, device, etc.
|
uint32_t flags; // File, directory, device, etc.
|
||||||
uint32_t size; // Size of file in bytes
|
uint32_t size; // Size of file in bytes
|
||||||
uint32_t inode; // Unique identifier managed by the specific filesystem
|
|
||||||
|
|
||||||
read_type_t read;
|
read_type_t read;
|
||||||
write_type_t write;
|
write_type_t write;
|
||||||
finddir_type_t finddir;
|
finddir_type_t finddir;
|
||||||
|
|
||||||
struct vfs_node* mount;
|
struct vfs_node* ptr;
|
||||||
} vfs_node_t;
|
} 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
|
#endif
|
||||||
Reference in New Issue
Block a user