diff --git a/kernel/src/ata.cpp b/kernel/src/ata.cpp index 3205e120..4dd26153 100644 --- a/kernel/src/ata.cpp +++ b/kernel/src/ata.cpp @@ -12,9 +12,13 @@ #include "thor.hpp" #include "interrupts.hpp" #include "console.hpp" +#include "errors.hpp" +#include "disks.hpp" namespace { +static constexpr const size_t BLOCK_SIZE = 512; + //IDE Controllers #define ATA_PRIMARY 0x1F0 #define ATA_SECONDARY 0x170 @@ -351,20 +355,134 @@ ata::drive_descriptor& ata::drive(uint8_t disk){ return drives[disk]; } -size_t ata::ata_driver::read(void* data, char* buffer, size_t count, size_t offset, size_t& read){ - //TODO +size_t ata::ata_driver::read(void* data, char* destination, size_t count, size_t offset, size_t& read){ + if(count % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_COUNT; + } + + if(offset % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_OFFSET; + } + + read = 0; + + auto sectors = count % BLOCK_SIZE; + auto start = offset % BLOCK_SIZE; + + auto descriptor = reinterpret_cast(data); + auto disk = reinterpret_cast(descriptor->descriptor); + + auto buffer = reinterpret_cast(destination); + + for(size_t i = 0; i < sectors; ++i){ + if(!read_write_sector(*disk, start + i, buffer, true)){ + return std::ERROR_FAILED; + } + + buffer += BLOCK_SIZE; + read += BLOCK_SIZE; + } + + return 0; } -size_t ata::ata_driver::write(void* data, const char* buffer, size_t count, size_t offset, size_t& written){ - //TODO +size_t ata::ata_driver::write(void* data, const char* source, size_t count, size_t offset, size_t& written){ + if(count % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_COUNT; + } + + if(offset % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_OFFSET; + } + + written = 0; + + auto sectors = count % BLOCK_SIZE; + auto start = offset % BLOCK_SIZE; + + auto descriptor = reinterpret_cast(data); + auto disk = reinterpret_cast(descriptor->descriptor); + + auto buffer = reinterpret_cast(const_cast(source)); + + for(size_t i = 0; i < sectors; ++i){ + if(!read_write_sector(*disk, start + i, buffer, false)){ + return std::ERROR_FAILED; + } + + buffer += BLOCK_SIZE; + written += BLOCK_SIZE; + } + + return 0; } -size_t ata::ata_part_driver::read(void* data, char* buffer, size_t count, size_t offset, size_t& read){ - //TODO +size_t ata::ata_part_driver::read(void* data, char* destination, size_t count, size_t offset, size_t& read){ + if(count % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_COUNT; + } + + if(offset % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_OFFSET; + } + + read = 0; + + auto sectors = count % BLOCK_SIZE; + auto start = offset % BLOCK_SIZE; + + auto part_descriptor = reinterpret_cast(data); + auto descriptor = part_descriptor->disk; + auto disk = reinterpret_cast(descriptor->descriptor); + + start += part_descriptor->start; + + auto buffer = reinterpret_cast(destination); + + for(size_t i = 0; i < sectors; ++i){ + if(!read_write_sector(*disk, start + i, buffer, true)){ + return std::ERROR_FAILED; + } + + buffer += BLOCK_SIZE; + read += BLOCK_SIZE; + } + + return 0; } -size_t ata::ata_part_driver::write(void* data, const char* buffer, size_t count, size_t offset, size_t& written){ - //TODO +size_t ata::ata_part_driver::write(void* data, const char* source, size_t count, size_t offset, size_t& written){ + if(count % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_COUNT; + } + + if(offset % BLOCK_SIZE != 0){ + return std::ERROR_INVALID_OFFSET; + } + + written = 0; + + auto sectors = count % BLOCK_SIZE; + auto start = offset % BLOCK_SIZE; + + auto part_descriptor = reinterpret_cast(data); + auto descriptor = part_descriptor->disk; + auto disk = reinterpret_cast(descriptor->descriptor); + + start += part_descriptor->start; + + auto buffer = reinterpret_cast(const_cast(source)); + + for(size_t i = 0; i < sectors; ++i){ + if(!read_write_sector(*disk, start + i, buffer, false)){ + return std::ERROR_FAILED; + } + + buffer += BLOCK_SIZE; + written += BLOCK_SIZE; + } + + return 0; } bool ata::read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination){ @@ -375,7 +493,7 @@ bool ata::read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, v return false; } - buffer += 512; + buffer += BLOCK_SIZE;; } return true; @@ -389,7 +507,7 @@ bool ata::write_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, return false; } - buffer += 512; + buffer += BLOCK_SIZE; } return true; diff --git a/kernel/src/disks.cpp b/kernel/src/disks.cpp index 527988b2..d567e194 100644 --- a/kernel/src/disks.cpp +++ b/kernel/src/disks.cpp @@ -67,14 +67,14 @@ void disks::detect_disks(){ std::string name = "cd"; name += cdrom++; - devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, atapi_driver, &descriptor); + devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, atapi_driver, &_disks[number_of_disks]); } else { _disks[number_of_disks] = {number_of_disks, disks::disk_type::ATA, &descriptor}; std::string name = "hd"; name += disk++; - devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, ata_driver, &descriptor); + devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, ata_driver, &_disks[number_of_disks]); char part = '1'; diff --git a/kernel/src/vfs/vfs.cpp b/kernel/src/vfs/vfs.cpp index bf4e7729..09837721 100644 --- a/kernel/src/vfs/vfs.cpp +++ b/kernel/src/vfs/vfs.cpp @@ -61,8 +61,8 @@ std::string partition_type_to_string(vfs::partition_type type){ std::vector mount_point_list; void mount_root(){ - //TODO Get information about the root from a confgiuration file - mount(vfs::partition_type::FAT32, "/", "TODO"); + //TODO Get information about the root from a configuration file + mount(vfs::partition_type::FAT32, "/", "/dev/hda1"); } void mount_sys(){ diff --git a/tlib/include/errors.hpp b/tlib/include/errors.hpp index dba6f018..8ea2afcf 100644 --- a/tlib/include/errors.hpp +++ b/tlib/include/errors.hpp @@ -28,6 +28,7 @@ constexpr const size_t ERROR_DISK_FULL = 12; constexpr const size_t ERROR_PERMISSION_DENIED = 13; constexpr const size_t ERROR_INVALID_OFFSET = 14; constexpr const size_t ERROR_UNSUPPORTED = 15; +constexpr const size_t ERROR_INVALID_COUNT = 16; inline const char* error_message(size_t error){ switch(error){ @@ -61,6 +62,8 @@ inline const char* error_message(size_t error){ return "The offset is not valid"; case ERROR_UNSUPPORTED: return "Unsupported operation: May not be implemented yet"; + case ERROR_INVALID_COUNT: + return "The count is not valid"; default: return "Unknonwn error"; }