VFS, DeviceFS: Implement a device filesystem

For now, we just have a version device. (this will allow us to get rid of sys_getversion!!)
More should be implemented soon.
This commit is contained in:
apio 2022-10-11 19:21:16 +02:00
parent a198cf8d8d
commit 0a7d4a530d
8 changed files with 123 additions and 24 deletions

View File

@ -8,6 +8,39 @@
typedef long ssize_t;
int print_version()
{
char version[4096];
FILE* verfile = fopen("/dev/version", "r");
if (!verfile)
{
perror("fopen");
return 1;
}
size_t nread = fread(version, 4096, 1, verfile);
if (ferror(verfile))
{
perror("fread");
return 1;
}
printf("Read %zd bytes\n", nread);
version[nread] = 0;
if (fclose(verfile) < 0)
{
perror("fclose");
return 1;
}
printf("Your kernel version is %s\n\n", version);
return 0;
}
int main()
{
if (gettid() == 0) // why are we the idle task?
@ -21,10 +54,7 @@ int main()
sleep(1);
char version[40];
syscall(SYS_getversion, version, sizeof(version));
printf("Your kernel version is %s\n\n", version);
if (print_version()) return 1;
sleep(2);

View File

@ -38,6 +38,7 @@ namespace VFS
Node* resolve_path(const char* filename, Node* root = nullptr);
void mount(Node* mountpoint, Node* mounted);
void mount(const char* pathname, Node* mounted);
void unmount(Node* mountpoint);

View File

@ -0,0 +1,9 @@
#pragma once
#include "fs/VFS.h"
namespace DeviceFS
{
VFS::Node* get();
VFS::Node* finddir(VFS::Node* node, const char* filename);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "fs/VFS.h"
namespace VersionDevice
{
VFS::Node* create_new();
ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer);
}

View File

@ -134,6 +134,11 @@ void VFS::mount(Node* mountpoint, Node* mounted)
mountpoint->flags |= VFS_MOUNTPOINT;
}
void VFS::mount(const char* pathname, Node* mounted)
{
return mount(resolve_path(pathname), mounted);
}
void VFS::unmount(Node* mountpoint)
{
if (!mountpoint) return;

View File

@ -0,0 +1,35 @@
#include "fs/devices/DeviceFS.h"
#include "fs/devices/Version.h"
#include "std/stdlib.h"
#include "std/string.h"
#define DEVFS_MAX_FILES 32
VFS::Node* devfs_root = nullptr;
VFS::Node* devfs_files[DEVFS_MAX_FILES];
int devfs_file_count = 0;
VFS::Node* DeviceFS::get()
{
if (devfs_root) return devfs_root;
devfs_root = new VFS::Node;
devfs_root->length = 0;
devfs_root->inode = 0;
devfs_root->type = VFS_DIRECTORY;
devfs_root->find_func = DeviceFS::finddir;
strncpy(devfs_root->name, "dev", sizeof(devfs_root->name));
devfs_files[devfs_file_count++] = VersionDevice::create_new();
return devfs_root;
}
VFS::Node* DeviceFS::finddir(VFS::Node* node, const char* filename)
{
if (!node) return 0;
for (int i = 0; i < devfs_file_count; i++)
{
if (strncmp(devfs_files[i]->name, filename, sizeof(VFS::Node::name)) == 0) { return devfs_files[i]; }
}
return 0;
}

View File

@ -0,0 +1,26 @@
#include "fs/devices/Version.h"
#include "config.h"
#include "std/stdio.h"
#include "std/stdlib.h"
#include "std/string.h"
VFS::Node* VersionDevice::create_new()
{
VFS::Node* dev = new VFS::Node;
dev->read_func = VersionDevice::read;
dev->inode = 0;
dev->length = strlen(moon_version()) + 5;
dev->type = VFS_FILE;
strncpy(dev->name, "version", sizeof(dev->name));
return dev;
}
ssize_t VersionDevice::read(VFS::Node* node, size_t offset, size_t size, char* buffer)
{
if (!node) return -1;
if (offset > node->length) return -1;
if (offset + size > node->length) { size = node->length - offset; }
if (offset > 0) return -1;
snprintf(buffer, size + 1, "moon %s", moon_version()); // FIXME: Support offseting this read
return (ssize_t)size;
}

View File

@ -5,6 +5,7 @@
#include "config.h"
#include "cpu/CPU.h"
#include "fs/VFS.h"
#include "fs/devices/DeviceFS.h"
#include "gdt/GDT.h"
#include "init/Init.h"
#include "init/InitRD.h"
@ -158,30 +159,13 @@ extern "C" void _start()
Init::finish_kernel_boot();
VFS::mkdir("/", "dev");
VFS::mount("/dev", DeviceFS::get());
Interrupts::enable();
kinfoln("Interrupts enabled");
kinfoln("Trying VFS");
if (VFS::mkdir("/", "rootfs") < 0) { kerrorln("Unable to create directory rootfs"); }
else
{
VFS::mount(VFS::resolve_path("/rootfs"), VFS::root());
VFS::Node* node = VFS::resolve_path("/rootfs/sys/config");
if (!node) kerrorln("unable to find /sys/config in VFS");
else
{
kinfoln("Found '%s'", node->name);
char* buffer = (char*)kmalloc(node->length + 1);
buffer[node->length] = 0;
ssize_t nread = VFS::read(node, 0, node->length, buffer);
kdbgln("Read %zd bytes", nread);
kinfoln("Read: %s", buffer);
kfree(buffer);
}
}
PCI::scan([](PCI::Device& dev) {
kinfoln("Found PCI device %x:%x, %s", dev.id().vendor, dev.id().device, pci_type_name(dev.type()));
});