diff options
Diffstat (limited to 'kernel/src/generic')
| -rw-r--r-- | kernel/src/generic/devfs.cpp | 205 | ||||
| -rw-r--r-- | kernel/src/generic/devfs.hpp | 29 | ||||
| -rw-r--r-- | kernel/src/generic/evdev.cpp | 1 | ||||
| -rw-r--r-- | kernel/src/generic/mp.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/generic/tmpfs.cpp | 3 | ||||
| -rw-r--r-- | kernel/src/generic/vfs.hpp | 22 |
6 files changed, 247 insertions, 17 deletions
diff --git a/kernel/src/generic/devfs.cpp b/kernel/src/generic/devfs.cpp index e69de29..9b7dc1d 100644 --- a/kernel/src/generic/devfs.cpp +++ b/kernel/src/generic/devfs.cpp @@ -0,0 +1,205 @@ +#include <generic/vfs.hpp> +#include <generic/devfs.hpp> +#include <klibc/string.hpp> +#include <generic/pmm.hpp> +#include <generic/hhdm.hpp> +#include <utils/errno.hpp> +#include <generic/lock/spinlock.hpp> +#include <cstdint> +#include <atomic> + +devfs_node* head_devfs_node = nullptr; +devfs_node root_devfs_node = {}; + +std::atomic<std::uint64_t> devfs_id = 0; + +locks::preempt_spinlock devfs_lock; + +devfs_node* devfs_lookup(char* path) { + + if(klibc::strcmp(path,"/\0") == 0) + return &root_devfs_node; + + bool state = devfs_lock.lock(); + devfs_node* current_node = head_devfs_node; + while(current_node != nullptr) { + if(klibc::strcmp(current_node->path, path) == 0) { + devfs_lock.unlock(state); + return current_node; + } + } + devfs_lock.unlock(state); + return nullptr; +} + +void create(bool is_tty, char* path, void* arg, std::uint64_t mmap, std::uint64_t mmap_size, std::int32_t (*open)(file_descriptor*fd, devfs_node* node), std::int32_t (*ioctl)(devfs_node* node, std::uint64_t req, void* arg), signed long (*read)(file_descriptor* fd, devfs_node* node, void* buffer, std::size_t count), signed long (*write)(file_descriptor* fd, devfs_node* node, void* buffer, std::size_t count), bool (*poll)(devfs_node* node, vfs_poll_type type), std::int32_t (*close)(file_descriptor* fd, devfs_node* node)) { + bool state = devfs_lock.lock(); + + assert(devfs_lookup(path) == nullptr," afdsfsdfsf!!!"); + + devfs_node* new_node = (devfs_node*)(pmm::freelist::alloc_4k() + etc::hhdm()); + new_node->mmap = mmap; + new_node->mmap_size = mmap_size; + new_node->open = open; + new_node->write = write; + new_node->read = read; + new_node->poll = poll; + new_node->close = close; + new_node->ioctl = ioctl; + new_node->arg = arg; + new_node->is_a_tty = is_tty; + new_node->id = ++devfs_id; + + new_node->next = head_devfs_node; + head_devfs_node = new_node; + + devfs_lock.unlock(state); +} + +std::int32_t devfs_ioctl(file_descriptor* file, std::uint64_t req, void* arg) { + auto node = (devfs_node*)file->fs_specific.tmpfs_pointer; + if(node->ioctl == nullptr) + return -ENOTSUP; + return node->ioctl(node, req, arg); +} + +signed long devfs_read(file_descriptor* fd, void* buffer, std::size_t count) { + auto node = (devfs_node*)fd->fs_specific.tmpfs_pointer; + if(node->read == nullptr) + return -ENOTSUP; + return node->read(fd, node, buffer, count); +} + +signed long devfs_write(file_descriptor* fd, void* buffer, std::size_t count) { + auto node = (devfs_node*)fd->fs_specific.tmpfs_pointer; + if(node->write == nullptr) + return -ENOTSUP; + return node->write(fd, node, buffer, count); +} + +std::int32_t devfs_stat(file_descriptor* file, stat* out) { + if(((devfs_node*)file->other.ls_pointer)->is_root == true) { + out->st_mode = S_IFDIR | 0666; + return 0; + } + (void)file; + (void)out; + out->st_mode = S_IFCHR | 0666; + return 0; +} + +bool devfs_poll(file_descriptor* file, vfs_poll_type type) { + auto node = (devfs_node*)file->fs_specific.tmpfs_pointer; + if(node->poll == nullptr) + return false; + return node->poll(node, type); +} + +std::int32_t devfs_mmap(file_descriptor* file, std::uint64_t* out_phys, std::size_t* out_size) { + auto node = (devfs_node*)file->fs_specific.tmpfs_pointer; + if(node->mmap == 0) + return -EINVAL; + *out_phys = node->mmap; + *out_size = node->mmap_size; + return 0; +} + +void devfs_close(file_descriptor* file) { + auto node = (devfs_node*)file->fs_specific.tmpfs_pointer; + if(node->close == nullptr) + return; + node->close(file, node); + return; +} + +signed long devfs_ls(file_descriptor* file, char* out, std::size_t count) { + bool state = devfs_lock.lock(); + dirent* dir = (dirent*)out; + if(file->other.ls_pointer == nullptr) { + devfs_lock.unlock(state); + return 0; + } else if(file->other.ls_pointer == (void*)1) { + file->other.ls_pointer = (void*)head_devfs_node; + } + + devfs_node* node = (devfs_node*)file->other.ls_pointer; + + if(count < sizeof(dirent) + 1 + klibc::strlen(node->path)) { + devfs_lock.unlock(state); + return 0; + } + + dir->d_ino = node->id; + dir->d_reclen = sizeof(dirent) + 1 + klibc::strlen(node->path + 1); + dir->d_type = DT_CHR; + dir->d_off = 0; + klibc::memcpy(dir->d_name, node->path + 1, klibc::strlen(node->path + 1) + 1); + + file->other.ls_pointer = (void*)(node->next); + + devfs_lock.unlock(state); + return dir->d_reclen; +} + +std::int32_t devfs_open(filesystem* fs, void* file_desc, char* path, bool is_directory) { + (void)fs; + auto node = devfs_lookup(path); + + if(node == nullptr) + return -EINVAL; + + file_descriptor* fd = (file_descriptor*)file_desc; + if(node->is_root && is_directory) { + fd->vnode.stat = devfs_stat; + fd->vnode.ls = devfs_ls; + fd->other.ls_pointer = (void*)1; + fd->fs_specific.tmpfs_pointer = (std::uint64_t)(&root_devfs_node); + return 0; + } + + fd->vnode.stat = devfs_stat; + fd->vnode.ioctl = devfs_ioctl; + fd->vnode.poll = devfs_poll; + fd->vnode.mmap = devfs_mmap; + fd->vnode.read = devfs_read; + fd->vnode.write = devfs_write; + fd->vnode.close = devfs_close; + fd->other.is_a_tty = node->is_a_tty; + fd->fs_specific.tmpfs_pointer = (std::uint64_t)node; + + if(node->open) + node->open(fd, node); + + return 0; + +} + +std::int32_t devfs_readlink(filesystem* fs, char* path, char* buffer) { + (void)fs; + (void)path; + (void)buffer; + return -EINVAL; +} + +std::int32_t devfs_create(filesystem* fs, char* path, vfs_file_type type, std::uint32_t mode) { + (void)fs; + (void)path; + (void)type; + (void)mode; + return -ENOTSUP; +} + +std::int32_t devfs_remove(filesystem* fs, char* path) { + (void)fs; + (void)path; + return -ENOTSUP; +} + +void init(vfs::node* new_node) { + root_devfs_node.is_root = true; + new_node->fs->create = devfs_create; + new_node->fs->open = devfs_open; + new_node->fs->readlink = devfs_readlink; + new_node->fs->remove = devfs_remove; + klibc::memcpy(new_node->path, "/dev\0", sizeof("/dev\0") + 1); +}
\ No newline at end of file diff --git a/kernel/src/generic/devfs.hpp b/kernel/src/generic/devfs.hpp index 2c91d83..5497b88 100644 --- a/kernel/src/generic/devfs.hpp +++ b/kernel/src/generic/devfs.hpp @@ -3,11 +3,36 @@ #include <generic/vfs.hpp> struct devfs_node { - vfs::pipe* pipe; + vfs::pipe* write_pipe; + vfs::pipe* read_pipe; + + std::int32_t (*open)(file_descriptor* fd, devfs_node* node); + std::int32_t (*ioctl)(devfs_node* node, std::uint64_t req, void* arg); + signed long (*read)(file_descriptor* fd, devfs_node* node, void* buffer, std::size_t count); + signed long (*write)(file_descriptor* fd, devfs_node* node, void* buffer, std::size_t count); + bool (*poll)(devfs_node* node, vfs_poll_type type); + + std::int32_t (*close)(file_descriptor* fd, devfs_node* node); + + void* arg; + + bool is_root; + + bool is_a_tty; + char path[256]; + + std::uint64_t mmap; + std::uint64_t mmap_size; + + std::uint64_t id; + + devfs_node* next; }; +static_assert(sizeof(devfs_node) < 4096, "fsfsdf"); + // for non input devices namespace devfs { - void create(); + void create(bool is_tty, char* path, void* arg, std::uint64_t mmap, std::uint64_t mmap_size, std::int32_t (*open)(file_descriptor*fd, devfs_node* node), std::int32_t (*ioctl)(devfs_node* node, std::uint64_t req, void* arg), signed long (*read)(file_descriptor* fd, devfs_node* node, void* buffer, std::size_t count), signed long (*write)(file_descriptor* fd, devfs_node* node, void* buffer, std::size_t count), bool (*poll)(devfs_node* node, vfs_poll_type type), std::int32_t (*close)(file_descriptor* fd, devfs_node* node)); void init(vfs::node* new_node); }
\ No newline at end of file diff --git a/kernel/src/generic/evdev.cpp b/kernel/src/generic/evdev.cpp index b7bb4c1..409ac71 100644 --- a/kernel/src/generic/evdev.cpp +++ b/kernel/src/generic/evdev.cpp @@ -153,6 +153,7 @@ std::int32_t evdev_stat(file_descriptor* file, stat* out) { std::int32_t evdev_open(filesystem* fs, void* file_desc, char* path, bool is_directory) { file_descriptor* fd = (file_descriptor*)file_desc; + (void)fs; if(klibc::strcmp(path, "/") == 0) { fd->fs_specific.tmpfs_pointer = (std::uint64_t)&evroot_node; diff --git a/kernel/src/generic/mp.cpp b/kernel/src/generic/mp.cpp index 0ab4678..89be3c8 100644 --- a/kernel/src/generic/mp.cpp +++ b/kernel/src/generic/mp.cpp @@ -34,6 +34,7 @@ void mp::sync() { } void smptrampoline(limine_mp_info* smp_info) { + smp_lock.lock(); std::uint32_t enum_cpu = smp_info->processor_id; arch::init(ARCH_INIT_MP); @@ -41,7 +42,7 @@ void smptrampoline(limine_mp_info* smp_info) { x86_64::cpu_data()->cpu = balance_how_much_cpus++; enum_cpu = x86_64::cpu_data()->cpu; #endif - klibc::printf("SMP: Cpu %d is online (%d)\r\n",smp_info->lapic_id,enum_cpu); + log("smp", "cpu %d is online (%d)",smp_info->lapic_id,enum_cpu); smp_lock.unlock(); mp::sync(); if(time::timer) time::timer->sleep(10000); @@ -63,4 +64,5 @@ void mp::init() { mp_info->cpus[i]->goto_address = smptrampoline; } } + log("mp", "detected %d cpus", mp_info->cpu_count); }
\ No newline at end of file diff --git a/kernel/src/generic/tmpfs.cpp b/kernel/src/generic/tmpfs.cpp index 650fda3..a399d60 100644 --- a/kernel/src/generic/tmpfs.cpp +++ b/kernel/src/generic/tmpfs.cpp @@ -117,7 +117,6 @@ signed long tmpfs_ls(file_descriptor* file, char* out, std::size_t count) { auto node = (tmpfs::tmpfs_node*)file->fs_specific.tmpfs_pointer; std::size_t current_offset = 0; - dirent file_ls = {}; if(node->type != vfs_file_type::directory) return -ENOTDIR; @@ -151,7 +150,7 @@ again: } file->vnode.fs->lock.unlock(); - return 0; + return current_offset; } std::int32_t tmpfs_create(filesystem* fs, char* path, vfs_file_type type, std::uint32_t mode) { diff --git a/kernel/src/generic/vfs.hpp b/kernel/src/generic/vfs.hpp index ecfd25b..1a79e98 100644 --- a/kernel/src/generic/vfs.hpp +++ b/kernel/src/generic/vfs.hpp @@ -4,6 +4,8 @@ #include <generic/lock/mutex.hpp> #include <utils/linux.hpp> #include <utils/assert.hpp> +#include <generic/pmm.hpp> +#include <generic/hhdm.hpp> #include <generic/scheduling.hpp> #define USERSPACE_PIPE_SIZE (64 * 1024) @@ -237,6 +239,9 @@ struct file_descriptor { struct { int cycle; int queue; + int tty_num; + bool is_a_tty; + void* ls_pointer; } other; struct { @@ -249,6 +254,8 @@ struct file_descriptor { std::int32_t (*stat)(file_descriptor* file, stat* out); void (*close)(file_descriptor* file); + std::int32_t (*mmap)(file_descriptor* file, std::uint64_t* out_phys, std::size_t* out_size); + signed long (*ls)(file_descriptor* file, char* out, std::size_t count); bool (*poll)(file_descriptor* file, vfs_poll_type type); @@ -305,14 +312,10 @@ namespace vfs { class pipe { private: - std::uint64_t read_ptr = 0; - std::atomic_flag is_received = ATOMIC_FLAG_INIT; std::atomic_flag is_n_closed = ATOMIC_FLAG_INIT; - int is_was_writed_ever = 0; - public: char* buffer; @@ -383,7 +386,7 @@ namespace vfs { return count; } - std::uint64_t write(const char* src_buffer, std::uint64_t count,int id) { + std::uint64_t write(const char* src_buffer, std::uint64_t count) { std::uint64_t written = 0; @@ -397,8 +400,6 @@ namespace vfs { continue; } - uint64_t old_size = this->size; - std::uint64_t to_write = (count - written) < space_left ? (count - written) : space_left; if(to_write < 0) to_write = 0; @@ -413,7 +414,7 @@ namespace vfs { return written; } - std::uint64_t nolock_write(const char* src_buffer, std::uint64_t count,int id) { + std::uint64_t nolock_write(const char* src_buffer, std::uint64_t count) { std::uint64_t written = 0; @@ -426,8 +427,6 @@ namespace vfs { std::uint64_t space_left = this->total_size - this->size; - uint64_t old_size = this->size; - std::uint64_t to_write = (count - written) < space_left ? (count - written) : space_left; if(to_write < 0) to_write = 0; @@ -442,10 +441,9 @@ namespace vfs { return written; } - std::int64_t read(std::int64_t* read_count, char* dest_buffer, std::uint64_t count, int is_block) { + std::int64_t read(char* dest_buffer, std::uint64_t count, int is_block) { std::uint64_t read_bytes = 0; - int tries = 0; while (true) { bool state = this->lock.lock(); |
