Virtual File System #10

Merged
apio merged 7 commits from vfs into main 2022-10-10 18:25:43 +00:00
4 changed files with 113 additions and 0 deletions
Showing only changes of commit f3d7e220ac - Show all commits

22
kernel/include/fs/VFS.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
namespace VFS
{
struct Node;
typedef int32_t (*node_read)(Node*, uint32_t, uint32_t, char*);
typedef Node* (*node_finddir)(Node*, const char*);
struct Node
{
char name[64];
uint64_t inode;
node_read read_func;
node_finddir find_func;
};
int32_t read(Node* node, uint32_t offset, uint32_t length, char* buffer);
Node* open(const char* filename);
void mount_root(Node* root);
}

24
kernel/src/fs/VFS.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "fs/VFS.h"
static VFS::Node* vfs_root;
int32_t VFS::read(Node* node, uint32_t offset, uint32_t length, char* buffer)
{
if (!node) return -1;
if (!node->read_func) return -1;
return node->read_func(node, offset, length, buffer);
}
VFS::Node* VFS::open(const char* filename)
{
if (!vfs_root) return 0;
if (!vfs_root->find_func) return 0;
return vfs_root->find_func(vfs_root, filename);
}
void VFS::mount_root(Node* root)
{
vfs_root = root;
}

View File

@ -2,6 +2,7 @@
#include "init/InitRD.h"
#include "bootboot.h"
#include "fs/VFS.h"
#include "io/Serial.h"
#include "log/Log.h"
#include "memory/MemoryManager.h"
@ -14,6 +15,8 @@ extern BOOTBOOT bootboot;
static void* initrd_base;
static bool initrd_initialized = false;
static VFS::Node initrd_root;
bool InitRD::is_initialized()
{
return initrd_initialized;
@ -112,10 +115,58 @@ void InitRD::for_each(void (*callback)(File& f))
}
}
static InitRD::File files[32];
static uint32_t total_files = 0;
static VFS::Node nodes[32];
int32_t initrd_read(VFS::Node* node, uint32_t offset, uint32_t length, char* buffer)
{
if (!node) return -1;
if (node->inode >= total_files) return -1;
InitRD::File& file = files[node->inode];
if (offset > file.size) return -1;
if (offset + length > file.size) { length = (uint32_t)file.size - offset; }
memcpy(buffer, (void*)((uint64_t)file.addr + offset), length);
return (int32_t)length;
}
VFS::Node* initrd_scan_root(VFS::Node*, const char* filename)
{
for (uint32_t i = 0; i < total_files; i++)
{
if (strncmp(nodes[i].name, filename, sizeof(VFS::Node::name)) == 0) { return &nodes[i]; }
}
return 0;
}
void initrd_scan()
{
InitRD::for_each([](InitRD::File& f) {
if (total_files >= 32) return;
kdbgln("registering file %s", f.name);
files[total_files++] = f;
});
for (uint32_t i = 0; i < total_files; i++)
{
VFS::Node& node = nodes[i];
node.inode = i;
node.read_func = initrd_read;
strncpy(node.name, files[i].name, sizeof(node.name));
}
}
void InitRD::init()
{
initrd_base =
MemoryManager::get_unaligned_mappings((void*)bootboot.initrd_ptr, bootboot.initrd_size / PAGE_SIZE + 1);
kdbgln("physical base at %lx, size %lx, mapped to %p", bootboot.initrd_ptr, bootboot.initrd_size, initrd_base);
kdbgln("total blocks: %ld", get_total_blocks());
initrd_scan();
initrd_root.inode = (uint64_t)-1;
strncpy(initrd_root.name, "initrd", 7);
initrd_root.find_func = initrd_scan_root;
VFS::mount_root(&initrd_root);
kdbgln("mounted initrd at VFS root, total files: %d", total_files);
initrd_initialized = true;
}

View File

@ -4,6 +4,7 @@
#include "assert.h"
#include "config.h"
#include "cpu/CPU.h"
#include "fs/VFS.h"
#include "gdt/GDT.h"
#include "init/Init.h"
#include "init/InitRD.h"
@ -159,6 +160,21 @@ extern "C" void _start()
kinfoln("Interrupts enabled");
kinfoln("Trying VFS");
VFS::Node* node = VFS::open("sys/moon.sym");
if (!node) { kerrorln("Unable to find file in VFS"); }
else
{
kinfoln("Found '%s'", node->name);
char buffer[256];
kinfoln("Reading 255 bytes at offset 128...");
int nwritten = VFS::read(node, 128, 255, buffer);
kinfoln("Read a total of %d bytes", nwritten);
buffer[255] = 0;
kinfoln("Read: %s", buffer);
}
PCI::scan([](PCI::Device& dev) {
kinfoln("Found PCI device %x:%x, %s", dev.id().vendor, dev.id().device, pci_type_name(dev.type()));
});