diff --git a/Makefile b/Makefile index 424eeb13..804389c0 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ thor.flp: hdd.img bootloader/stage1.bin bootloader/stage2.bin kernel/kernel.bin sudo /bin/mount -t vfat /dev/loop0 mnt/fake/ sudo mkdir mnt/fake/bin/ sudo mkdir mnt/fake/sys/ + sudo mkdir mnt/fake/dev/ sudo /bin/cp kernel/kernel.bin mnt/fake/ sudo /bin/cp programs/dist/* mnt/fake/bin/ sleep 0.1 diff --git a/kernel/include/ata.hpp b/kernel/include/ata.hpp index 30805175..a0899fdf 100644 --- a/kernel/include/ata.hpp +++ b/kernel/include/ata.hpp @@ -11,6 +11,8 @@ #include #include +#include "fs/devfs.hpp" + namespace ata { struct drive_descriptor { @@ -31,6 +33,16 @@ drive_descriptor& drive(uint8_t disk); bool read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination); bool write_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* source); +struct ata_driver : devfs::dev_driver { + size_t read(void* data, char* buffer, size_t count, size_t offset, size_t& read); + size_t write(void* data, const char* buffer, size_t count, size_t offset, size_t& written); +}; + +struct ata_part_driver : devfs::dev_driver { + size_t read(void* data, char* buffer, size_t count, size_t offset, size_t& read); + size_t write(void* data, const char* buffer, size_t count, size_t offset, size_t& written); +}; + } #endif diff --git a/kernel/include/disks.hpp b/kernel/include/disks.hpp index c2dfb9a1..b60d9241 100644 --- a/kernel/include/disks.hpp +++ b/kernel/include/disks.hpp @@ -35,6 +35,7 @@ struct partition_descriptor { vfs::partition_type type; uint64_t start; uint64_t sectors; + disk_descriptor* disk; }; void detect_disks(); @@ -43,16 +44,15 @@ uint64_t detected_disks(); bool disk_exists(uint64_t uuid); -const disk_descriptor& disk_by_index(uint64_t index); -const disk_descriptor& disk_by_uuid(uint64_t uuid); +disk_descriptor& disk_by_index(uint64_t index); +disk_descriptor& disk_by_uuid(uint64_t uuid); const char* disk_type_to_string(disk_type type); const char* partition_type_to_string(vfs::partition_type type); bool read_sectors(const disk_descriptor& disk, uint64_t start, uint8_t count, void* destination); bool write_sectors(const disk_descriptor& disk, uint64_t start, uint8_t count, void* destination); -std::unique_heap_array partitions(const disk_descriptor& disk); -bool partition_exists(const disk_descriptor& disk, uint64_t uuid); +std::unique_heap_array partitions(disk_descriptor& disk); } diff --git a/kernel/src/ata.cpp b/kernel/src/ata.cpp index 54c7d3c3..3205e120 100644 --- a/kernel/src/ata.cpp +++ b/kernel/src/ata.cpp @@ -351,6 +351,22 @@ 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::write(void* data, const char* buffer, size_t count, size_t offset, size_t& written){ + //TODO +} + +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::write(void* data, const char* buffer, size_t count, size_t offset, size_t& written){ + //TODO +} + bool ata::read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination){ auto buffer = reinterpret_cast(destination); diff --git a/kernel/src/disks.cpp b/kernel/src/disks.cpp index f23b9fbe..f7e9802f 100644 --- a/kernel/src/disks.cpp +++ b/kernel/src/disks.cpp @@ -13,7 +13,8 @@ #include "ata.hpp" #include "thor.hpp" #include "console.hpp" -#include "fs/fat32.hpp" + +#include "fs/devfs.hpp" namespace { @@ -41,38 +42,63 @@ struct boot_record_t { static_assert(sizeof(boot_record_t) == 512, "The boot record is 512 bytes long"); -const disks::disk_descriptor* _mounted_disk; -const disks::partition_descriptor* _mounted_partition; +ata::ata_driver ata_driver_impl; +ata::ata_part_driver ata_part_driver_impl; -std::vector pwd; +devfs::dev_driver* ata_driver = &ata_driver_impl; +devfs::dev_driver* ata_part_driver = &ata_part_driver_impl; +devfs::dev_driver* atapi_driver = nullptr; } //end of anonymous namespace void disks::detect_disks(){ ata::detect_disks(); + char cdrom = 'a'; + char disk = 'a'; + for(uint8_t i = 0; i < ata::number_of_disks(); ++i){ auto& descriptor = ata::drive(i); if(descriptor.present){ - _disks[number_of_disks] = {number_of_disks, descriptor.atapi ? disks::disk_type::ATAPI : disks::disk_type::ATA, &descriptor}; + if(descriptor.atapi){ + _disks[number_of_disks] = {number_of_disks, disks::disk_type::ATAPI, &descriptor}; + + std::string name = "cd"; + name += cdrom++; + + devfs::register_device("/dev/", name, devfs::device_type::BLOCK_DEVICE, atapi_driver, &descriptor); + } 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); + + char part = '1'; + + for(auto& partition : partitions(_disks[number_of_disks])){ + auto part_name = name + part++; + + devfs::register_device("/dev/", part_name, devfs::device_type::BLOCK_DEVICE, ata_part_driver, new partition_descriptor(partition)); + } + } + ++number_of_disks; } } - - _mounted_disk = nullptr; - _mounted_partition = nullptr; } uint64_t disks::detected_disks(){ return number_of_disks; } -const disks::disk_descriptor& disks::disk_by_index(uint64_t index){ +disks::disk_descriptor& disks::disk_by_index(uint64_t index){ return _disks[index]; } -const disks::disk_descriptor& disks::disk_by_uuid(uint64_t uuid){ +disks::disk_descriptor& disks::disk_by_uuid(uint64_t uuid){ for(uint64_t i = 0; i < number_of_disks; ++i){ if(_disks[i].uuid == uuid){ return _disks[i]; @@ -134,7 +160,7 @@ bool disks::write_sectors(const disk_descriptor& disk, uint64_t start, uint8_t c } } -std::unique_heap_array disks::partitions(const disk_descriptor& disk){ +std::unique_heap_array disks::partitions(disk_descriptor& disk){ std::unique_ptr boot_record(new boot_record_t()); if(!read_sectors(disk, 0, 1, boot_record.get())){ @@ -167,7 +193,7 @@ std::unique_heap_array disks::partitions(const disk type = vfs::partition_type::UNKNOWN; } - partitions[p] = {p, type, boot_record->partitions[i].lba_begin, boot_record->partitions[i].sectors}; + partitions[p] = {p, type, boot_record->partitions[i].lba_begin, boot_record->partitions[i].sectors, &disk}; ++p; } @@ -176,13 +202,3 @@ std::unique_heap_array disks::partitions(const disk return partitions; } } - -bool disks::partition_exists(const disk_descriptor& disk, uint64_t uuid){ - for(auto& partition : partitions(disk)){ - if(partition.uuid == uuid){ - return true; - } - } - - return false; -} diff --git a/kernel/src/fs/devfs.cpp b/kernel/src/fs/devfs.cpp index ec36d784..8328df53 100644 --- a/kernel/src/fs/devfs.cpp +++ b/kernel/src/fs/devfs.cpp @@ -92,6 +92,10 @@ size_t devfs::devfs_file_system::read(const std::vector& file_path, if(device_list.name == mount_point){ for(auto& device : device_list.devices){ if(device.name == file_path.back()){ + if(!device.driver){ + return std::ERROR_UNSUPPORTED; + } + return device.driver->read(device.data, buffer, count, offset, read); } } @@ -111,6 +115,10 @@ size_t devfs::devfs_file_system::write(const std::vector& file_path if(device_list.name == mount_point){ for(auto& device : device_list.devices){ if(device.name == file_path.back()){ + if(!device.driver){ + return std::ERROR_UNSUPPORTED; + } + return device.driver->write(device.data, buffer, count, offset, written); } } diff --git a/kernel/src/fs/fat32.cpp b/kernel/src/fs/fat32.cpp index 304a89a6..a2f7758f 100644 --- a/kernel/src/fs/fat32.cpp +++ b/kernel/src/fs/fat32.cpp @@ -171,7 +171,7 @@ void init_file_entry(fat32::cluster_entry* entry_ptr, const char* name, uint32_t } //end of anonymous namespace fat32::fat32_file_system::fat32_file_system(size_t disk_uuid, size_t partition_uuid) : disk(disks::disk_by_uuid(disk_uuid)) { - for(auto& p : partitions(disk)){ + for(auto& p : partitions(disks::disk_by_uuid(disk_uuid))){ if(p.uuid == partition_uuid){ partition = p; break; diff --git a/kernel/src/fs/sysfs.cpp b/kernel/src/fs/sysfs.cpp index c0e07fd1..7f164eb6 100644 --- a/kernel/src/fs/sysfs.cpp +++ b/kernel/src/fs/sysfs.cpp @@ -281,7 +281,7 @@ size_t sysfs::sysfs_file_system::write(const std::vector&, const ch return std::ERROR_PERMISSION_DENIED; } -size_t sysfs::sysfs_file_system::truncate(const std::vector& file_path, size_t size){ +size_t sysfs::sysfs_file_system::truncate(const std::vector&, size_t){ return std::ERROR_PERMISSION_DENIED; } diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index 5aa7c933..1c13abf8 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -47,7 +47,6 @@ bool shift = false; //Declarations of the different functions void disks_command(const std::vector& params); -void partitions_command(const std::vector& params); void exec_command(const std::vector& params); struct command_definition { @@ -55,9 +54,8 @@ struct command_definition { void (*function)(const std::vector&); }; -command_definition commands[3] = { +command_definition commands[2] = { {"disks", disks_command}, - {"partitions", partitions_command}, {"exec", exec_command}, }; @@ -208,32 +206,6 @@ void disks_command(const std::vector& params){ } } -void partitions_command(const std::vector& params){ - auto uuid = parse(params[1]); - - if(disks::disk_exists(uuid)){ - auto& disk = disks::disk_by_uuid(uuid); - - if(disk.type != disks::disk_type::ATA){ - k_print_line("Only ATA disks are supported"); - } else { - auto partitions = disks::partitions(disk); - - if(partitions.size() > 0){ - k_print_line("UUID Type Start Sectors"); - - for(auto& partition : partitions){ - k_printf("%10d %12s %10d %u\n", partition.uuid, - disks::partition_type_to_string(partition.type), - partition.start, partition.sectors); - } - } - } - } else { - k_printf("Disks %u does not exist\n", uuid); - } -} - void exec_command(const std::vector&){ //Fake exec just to start() the scheduler std::vector params; diff --git a/tlib/include/errors.hpp b/tlib/include/errors.hpp index ea11ba1b..dba6f018 100644 --- a/tlib/include/errors.hpp +++ b/tlib/include/errors.hpp @@ -27,6 +27,7 @@ constexpr const size_t ERROR_INVALID_FILE_SYSTEM = 11; 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; inline const char* error_message(size_t error){ switch(error){ @@ -58,6 +59,8 @@ inline const char* error_message(size_t error){ return "Permission denied"; case ERROR_INVALID_OFFSET: return "The offset is not valid"; + case ERROR_UNSUPPORTED: + return "Unsupported operation: May not be implemented yet"; default: return "Unknonwn error"; }