Virtual File System #10

Merged
apio merged 7 commits from vfs into main 2022-10-10 18:25:43 +00:00
14 changed files with 174 additions and 20 deletions
Showing only changes of commit da2ede3450 - Show all commits

View File

@ -5,6 +5,8 @@
#include <sys/syscall.h>
#include <unistd.h>
typedef long ssize_t;
int main()
{
if (gettid() == 0) // why are we the idle task?
@ -25,14 +27,42 @@ int main()
sleep(2);
const char* filename = "/sys/config";
printf("Opening %s for reading...\n", filename);
int fd = syscall(SYS_open, filename, 1);
if (fd < 0)
{
char* variable = malloc(200);
*variable = 3;
printf("Allocated variable at address %p\n", variable);
free(variable);
perror("open");
// return 1;
}
else { printf("Got fd %d\n", fd); }
char buf[4096];
ssize_t nread = syscall(SYS_read, fd, sizeof(buf), buf);
if (nread < 0)
{
perror("read");
// return 1;
}
else
{
buf[nread] = 0;
printf("Read %zd bytes\n\n", nread);
printf("%s", buf);
}
printf("Press any key to restart.\n");
if (syscall(SYS_close, fd) < 0)
{
perror("close");
// return 1;
}
printf("\n\nPress any key to restart.\n");
return 0;
}

View File

@ -1,6 +1,9 @@
#pragma once
#define EPERM 1
#define ENOENT 2
#define EBADF 9
#define ENOMEM 12
#define EINVAL 22
#define EMFILE 24
#define ENOSYS 38

View File

@ -27,9 +27,8 @@ struct Descriptor
Descriptor();
private:
uint64_t m_offset;
VFS::Node* m_node;
bool m_can_read;
bool m_is_open;
}
bool m_can_read;
VFS::Node* m_node;
uint64_t m_offset;
};

View File

@ -12,6 +12,9 @@
#define SYS_gettid 7
#define SYS_mmap 8
#define SYS_munmap 9
#define SYS_open 10
#define SYS_read 11
#define SYS_close 12
namespace Syscall
{
@ -27,4 +30,7 @@ void sys_rand(Context* context);
void sys_getversion(Context* context, char* buffer, size_t max);
void sys_gettid(Context* context);
void sys_mmap(Context* context, void* address, size_t size, int flags);
void sys_munmap(Context* context, void* address, size_t size);
void sys_munmap(Context* context, void* address, size_t size);
void sys_open(Context* context, const char* filename, int flags);
void sys_read(Context* context, int fd, size_t size, char* buffer);
void sys_close(Context* context, int fd);

View File

@ -1,7 +1,10 @@
#pragma once
#include "fs/FileDescriptor.h"
#include "interrupts/Context.h"
#include "sys/elf/Image.h"
#define TASK_MAX_FDS 8
struct Task
{
enum TaskState
@ -36,6 +39,8 @@ struct Task
bool is_user_task();
ELFImage* image = nullptr;
Descriptor files[TASK_MAX_FDS];
};
void set_context_from_task(Task& task, Context* ctx);

View File

@ -5,7 +5,7 @@ Descriptor::Descriptor() : m_is_open(false)
}
Descriptor::Descriptor(const Descriptor& other)
: m_is_open(other.is_open()), m_can_read(other.can_read()), m_node(other.m_node), m_offset(other.m_offset)
: m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_node(other.m_node), m_offset(other.m_offset)
{
}
@ -14,6 +14,7 @@ void Descriptor::open(VFS::Node* node, bool can_read)
m_can_read = can_read;
m_node = node;
m_offset = 0;
m_is_open = true;
}
ssize_t Descriptor::read(size_t size, char* buffer)

View File

@ -26,6 +26,9 @@ void Syscall::entry(Context* context)
case SYS_gettid: sys_gettid(context); break;
case SYS_mmap: sys_mmap(context, (void*)context->rdi, context->rsi, (int)context->rdx); break;
case SYS_munmap: sys_munmap(context, (void*)context->rdi, context->rsi); break;
case SYS_open: sys_open(context, (const char*)context->rdi, (int)context->rsi); break;
case SYS_read: sys_read(context, (int)context->rdi, context->rsi, (char*)context->rdx); break;
case SYS_close: sys_close(context, (int)context->rdi); break;
default: context->rax = -ENOSYS; break;
}
}

View File

