Compare commits
3 Commits
49c7900407
...
8158ddc94f
Author | SHA1 | Date | |
---|---|---|---|
8158ddc94f | |||
b38c52f8c7 | |||
f3d7e220ac |
26
kernel/include/fs/VFS.h
Normal file
26
kernel/include/fs/VFS.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#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;
|
||||||
|
uint64_t length;
|
||||||
|
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);
|
||||||
|
|
||||||
|
Node* root();
|
||||||
|
}
|
65
kernel/src/fs/VFS.cpp
Normal file
65
kernel/src/fs/VFS.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#define MODULE "vfs"
|
||||||
|
|
||||||
|
#include "fs/VFS.h"
|
||||||
|
#include "log/Log.h"
|
||||||
|
#include "std/string.h"
|
||||||
|
|
||||||
|
static VFS::Node* vfs_root;
|
||||||
|
|
||||||
|
int32_t VFS::read(Node* node, uint32_t offset, uint32_t length, char* buffer)
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
kwarnln("read() failed: trying to read from nullptr");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!node->read_func)
|
||||||
|
{
|
||||||
|
kwarnln("read() failed: the chosen node doesn't support reading");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
kdbgln("read(): node %s (inode %ld), offset %d, %d bytes, into %p", node->name, node->inode, offset, length,
|
||||||
|
(void*)buffer);
|
||||||
|
|
||||||
|
return node->read_func(node, offset, length, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
VFS::Node* VFS::open(const char* filename)
|
||||||
|
{
|
||||||
|
if (!vfs_root)
|
||||||
|
{
|
||||||
|
kwarnln("open() failed: root not mounted");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!vfs_root->find_func)
|
||||||
|
{
|
||||||
|
kwarnln("open() failed: root doesn't support finding files");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kinfoln("open(): opening %s", filename);
|
||||||
|
|
||||||
|
return vfs_root->find_func(vfs_root, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFS::mount_root(Node* root)
|
||||||
|
{
|
||||||
|
if (!root)
|
||||||
|
{
|
||||||
|
kwarnln("mount_root() failed: attempted to mount nullptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (vfs_root)
|
||||||
|
{
|
||||||
|
kwarnln("mount_root() failed: root filesystem already mounted");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kinfoln("mounting node '%s' as vfs root", root->name);
|
||||||
|
vfs_root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
VFS::Node* VFS::root()
|
||||||
|
{
|
||||||
|
return vfs_root;
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "init/InitRD.h"
|
#include "init/InitRD.h"
|
||||||
#include "bootboot.h"
|
#include "bootboot.h"
|
||||||
|
#include "fs/VFS.h"
|
||||||
#include "io/Serial.h"
|
#include "io/Serial.h"
|
||||||
#include "log/Log.h"
|
#include "log/Log.h"
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
@ -14,6 +15,8 @@ extern BOOTBOOT bootboot;
|
|||||||
static void* initrd_base;
|
static void* initrd_base;
|
||||||
static bool initrd_initialized = false;
|
static bool initrd_initialized = false;
|
||||||
|
|
||||||
|
static VFS::Node initrd_root;
|
||||||
|
|
||||||
bool InitRD::is_initialized()
|
bool InitRD::is_initialized()
|
||||||
{
|
{
|
||||||
return initrd_initialized;
|
return initrd_initialized;
|
||||||
@ -112,10 +115,62 @@ 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;
|
||||||
|
node.length = files[i].size;
|
||||||
|
strncpy(node.name, files[i].name, sizeof(node.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InitRD::init()
|
void InitRD::init()
|
||||||
{
|
{
|
||||||
initrd_base =
|
initrd_base =
|
||||||
MemoryManager::get_unaligned_mappings((void*)bootboot.initrd_ptr, bootboot.initrd_size / PAGE_SIZE + 1);
|
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("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.length = 0;
|
||||||
|
initrd_root.inode = (uint64_t)-1;
|
||||||
|
strncpy(initrd_root.name, "initrd", 7);
|
||||||
|
initrd_root.find_func = initrd_scan_root;
|
||||||
|
VFS::mount_root(&initrd_root);
|
||||||
|
VFS::mount_root(0);
|
||||||
|
VFS::mount_root(&initrd_root);
|
||||||
|
kdbgln("mounted initrd at VFS root, total files: %d", total_files);
|
||||||
initrd_initialized = true;
|
initrd_initialized = true;
|
||||||
}
|
}
|
@ -4,6 +4,7 @@
|
|||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cpu/CPU.h"
|
#include "cpu/CPU.h"
|
||||||
|
#include "fs/VFS.h"
|
||||||
#include "gdt/GDT.h"
|
#include "gdt/GDT.h"
|
||||||
#include "init/Init.h"
|
#include "init/Init.h"
|
||||||
#include "init/InitRD.h"
|
#include "init/InitRD.h"
|
||||||
@ -159,6 +160,21 @@ extern "C" void _start()
|
|||||||
|
|
||||||
kinfoln("Interrupts enabled");
|
kinfoln("Interrupts enabled");
|
||||||
|
|
||||||
|
kinfoln("Trying VFS");
|
||||||
|
|
||||||
|
VFS::Node* node = VFS::open("sys/config");
|
||||||
|
if (!node) { kerrorln("Unable to find file in VFS"); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kinfoln("Found '%s'", node->name);
|
||||||
|
char* buffer = (char*)kmalloc(node->length + 1);
|
||||||
|
buffer[node->length] = 0;
|
||||||
|
int nread = VFS::read(node, 0, (uint32_t)node->length, buffer);
|
||||||
|
kdbgln("Read %d bytes", nread);
|
||||||
|
kinfoln("Read: %s", buffer);
|
||||||
|
kfree(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
PCI::scan([](PCI::Device& dev) {
|
PCI::scan([](PCI::Device& dev) {
|
||||||
kinfoln("Found PCI device %x:%x, %s", dev.id().vendor, dev.id().device, pci_type_name(dev.type()));
|
kinfoln("Found PCI device %x:%x, %s", dev.id().vendor, dev.id().device, pci_type_name(dev.type()));
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user