summaryrefslogtreecommitdiff
path: root/kernel/fs/devfs.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-30 22:12:14 +0100
committerAnton Kling <anton@kling.gg>2023-10-31 00:18:38 +0100
commit8a9208612eec8ddae4c418485d848ecfa0613699 (patch)
tree2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /kernel/fs/devfs.c
parentca76600acc8bf7a02346efa5bd8f17072210ec01 (diff)
Meta: Move kernel and userland to their own folders.
This is to allow both the kernel and the userland to share certain header files and to make the folder structure a bit more clear.
Diffstat (limited to 'kernel/fs/devfs.c')
-rw-r--r--kernel/fs/devfs.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/kernel/fs/devfs.c b/kernel/fs/devfs.c
new file mode 100644
index 0000000..14748a7
--- /dev/null
+++ b/kernel/fs/devfs.c
@@ -0,0 +1,91 @@
+#include <drivers/keyboard.h>
+#include <drivers/serial.h>
+#include <fs/devfs.h>
+#include <fs/vfs.h>
+#include <random.h>
+
+devfs_file files[20];
+int num_files = 0;
+
+vfs_inode_t *devfs_add_file(
+ char *path,
+ int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd),
+ int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd),
+ vfs_vm_object_t *(get_vm_object)(uint64_t length, uint64_t offset,
+ vfs_fd_t *fd),
+ uint8_t has_data, uint8_t can_write, int type) {
+ files[num_files].name = copy_and_allocate_string(path);
+
+ vfs_inode_t *i = kmalloc(sizeof(vfs_inode_t));
+ files[num_files].inode = i;
+ i->type = type;
+ i->read = read;
+ i->write = write;
+ i->close = NULL;
+ i->get_vm_object = get_vm_object;
+ i->has_data = has_data;
+ i->is_open = 1;
+ i->can_write = can_write;
+ num_files++;
+ return i;
+}
+
+vfs_inode_t *devfs_open(const char *file) {
+ for (int i = 0; i < num_files; i++)
+ if (isequal_n(files[i].name, file, strlen(files[i].name)))
+ return files[i].inode;
+
+ return 0;
+}
+
+int devfs_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) {
+ return fd->inode->read(buffer, offset, len, fd);
+}
+
+int devfs_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) {
+ return fd->inode->write(buffer, offset, len, fd);
+}
+
+vfs_vm_object_t *devfs_get_vm_object(uint64_t length, uint64_t offset,
+ vfs_fd_t *fd) {
+ return fd->inode->get_vm_object(length, offset, fd);
+}
+
+int stdout_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) {
+ (void)offset;
+ (void)fd;
+
+ int rc = len;
+ for (; len--;)
+ putc(*buffer++);
+ return rc;
+}
+
+int serial_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) {
+ (void)offset;
+ (void)fd;
+
+ int rc = len;
+ for (; len--;)
+ write_serial(*buffer++);
+ return rc;
+}
+
+void add_serial(void) {
+ devfs_add_file("/serial", NULL, serial_write, NULL, 0, 1,
+ FS_TYPE_CHAR_DEVICE);
+}
+
+void add_stdout(void) {
+ devfs_add_file("/stdout", NULL, stdout_write, NULL, 0, 1,
+ FS_TYPE_CHAR_DEVICE);
+}
+
+vfs_inode_t *devfs_mount(void) {
+ vfs_inode_t *root = kmalloc_eternal(sizeof(vfs_inode_t));
+ root->open = devfs_open;
+ root->read = devfs_read;
+ root->write = devfs_write;
+ root->close = NULL;
+ return root;
+}