@ -1,9 +1,108 @@
#define MODULE "stdio"
#include "errno.h"
#include "interrupts/Context.h"
#include "io/Serial.h"
#include "log/Log.h"
#include "render/TextRenderer.h"
#include "thread/Scheduler.h"
#include "thread/Task.h"
#define STDIO_FAIL(function, error) kwarnln("%s failed with %s", #function, #error)
void sys_write(Context* context, const char* addr, size_t size)
{
context->rax = size;
TextRenderer::write(addr, size);
}
void sys_open(Context* context, const char* filename, int flags)
{
Task* current_task = Scheduler::current_task();
int fd = -1;
for (fd = 0; fd < TASK_MAX_FDS; fd++)
{
if (!current_task->files[fd].is_open()) break;
}
if (fd == -1)
{
STDIO_FAIL(open, EMFILE);
context->rax = -EMFILE;
return;
}
VFS::Node* node = VFS::resolve_path(filename);
if (!node)
{
STDIO_FAIL(open, ENOENT);
context->rax = -ENOENT;
return;
}
current_task->files[fd].open(node,
(bool)flags); // FIXME: Implement more flags. (right now, 1 is can_read, 0 is not)
context->rax = fd;
return;
}
void sys_read(Context* context, int fd, size_t size, char* buffer)
{
if (!buffer)
{
STDIO_FAIL(read, EINVAL);
context->rax = -EINVAL;
return;
}
if (fd >= TASK_MAX_FDS)
{
STDIO_FAIL(read, EBADF);
context->rax = -EBADF;
return;
}
if (fd < 0)
{
STDIO_FAIL(read, EBADF);
context->rax = -EBADF;
return;
}
Task* current_task = Scheduler::current_task();
if (!current_task->files[fd].is_open())
{
STDIO_FAIL(read, EBADF);
context->rax = -EBADF;
return;
}
if (!current_task->files[fd].can_read())
{
STDIO_FAIL(read, EBADF);
context->rax = -EBADF;
return;
}
ssize_t result = current_task->files[fd].read(size, buffer);
context->rax = (size_t)result;
return;
}
void sys_close(Context* context, int fd)
{
if (fd >= TASK_MAX_FDS)
{
STDIO_FAIL(close, EBADF);
context->rax = -EBADF;
return;
}
if (fd < 0)
{
STDIO_FAIL(close, EBADF);
context->rax = -EBADF;
return;
}
Task* current_task = Scheduler::current_task();
if (!current_task->files[fd].is_open())
{
STDIO_FAIL(close, EBADF);
context->rax = -EBADF;
return;
}
current_task->files[fd].close();
context->rax = 0;
return;
}

View File

@ -21,7 +21,7 @@ typedef struct stackframe
void StackTracer::trace()
{
stackframe* frame = (stackframe*)m_base_pointer;
while (Memory::is_kernel_address((uintptr_t)frame))
while (frame)
{
char symbol_name[512];
get_symbol_name(frame->instruction, symbol_name);
@ -32,11 +32,6 @@ void StackTracer::trace()
void StackTracer::trace_with_ip(uintptr_t ip)
{
if (!Memory::is_kernel_address(ip))
{
printf("(user stack)");
return;
}
char symbol_name[512];
get_symbol_name(ip, symbol_name);
printf("%lx: %s\n", ip, symbol_name);

View File

@ -7,7 +7,7 @@
do { \
if (rc < 0) \
{ \
errno = (int)rc; \
errno = (int)(-rc); \
return -1; \
} \
return (type)rc; \

View File

@ -4,8 +4,11 @@
extern int errno;
#define EPERM 1
#define ENOENT 2
#define EBADF 9
#define ENOMEM 12
#define EINVAL 22
#define EMFILE 24
#define ENOSYS 38
#endif

View File

@ -11,6 +11,9 @@
#define SYS_gettid 7
#define SYS_mmap 8
#define SYS_munmap 9
#define SYS_open 10
#define SYS_read 11
#define SYS_close 12
#ifndef __want_syscalls
#ifdef __cplusplus

View File

@ -121,7 +121,11 @@ extern "C"
case EINVAL: return "Invalid argument";
case ENOMEM: return "Out of memory";
case ENOSYS: return "Function not implemented";
default: return 0;
case ENOENT: return "No such file or directory";
case EBADF: return "Bad file descriptor";
case EMFILE: return "Too many open files";
case 0: return "Success";
default: return (char*)(unsigned long int)errnum;
}
}

View File

@ -35,15 +35,18 @@ extern "C"
case SYS_gettid:
case SYS_rand: result = __luna_syscall0(number); break;
case SYS_exit:
case SYS_close:
case SYS_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break;
case SYS_write:
case SYS_munmap:
case SYS_open:
case SYS_getversion: {
arg arg0 = va_arg(ap, arg);
arg arg1 = va_arg(ap, arg);
result = __luna_syscall2(number, arg0, arg1);
break;
}
case SYS_read:
case SYS_mmap: {
arg arg0 = va_arg(ap, arg);
arg arg1 = va_arg(ap, arg);