From b631f251defe2b2f7075e743f7f328cbfed5766b Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Wed, 10 Aug 2016 22:17:02 +0200 Subject: [PATCH] Complete ramdisk implementation --- kernel/include/ramdisk.hpp | 6 +++-- kernel/src/disks.cpp | 2 +- kernel/src/ramdisk.cpp | 53 +++++++++++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/kernel/include/ramdisk.hpp b/kernel/include/ramdisk.hpp index 114c6335..1cdc38ab 100644 --- a/kernel/include/ramdisk.hpp +++ b/kernel/include/ramdisk.hpp @@ -16,10 +16,12 @@ namespace ramdisk { struct disk_descriptor { uint64_t id; - //TODO + uint64_t max_size; + uint64_t pages; + char** allocated; }; -disk_descriptor* make_disk(); +disk_descriptor* make_disk(uint64_t max_size); struct ramdisk_driver : devfs::dev_driver { size_t read(void* data, char* buffer, size_t count, size_t offset, size_t& read); diff --git a/kernel/src/disks.cpp b/kernel/src/disks.cpp index 71cca193..78c224cc 100644 --- a/kernel/src/disks.cpp +++ b/kernel/src/disks.cpp @@ -57,7 +57,7 @@ devfs::dev_driver* ramdisk_driver = &ramdisk_driver_impl; devfs::dev_driver* atapi_driver = nullptr; void make_ram_disk(){ - auto* descriptor = ramdisk::make_disk(); + auto* descriptor = ramdisk::make_disk(1024 * 1024); //1MiB if(!descriptor){ logging::logf(logging::log_level::ERROR, "disks: failed to created /dev/ram0"); diff --git a/kernel/src/ramdisk.cpp b/kernel/src/ramdisk.cpp index 024cba03..875af878 100644 --- a/kernel/src/ramdisk.cpp +++ b/kernel/src/ramdisk.cpp @@ -8,6 +8,8 @@ #include "ramdisk.hpp" #include "errors.hpp" #include "disks.hpp" +#include "paging.hpp" +#include "logging.hpp" namespace { @@ -18,14 +20,17 @@ ramdisk::disk_descriptor ramdisks[MAX_RAMDISK]; } //end of anonymous namespace -ramdisk::disk_descriptor* ramdisk::make_disk(){ +ramdisk::disk_descriptor* ramdisk::make_disk(uint64_t max_size){ if(current == MAX_RAMDISK){ return nullptr; } - ramdisks[current].id = current; + auto pages = paging::pages(max_size); - //TODO + ramdisks[current].id = current; + ramdisks[current].max_size = max_size; + ramdisks[current].pages = pages; + ramdisks[current].allocated = new char*[pages]; ++current; return &ramdisks[current - 1]; @@ -37,7 +42,27 @@ size_t ramdisk::ramdisk_driver::read(void* data, char* destination, size_t count auto descriptor = reinterpret_cast(data); auto disk = reinterpret_cast(descriptor->descriptor); - return std::ERROR_INVALID_COUNT; + if(offset + count >= disk->max_size){ + logging::logf(logging::log_level::ERROR, "ramdisk: Tried to read too far\n"); + return std::ERROR_INVALID_OFFSET; + } + + while(read != count){ + auto page = offset / paging::PAGE_SIZE; + + if(!disk->allocated[page]){ + disk->allocated[page] = new char[paging::PAGE_SIZE]; + std::fill_n(disk->allocated[page], paging::PAGE_SIZE, 0); + } + + auto to_read = std::min(paging::PAGE_SIZE, count - read); + std::copy_n(destination, disk->allocated[page], to_read); + read += to_read; + + offset += paging::PAGE_SIZE; + } + + return 0; } size_t ramdisk::ramdisk_driver::write(void* data, const char* source, size_t count, size_t offset, size_t& written){ @@ -46,5 +71,25 @@ size_t ramdisk::ramdisk_driver::write(void* data, const char* source, size_t cou auto descriptor = reinterpret_cast(data); auto disk = reinterpret_cast(descriptor->descriptor); + if(offset + count >= disk->max_size){ + logging::logf(logging::log_level::ERROR, "ramdisk: Tried to write too far\n"); + return std::ERROR_INVALID_OFFSET; + } + + while(written != count){ + auto page = offset / paging::PAGE_SIZE; + + if(!disk->allocated[page]){ + disk->allocated[page] = new char[paging::PAGE_SIZE]; + std::fill_n(disk->allocated[page], paging::PAGE_SIZE, 0); + } + + auto to_write = std::min(paging::PAGE_SIZE, count - written); + std::copy_n(disk->allocated[page], source, to_write); + written += to_write; + + offset += paging::PAGE_SIZE; + } + return std::ERROR_INVALID_COUNT; }