mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
202 lines
6.7 KiB
C
202 lines
6.7 KiB
C
#include <fs/ramfs.h>
|
|
#include <mm/kmalloc.h>
|
|
#include <lib/string.h>
|
|
|
|
#define MAX_CHILDREN 32
|
|
|
|
typedef struct ramfs_entry {
|
|
vfs_node_t node;
|
|
uint8_t* data;
|
|
size_t capacity;
|
|
struct ramfs_entry* children[MAX_CHILDREN];
|
|
uint32_t child_count;
|
|
} ramfs_entry_t;
|
|
|
|
static vfs_dirent_t shared_dirent;
|
|
|
|
static int ramfs_mkdir_impl(vfs_node_t* parent, const char* name, mode_t mode);
|
|
static int ramfs_create_impl(vfs_node_t* parent, const char* name, mode_t mode);
|
|
static struct vfs_dirent* ramfs_readdir(vfs_node_t* node, uint32_t index);
|
|
static struct vfs_node* ramfs_finddir(vfs_node_t* node, const char* name);
|
|
|
|
static ssize_t ramfs_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
|
|
ramfs_entry_t* entry = (ramfs_entry_t*)node;
|
|
if (!entry || !entry->data || (size_t)offset >= node->length) return 0;
|
|
|
|
if (offset + size > node->length) {
|
|
size = node->length - offset;
|
|
}
|
|
|
|
memcpy(buffer, entry->data + offset, size);
|
|
return (ssize_t)size;
|
|
}
|
|
|
|
static ssize_t ramfs_write(vfs_node_t* node, off_t offset, size_t size, const uint8_t* buffer) {
|
|
ramfs_entry_t* entry = (ramfs_entry_t*)node;
|
|
if (!entry) return -1;
|
|
|
|
if (offset + size > entry->capacity) {
|
|
size_t new_cap = (offset + size + 256) & ~255;
|
|
uint8_t* new_data = (uint8_t*)kmalloc(new_cap);
|
|
if (!new_data) return -1;
|
|
|
|
if (entry->data) {
|
|
memcpy(new_data, entry->data, node->length);
|
|
kfree(entry->data);
|
|
}
|
|
entry->data = new_data;
|
|
entry->capacity = new_cap;
|
|
}
|
|
|
|
memcpy(entry->data + offset, buffer, size);
|
|
if (offset + size > node->length) {
|
|
node->length = offset + size;
|
|
}
|
|
return (ssize_t)size;
|
|
}
|
|
|
|
static struct vfs_dirent* ramfs_readdir(vfs_node_t* node, uint32_t index) {
|
|
ramfs_entry_t* entry = (ramfs_entry_t*)node;
|
|
if (!entry || index >= entry->child_count) return NULL;
|
|
|
|
strncpy(shared_dirent.name, entry->children[index]->node.name, sizeof(shared_dirent.name) - 1);
|
|
shared_dirent.inode = entry->children[index]->node.inode;
|
|
shared_dirent.type = entry->children[index]->node.flags;
|
|
return &shared_dirent;
|
|
}
|
|
|
|
static struct vfs_node* ramfs_finddir(vfs_node_t* node, const char* name) {
|
|
ramfs_entry_t* entry = (ramfs_entry_t*)node;
|
|
if (!entry) return NULL;
|
|
|
|
for (uint32_t i = 0; i < entry->child_count; i++) {
|
|
if (strcmp(entry->children[i]->node.name, name) == 0) {
|
|
return &entry->children[i]->node;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static int ramfs_mkdir_impl(vfs_node_t* parent, const char* name, mode_t mode) {
|
|
ramfs_entry_t* p = (ramfs_entry_t*)parent;
|
|
if (!p || p->child_count >= MAX_CHILDREN) return -1;
|
|
|
|
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
|
|
if (!child) return -1;
|
|
|
|
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
|
|
child->node.flags = FS_DIRECTORY;
|
|
child->node.mode = mode;
|
|
child->node.readdir = ramfs_readdir;
|
|
child->node.finddir = ramfs_finddir;
|
|
child->node.mkdir = ramfs_mkdir_impl;
|
|
child->node.create = ramfs_create_impl;
|
|
|
|
p->children[p->child_count++] = child;
|
|
return 0;
|
|
}
|
|
|
|
static int ramfs_create_impl(vfs_node_t* parent, const char* name, mode_t mode) {
|
|
ramfs_entry_t* p = (ramfs_entry_t*)parent;
|
|
if (!p || p->child_count >= MAX_CHILDREN) return -1;
|
|
|
|
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
|
|
if (!child) return -1;
|
|
|
|
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
|
|
child->node.flags = FS_FILE;
|
|
child->node.mode = mode;
|
|
child->node.read = ramfs_read;
|
|
child->node.write = ramfs_write;
|
|
|
|
p->children[p->child_count++] = child;
|
|
return 0;
|
|
}
|
|
|
|
vfs_node_t* ramfs_add_file(vfs_node_t* parent, const char* name, const void* content, size_t size) {
|
|
ramfs_entry_t* p = (ramfs_entry_t*)parent;
|
|
if (!p || p->child_count >= MAX_CHILDREN) return NULL;
|
|
|
|
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
|
|
if (!child) return NULL;
|
|
|
|
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
|
|
child->node.flags = FS_FILE;
|
|
child->node.mode = 0644;
|
|
child->node.length = size;
|
|
child->node.read = ramfs_read;
|
|
child->node.write = ramfs_write;
|
|
|
|
if (size > 0 && content) {
|
|
child->capacity = size;
|
|
child->data = (uint8_t*)kmalloc(size);
|
|
if (child->data) {
|
|
memcpy(child->data, content, size);
|
|
}
|
|
}
|
|
|
|
p->children[p->child_count++] = child;
|
|
return &child->node;
|
|
}
|
|
|
|
vfs_node_t* ramfs_add_dir(vfs_node_t* parent, const char* name) {
|
|
ramfs_entry_t* child = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
|
|
if (!child) return NULL;
|
|
|
|
strncpy(child->node.name, name, sizeof(child->node.name) - 1);
|
|
child->node.flags = FS_DIRECTORY;
|
|
child->node.mode = 0755;
|
|
child->node.readdir = ramfs_readdir;
|
|
child->node.finddir = ramfs_finddir;
|
|
child->node.mkdir = ramfs_mkdir_impl;
|
|
child->node.create = ramfs_create_impl;
|
|
|
|
if (parent) {
|
|
ramfs_entry_t* p = (ramfs_entry_t*)parent;
|
|
if (p->child_count < MAX_CHILDREN) {
|
|
p->children[p->child_count++] = child;
|
|
}
|
|
}
|
|
|
|
return &child->node;
|
|
}
|
|
|
|
vfs_node_t* ramfs_create_root(void) {
|
|
ramfs_entry_t* root = (ramfs_entry_t*)kzalloc(sizeof(ramfs_entry_t));
|
|
if (!root) return NULL;
|
|
|
|
strcpy(root->node.name, "/");
|
|
root->node.flags = FS_DIRECTORY;
|
|
root->node.mode = 0755;
|
|
root->node.readdir = ramfs_readdir;
|
|
root->node.finddir = ramfs_finddir;
|
|
root->node.mkdir = ramfs_mkdir_impl;
|
|
root->node.create = ramfs_create_impl;
|
|
|
|
vfs_node_t* etc = ramfs_add_dir(&root->node, "etc");
|
|
ramfs_add_dir(&root->node, "bin");
|
|
ramfs_add_dir(&root->node, "dev");
|
|
ramfs_add_dir(&root->node, "proc");
|
|
ramfs_add_dir(&root->node, "sys");
|
|
ramfs_add_dir(&root->node, "home");
|
|
ramfs_add_dir(&root->node, "tmp");
|
|
vfs_node_t* mnt = ramfs_add_dir(&root->node, "mnt");
|
|
if (mnt) {
|
|
ramfs_add_dir(mnt, "fat32");
|
|
ramfs_add_dir(mnt, "ramdisk");
|
|
ramfs_add_dir(mnt, "nvme");
|
|
}
|
|
|
|
if (etc) {
|
|
ramfs_add_file(etc, "hostname", "sub-os\n", 7);
|
|
ramfs_add_file(etc, "os-release", "NAME=\"SUB-OS\"\nVERSION=\"0.2.0-lts\"\nARCH=\"x86_64\"\n", 48);
|
|
ramfs_add_file(etc, "resolv.conf", "nameserver 10.0.2.3\nsearch localdomain\n", 39);
|
|
ramfs_add_file(etc, "motd", "====================================================\n Welcome to SUB-OS Modular Monolithic Linux Core!\n====================================================\n", 137);
|
|
}
|
|
|
|
const char* readme = "SUB-OS Production-Level Modular Operating System\nArchitecture: x86_64 Long Mode\nSubsystems: PMM, Heap, VFS, PCI, E1000, Net, Crypto, LazyBox\n";
|
|
ramfs_add_file(&root->node, "readme.txt", readme, strlen(readme));
|
|
|
|
return &root->node;
|
|
}
|