diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 386fce4952..1bfaec8160 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -15,9 +15,9 @@ set(KERNEL_SOURCES kernel/CPUID.cpp kernel/Debug.cpp kernel/Device.cpp - kernel/DeviceManager.cpp kernel/Errors.cpp kernel/Font.cpp + kernel/FS/DevFS/FileSystem.cpp kernel/FS/Ext2.cpp kernel/FS/Inode.cpp kernel/FS/Pipe.cpp diff --git a/kernel/include/kernel/Device.h b/kernel/include/kernel/Device.h index 37b3dba9b0..7a2a0f9b55 100644 --- a/kernel/include/kernel/Device.h +++ b/kernel/include/kernel/Device.h @@ -1,53 +1,41 @@ #pragma once -#include +#include namespace Kernel { - class Device : public Inode + class Device : public RamInode { public: - Device(); - virtual ~Device() {} + Device(mode_t, uid_t, gid_t); + virtual ~Device() = default; virtual void update() {} virtual bool is_device() const override { return true; } - virtual bool is_partition() const { return false; } - virtual ino_t ino() const override { return m_ino_t; } - virtual nlink_t nlink() const override { return 1; } - virtual off_t size() const override { return 0; } - virtual timespec atime() const override { return m_create_time; } - virtual timespec mtime() const override { return m_create_time; } - virtual timespec ctime() const override { return m_create_time; } - virtual blksize_t blksize() const override { return DeviceManager::get().blksize(); } - virtual blkcnt_t blocks() const override { return DeviceManager::get().blocks(); } - virtual dev_t dev() const override { return DeviceManager::get().dev(); } - - /* - a device has to overload - virtual Mode mode() const; - virtual uid_t uid() const; - virtual gid_t gid() const; - virtual dev_t rdev() const; - virtual BAN::StringView name() const; - */ - - private: - const timespec m_create_time; - const ino_t m_ino_t; + virtual dev_t rdev() const override = 0; }; class BlockDevice : public Device { public: + BlockDevice(mode_t mode, uid_t uid, gid_t gid) + : Device(Mode::IFBLK | mode, uid, gid) + { + ASSERT(Device::mode().ifblk()); + } }; class CharacterDevice : public Device { public: + CharacterDevice(mode_t mode, uid_t uid, gid_t gid) + : Device(Mode::IFCHR | mode, uid, gid) + { + ASSERT(Device::mode().ifchr()); + } }; } \ No newline at end of file diff --git a/kernel/include/kernel/DeviceManager.h b/kernel/include/kernel/DeviceManager.h deleted file mode 100644 index e9914d491e..0000000000 --- a/kernel/include/kernel/DeviceManager.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace Kernel -{ - - class Device; - - class DeviceManager final : public FileSystem, public Inode - { - BAN_NON_COPYABLE(DeviceManager); - BAN_NON_MOVABLE(DeviceManager); - - public: - static DeviceManager& get(); - - void initialize_pci_devices(); - void initialize_updater(); - - ino_t get_next_ino() const; - dev_t get_next_rdev() const; - uint8_t get_next_input_dev() const; - - void update(); - void add_device(Device*); - - virtual BAN::RefPtr root_inode() override { return this; } - - virtual BAN::StringView name() const override { return "device-manager"; } - - virtual BAN::ErrorOr> directory_find_inode(BAN::StringView) override; - virtual BAN::ErrorOr directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override; - - private: - DeviceManager() = default; - - private: - SpinLock m_lock; - BAN::Vector m_devices; - - friend class BAN::RefPtr; - - public: - virtual ino_t ino() const override { return 0; } - virtual Mode mode() const override { return { Mode::IFDIR | Mode::IRUSR | Mode::IWUSR | Mode::IXUSR | Mode::IRGRP | Mode::IXGRP | Mode::IROTH | Mode::IXOTH }; } - virtual nlink_t nlink() const override { return 1; } - virtual uid_t uid() const override { return 0; } - virtual gid_t gid() const override { return 0; } - virtual off_t size() const override { return 0; } - virtual timespec atime() const override { return { 0, 0 }; } - virtual timespec mtime() const override { return { 0, 0 }; } - virtual timespec ctime() const override { return { 0, 0 }; } - virtual blksize_t blksize() const override { ASSERT(m_blksize); return m_blksize; } - virtual blkcnt_t blocks() const override { return 0; } - virtual dev_t dev() const override { return makedev(0, 5); } - virtual dev_t rdev() const override { return 0; } - - virtual BAN::ErrorOr read(size_t, void*, size_t) { return BAN::Error::from_errno(EISDIR); } - virtual BAN::ErrorOr create_file(BAN::StringView, mode_t) { return BAN::Error::from_errno(ENOTSUP); } - - void set_blksize(blksize_t blksize) { m_blksize = blksize; } - - private: - blksize_t m_blksize = 0; - }; - -} \ No newline at end of file diff --git a/kernel/include/kernel/FS/DevFS/FileSystem.h b/kernel/include/kernel/FS/DevFS/FileSystem.h new file mode 100644 index 0000000000..232810c3e1 --- /dev/null +++ b/kernel/include/kernel/FS/DevFS/FileSystem.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +namespace Kernel +{ + + class DevFileSystem final : public RamFileSystem + { + public: + static void initialize(); + static DevFileSystem& get(); + + void initialize_device_updater(); + + void add_device(BAN::StringView path, BAN::RefPtr); + + dev_t get_next_rdev(); + + private: + DevFileSystem(size_t size) + : RamFileSystem(size) + { } + + private: + SpinLock m_device_lock; + }; + +} \ No newline at end of file diff --git a/kernel/include/kernel/FS/Ext2.h b/kernel/include/kernel/FS/Ext2.h index e511ea210b..d702b7a080 100644 --- a/kernel/include/kernel/FS/Ext2.h +++ b/kernel/include/kernel/FS/Ext2.h @@ -137,8 +137,6 @@ namespace Kernel virtual dev_t dev() const override { return 0; } virtual dev_t rdev() const override { return 0; } - virtual BAN::StringView name() const override { return m_name; } - virtual BAN::ErrorOr link_target() override; virtual BAN::ErrorOr directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override; diff --git a/kernel/include/kernel/FS/Inode.h b/kernel/include/kernel/FS/Inode.h index eafdd99f5d..6c63d7328c 100644 --- a/kernel/include/kernel/FS/Inode.h +++ b/kernel/include/kernel/FS/Inode.h @@ -78,8 +78,6 @@ namespace Kernel virtual bool is_device() const { return false; } virtual bool is_pipe() const { return false; } - virtual BAN::StringView name() const = 0; - virtual BAN::ErrorOr link_target() { ASSERT_NOT_REACHED(); } virtual BAN::ErrorOr> directory_find_inode(BAN::StringView) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); } diff --git a/kernel/include/kernel/FS/Pipe.h b/kernel/include/kernel/FS/Pipe.h index 6dfa880da6..3c05d08dd0 100644 --- a/kernel/include/kernel/FS/Pipe.h +++ b/kernel/include/kernel/FS/Pipe.h @@ -30,8 +30,6 @@ namespace Kernel virtual dev_t dev() const override { return 0; } // FIXME virtual dev_t rdev() const override { return 0; } // FIXME - virtual BAN::StringView name() const override { return ""sv; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; virtual BAN::ErrorOr write(size_t, const void*, size_t) override; diff --git a/kernel/include/kernel/FS/RamFS/FileSystem.h b/kernel/include/kernel/FS/RamFS/FileSystem.h index eb40c7ccc8..2b46c7d63e 100644 --- a/kernel/include/kernel/FS/RamFS/FileSystem.h +++ b/kernel/include/kernel/FS/RamFS/FileSystem.h @@ -8,13 +8,15 @@ namespace Kernel { class RamInode; + class RamDirectoryInode; - class RamFileSystem final : public FileSystem + class RamFileSystem : public FileSystem { public: static BAN::ErrorOr create(size_t size, mode_t, uid_t, gid_t); - ~RamFileSystem() = default; + virtual ~RamFileSystem() = default; + BAN::ErrorOr set_root_inode(BAN::RefPtr); virtual BAN::RefPtr root_inode() override { return m_inodes[m_root_inode]; } BAN::ErrorOr add_inode(BAN::RefPtr); @@ -23,15 +25,19 @@ namespace Kernel blksize_t blksize() const { return m_blksize; } ino_t next_ino() { return m_next_ino++; } - private: - RamFileSystem() = default; + void for_each_inode(void (*callback)(BAN::RefPtr)); + + protected: + RamFileSystem(size_t size) + : m_size(size) + { } private: - SpinLock m_lock; + RecursiveSpinLock m_lock; size_t m_size { 0 }; BAN::HashMap> m_inodes; - ino_t m_root_inode; + ino_t m_root_inode { 0 }; const blksize_t m_blksize = PAGE_SIZE; ino_t m_next_ino { 1 }; diff --git a/kernel/include/kernel/FS/RamFS/Inode.h b/kernel/include/kernel/FS/RamFS/Inode.h index 0b78b85fa7..2ff11efe35 100644 --- a/kernel/include/kernel/FS/RamFS/Inode.h +++ b/kernel/include/kernel/FS/RamFS/Inode.h @@ -12,6 +12,7 @@ namespace Kernel class RamInode : public Inode { public: + static BAN::ErrorOr> create(RamFileSystem&, mode_t, uid_t, gid_t); virtual ~RamInode() = default; virtual ino_t ino() const override { return m_inode_info.ino; } @@ -28,8 +29,6 @@ namespace Kernel virtual dev_t dev() const override { return m_inode_info.dev; } virtual dev_t rdev() const override { return m_inode_info.rdev; } - virtual BAN::StringView name() const override { ASSERT_NOT_REACHED(); } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; virtual BAN::ErrorOr write(size_t, const void*, size_t) override; @@ -39,7 +38,6 @@ namespace Kernel protected: RamInode(RamFileSystem& fs, mode_t, uid_t, gid_t); - static BAN::ErrorOr> create(RamFileSystem&, mode_t, uid_t, gid_t); protected: struct FullInodeInfo @@ -71,15 +69,17 @@ namespace Kernel class RamDirectoryInode final : public RamInode { public: + static BAN::ErrorOr> create(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t); ~RamDirectoryInode() = default; virtual BAN::ErrorOr> directory_find_inode(BAN::StringView) override; virtual BAN::ErrorOr directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override; virtual BAN::ErrorOr create_file(BAN::StringView, mode_t, uid_t, gid_t) override; + + BAN::ErrorOr add_inode(BAN::StringView, BAN::RefPtr); private: RamDirectoryInode(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t); - static BAN::ErrorOr> create(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t); private: static constexpr size_t m_name_max = NAME_MAX; diff --git a/kernel/include/kernel/Input/PS2Controller.h b/kernel/include/kernel/Input/PS2Controller.h index ae2036ff9f..5c4e149586 100644 --- a/kernel/include/kernel/Input/PS2Controller.h +++ b/kernel/include/kernel/Input/PS2Controller.h @@ -12,9 +12,9 @@ namespace Kernel::Input virtual void on_byte(uint8_t) = 0; public: - virtual Mode mode() const override { return { Mode::IFCHR | Mode::IRUSR | Mode::IRGRP }; } - virtual uid_t uid() const override { return 0; } - virtual gid_t gid() const override { return 0; } + PS2Device() + : CharacterDevice(Mode::IRUSR | Mode::IRGRP, 0, 0) + { } }; class PS2Controller diff --git a/kernel/include/kernel/Input/PS2Keyboard.h b/kernel/include/kernel/Input/PS2Keyboard.h index cf64ad7d98..b9a86e0c7a 100644 --- a/kernel/include/kernel/Input/PS2Keyboard.h +++ b/kernel/include/kernel/Input/PS2Keyboard.h @@ -60,13 +60,10 @@ namespace Kernel::Input Semaphore m_semaphore; public: - virtual BAN::StringView name() const override { return m_name; } virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; private: - const BAN::String m_name; const dev_t m_rdev; }; diff --git a/kernel/include/kernel/PCI.h b/kernel/include/kernel/PCI.h index 7cbba22f0a..78cccef436 100644 --- a/kernel/include/kernel/PCI.h +++ b/kernel/include/kernel/PCI.h @@ -60,6 +60,7 @@ namespace Kernel void check_device(uint8_t bus, uint8_t dev); void check_bus(uint8_t bus); void check_all_buses(); + void initialize_devices(); private: BAN::Vector m_devices; diff --git a/kernel/include/kernel/Storage/ATABus.h b/kernel/include/kernel/Storage/ATABus.h index baf83bb8a5..d9aa4a0480 100644 --- a/kernel/include/kernel/Storage/ATABus.h +++ b/kernel/include/kernel/Storage/ATABus.h @@ -20,28 +20,28 @@ namespace Kernel }; public: - static ATABus* create(ATAController*, uint16_t base, uint16_t ctrl, uint8_t irq); + static ATABus* create(ATAController&, uint16_t base, uint16_t ctrl, uint8_t irq); - BAN::ErrorOr read(ATADevice*, uint64_t, uint8_t, uint8_t*); - BAN::ErrorOr write(ATADevice*, uint64_t, uint8_t, const uint8_t*); + BAN::ErrorOr read(ATADevice&, uint64_t, uint8_t, uint8_t*); + BAN::ErrorOr write(ATADevice&, uint64_t, uint8_t, const uint8_t*); - ATAController* controller() { return m_controller; } + ATAController& controller() { return m_controller; } void on_irq(); private: - ATABus(ATAController* controller, uint16_t base, uint16_t ctrl) + ATABus(ATAController& controller, uint16_t base, uint16_t ctrl) : m_controller(controller) , m_base(base) , m_ctrl(ctrl) {} void initialize(uint8_t irq); - void select_device(const ATADevice*); - DeviceType identify(const ATADevice*, uint16_t*); + void select_device(const ATADevice&); + DeviceType identify(const ATADevice&, uint16_t*); void block_until_irq(); - uint8_t device_index(const ATADevice*) const; + uint8_t device_index(const ATADevice&) const; uint8_t io_read(uint16_t); void io_write(uint16_t, uint8_t); @@ -51,14 +51,14 @@ namespace Kernel BAN::Error error(); private: - ATAController* m_controller; + ATAController& m_controller; const uint16_t m_base; const uint16_t m_ctrl; SpinLock m_lock; bool m_has_got_irq { false }; - ATADevice* m_devices[2] { nullptr, nullptr }; + BAN::RefPtr m_devices[2] {}; friend class ATAController; }; diff --git a/kernel/include/kernel/Storage/ATAController.h b/kernel/include/kernel/Storage/ATAController.h index 649ae42d16..a79796db18 100644 --- a/kernel/include/kernel/Storage/ATAController.h +++ b/kernel/include/kernel/Storage/ATAController.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -13,16 +12,12 @@ namespace Kernel class ATAController final : public StorageController { public: - static BAN::ErrorOr create(const PCIDevice&); + static BAN::ErrorOr> create(const PCIDevice&); - virtual BAN::Vector devices() override; - - uint8_t next_device_index() const; + virtual BAN::Vector> devices() override; private: - ATAController() - : m_rdev(makedev(DeviceManager::get().get_next_rdev(), 0)) - { } + ATAController(); BAN::ErrorOr initialize(const PCIDevice& device); private: @@ -35,8 +30,6 @@ namespace Kernel virtual gid_t gid() const override { return 0; } virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::StringView name() const override { return "hd"sv; } - virtual BAN::ErrorOr read(size_t, void*, size_t) { return BAN::Error::from_errno(ENOTSUP); } private: diff --git a/kernel/include/kernel/Storage/ATADevice.h b/kernel/include/kernel/Storage/ATADevice.h index 6c6a166c58..3fcf2cd9bc 100644 --- a/kernel/include/kernel/Storage/ATADevice.h +++ b/kernel/include/kernel/Storage/ATADevice.h @@ -9,10 +9,7 @@ namespace Kernel class ATADevice final : public StorageDevice { public: - ATADevice(ATABus* bus) - : m_bus(bus) - , m_rdev(makedev(DeviceManager::get().get_next_rdev(), 0)) - { } + ATADevice(ATABus&); BAN::ErrorOr initialize(ATABus::DeviceType, const uint16_t*); virtual uint32_t sector_size() const override { return m_sector_words * 2; } @@ -25,7 +22,7 @@ namespace Kernel virtual BAN::ErrorOr write_sectors_impl(uint64_t, uint8_t, const uint8_t*) override; private: - ATABus* m_bus; + ATABus& m_bus; uint8_t m_index; ATABus::DeviceType m_type; @@ -44,13 +41,10 @@ namespace Kernel virtual gid_t gid() const override { return 0; } virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::StringView name() const override { return BAN::StringView(m_device_name, sizeof(m_device_name) - 1); } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; public: const dev_t m_rdev; - char m_device_name[4] {}; }; } \ No newline at end of file diff --git a/kernel/include/kernel/Storage/StorageController.h b/kernel/include/kernel/Storage/StorageController.h index ce46c16126..2e56896654 100644 --- a/kernel/include/kernel/Storage/StorageController.h +++ b/kernel/include/kernel/Storage/StorageController.h @@ -8,7 +8,10 @@ namespace Kernel class StorageController : public CharacterDevice { public: - virtual BAN::Vector devices() = 0; + StorageController() + : CharacterDevice(0660, 0, 0) + { } + virtual BAN::Vector> devices() = 0; }; } \ No newline at end of file diff --git a/kernel/include/kernel/Storage/StorageDevice.h b/kernel/include/kernel/Storage/StorageDevice.h index 36e24d6b50..0b3f77f561 100644 --- a/kernel/include/kernel/Storage/StorageDevice.h +++ b/kernel/include/kernel/Storage/StorageDevice.h @@ -48,20 +48,20 @@ namespace Kernel virtual Mode mode() const override { return { Mode::IFBLK | Mode::IRUSR | Mode::IRGRP }; } virtual uid_t uid() const override { return 0; } virtual gid_t gid() const override { return 0; } - virtual dev_t rdev() const override; - - virtual BAN::StringView name() const override { return m_device_name; } + virtual dev_t rdev() const override { return m_rdev; } virtual BAN::ErrorOr read(size_t, void*, size_t) override; - + private: - const uint32_t m_index; - BAN::String m_device_name; + const dev_t m_rdev; }; class StorageDevice : public BlockDevice { public: + StorageDevice() + : BlockDevice(0660, 0, 0) + { } virtual ~StorageDevice(); BAN::ErrorOr initialize_partitions(); @@ -74,7 +74,7 @@ namespace Kernel BAN::Vector& partitions() { return m_partitions; } const BAN::Vector& partitions() const { return m_partitions; } - + protected: virtual BAN::ErrorOr read_sectors_impl(uint64_t lba, uint8_t sector_count, uint8_t* buffer) = 0; virtual BAN::ErrorOr write_sectors_impl(uint64_t lba, uint8_t sector_count, const uint8_t* buffer) = 0; diff --git a/kernel/include/kernel/Terminal/TTY.h b/kernel/include/kernel/Terminal/TTY.h index 0dfb6e6b4b..0176cadf09 100644 --- a/kernel/include/kernel/Terminal/TTY.h +++ b/kernel/include/kernel/Terminal/TTY.h @@ -113,11 +113,9 @@ namespace Kernel virtual uid_t uid() const override { return 0; } virtual gid_t gid() const override { return 0; } virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::StringView name() const { return m_name; } private: dev_t m_rdev; - BAN::String m_name; }; } diff --git a/kernel/kernel/Device.cpp b/kernel/kernel/Device.cpp index 38fea26523..d35250622a 100644 --- a/kernel/kernel/Device.cpp +++ b/kernel/kernel/Device.cpp @@ -1,13 +1,11 @@ -#include #include -#include +#include namespace Kernel { - Device::Device() - : m_create_time({ BAN::to_unix_time(RTC::get_current_time()), 0 }) - , m_ino_t(DeviceManager::get().get_next_ino()) + Device::Device(mode_t mode, uid_t uid, gid_t gid) + : RamInode(DevFileSystem::get(), mode, uid, gid) { } } \ No newline at end of file diff --git a/kernel/kernel/DeviceManager.cpp b/kernel/kernel/DeviceManager.cpp deleted file mode 100644 index 81b9e4545a..0000000000 --- a/kernel/kernel/DeviceManager.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include -#include -#include - -namespace Kernel -{ - - DeviceManager& DeviceManager::get() - { - static DeviceManager instance; - return instance; - } - - void DeviceManager::initialize_pci_devices() - { - for (const auto& pci_device : PCI::get().devices()) - { - switch (pci_device.class_code()) - { - case 0x01: - { - StorageController* controller = nullptr; - switch (pci_device.subclass()) - { - case 0x01: - if (auto res = ATAController::create(pci_device); res.is_error()) - dprintln("{}", res.error()); - else - controller = res.value(); - break; - default: - dprintln("unsupported storage device (pci {2H}.{2H}.{2H})", pci_device.class_code(), pci_device.subclass(), pci_device.prog_if()); - break; - } - - if (controller) - { - add_device(controller); - for (auto* device : controller->devices()) - { - add_device(device); - if (auto res = device->initialize_partitions(); res.is_error()) - dprintln("{}", res.error()); - else - { - for (auto* partition : device->partitions()) - add_device(partition); - } - } - } - break; - } - default: - break; - } - } - } - - void DeviceManager::initialize_updater() - { - Process::create_kernel( - [](void*) - { - while (true) - { - DeviceManager::get().update(); - PIT::sleep(1); - } - }, nullptr - ); - } - - ino_t DeviceManager::get_next_ino() const - { - static ino_t next_ino = 1; - return next_ino++; - } - - dev_t DeviceManager::get_next_rdev() const - { - static dev_t next_dev = 1; - return next_dev++; - } - - uint8_t DeviceManager::get_next_input_dev() const - { - static uint8_t next_dev = 0; - return next_dev++; - } - - void DeviceManager::update() - { - LockGuard _(m_lock); - for (Device* device : m_devices) - device->update(); - } - - void DeviceManager::add_device(Device* device) - { - LockGuard _(m_lock); - MUST(m_devices.push_back(device)); - } - - BAN::ErrorOr> DeviceManager::directory_find_inode(BAN::StringView name) - { - LockGuard _(m_lock); - if (name == "."sv || name == ".."sv) - return BAN::RefPtr(this); - for (Device* device : m_devices) - if (device->name() == name) - return BAN::RefPtr(device); - return BAN::Error::from_errno(ENOENT); - } - - BAN::ErrorOr DeviceManager::directory_read_next_entries(off_t offset, DirectoryEntryList* list, size_t list_size) - { - if (offset != 0) - { - list->entry_count = 0; - return {}; - } - - LockGuard _(m_lock); - - size_t needed_size = sizeof(DirectoryEntryList); - needed_size += sizeof(DirectoryEntry) + 2; - needed_size += sizeof(DirectoryEntry) + 3; - for (Device* device : m_devices) - needed_size += sizeof(DirectoryEntry) + device->name().size() + 1; - if (needed_size > list_size) - return BAN::Error::from_errno(EINVAL); - - DirectoryEntry* ptr = list->array; - - ptr->dirent.d_ino = ino(); - ptr->rec_len = sizeof(DirectoryEntry) + 2; - memcpy(ptr->dirent.d_name, ".", 2); - ptr = ptr->next(); - - ptr->dirent.d_ino = 69; // FIXME: store parent inode number when we implement proper RAM fs - ptr->rec_len = sizeof(DirectoryEntry) + 3; - memcpy(ptr->dirent.d_name, "..", 3); - ptr = ptr->next(); - - for (Device* device : m_devices) - { - ptr->dirent.d_ino = device->ino(); - ptr->rec_len = sizeof(DirectoryEntry) + device->name().size() + 1; - memcpy(ptr->dirent.d_name, device->name().data(), device->name().size()); - ptr->dirent.d_name[device->name().size()] = '\0'; - - ptr = ptr->next(); - } - - list->entry_count = m_devices.size() + 2; - - return {}; - } - - -} \ No newline at end of file diff --git a/kernel/kernel/FS/DevFS/FileSystem.cpp b/kernel/kernel/FS/DevFS/FileSystem.cpp new file mode 100644 index 0000000000..c8b0b1cd10 --- /dev/null +++ b/kernel/kernel/FS/DevFS/FileSystem.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +namespace Kernel +{ + + static DevFileSystem* s_instance = nullptr; + + void DevFileSystem::initialize() + { + ASSERT(s_instance == nullptr); + s_instance = new DevFileSystem(1024 * 1024); + ASSERT(s_instance); + + auto root_inode = MUST(RamDirectoryInode::create(*s_instance, 0, Inode::Mode::IFDIR | 0755, 0, 0)); + MUST(s_instance->set_root_inode(root_inode)); + } + + DevFileSystem& DevFileSystem::get() + { + ASSERT(s_instance); + return *s_instance; + } + + void DevFileSystem::initialize_device_updater() + { + Process::create_kernel( + [](void*) + { + while (true) + { + s_instance->m_device_lock.lock(); + s_instance->for_each_inode( + [](BAN::RefPtr inode) + { + if (inode->is_device()) + ((Device*)inode.ptr())->update(); + } + ); + s_instance->m_device_lock.unlock(); + + PIT::sleep(1); + } + }, nullptr + ); + } + + void DevFileSystem::add_device(BAN::StringView path, BAN::RefPtr device) + { + ASSERT(!path.contains('/')); + MUST(reinterpret_cast(root_inode().ptr())->add_inode(path, device)); + } + + dev_t DevFileSystem::get_next_rdev() + { + static dev_t next_rdev = 1; + return next_rdev++; + } + +} \ No newline at end of file diff --git a/kernel/kernel/FS/RamFS/FileSystem.cpp b/kernel/kernel/FS/RamFS/FileSystem.cpp index 010ea2550a..c6fa9ed508 100644 --- a/kernel/kernel/FS/RamFS/FileSystem.cpp +++ b/kernel/kernel/FS/RamFS/FileSystem.cpp @@ -9,22 +9,29 @@ namespace Kernel BAN::ErrorOr RamFileSystem::create(size_t size, mode_t mode, uid_t uid, gid_t gid) { - auto* ramfs = new RamFileSystem; + auto* ramfs = new RamFileSystem(size); if (ramfs == nullptr) return BAN::Error::from_errno(ENOMEM); - ramfs->m_size = size; BAN::ScopeGuard deleter([ramfs] { delete ramfs; }); auto root_inode = TRY(RamDirectoryInode::create(*ramfs, 0, mode, uid, gid)); - TRY(ramfs->add_inode(root_inode)); - ramfs->m_root_inode = root_inode->ino(); + TRY(ramfs->set_root_inode(root_inode));; deleter.disable(); return ramfs; } + BAN::ErrorOr RamFileSystem::set_root_inode(BAN::RefPtr root_inode) + { + LockGuard _(m_lock); + ASSERT(m_root_inode == 0); + TRY(add_inode(root_inode)); + m_root_inode = root_inode->ino(); + return {}; + } + BAN::ErrorOr RamFileSystem::add_inode(BAN::RefPtr inode) { LockGuard _(m_lock); @@ -42,4 +49,11 @@ namespace Kernel return m_inodes[ino]; } + void RamFileSystem::for_each_inode(void (*callback)(BAN::RefPtr)) + { + LockGuard _(m_lock); + for (auto& [_, inode] : m_inodes) + callback(inode); + } + } \ No newline at end of file diff --git a/kernel/kernel/FS/RamFS/Inode.cpp b/kernel/kernel/FS/RamFS/Inode.cpp index 9009871ea5..5471d3218f 100644 --- a/kernel/kernel/FS/RamFS/Inode.cpp +++ b/kernel/kernel/FS/RamFS/Inode.cpp @@ -180,13 +180,6 @@ namespace Kernel BAN::ErrorOr RamDirectoryInode::create_file(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid) { - if (name.size() > m_name_max) - return BAN::Error::from_errno(ENAMETOOLONG); - - for (auto& entry : m_entries) - if (name == entry.name) - return BAN::Error::from_errno(EEXIST); - BAN::RefPtr inode; if (Mode{ mode }.ifreg()) inode = TRY(RamInode::create(m_fs, mode, uid, gid)); @@ -195,6 +188,20 @@ namespace Kernel else ASSERT_NOT_REACHED(); + TRY(add_inode(name, inode)); + + return {}; + } + + BAN::ErrorOr RamDirectoryInode::add_inode(BAN::StringView name, BAN::RefPtr inode) + { + if (name.size() > m_name_max) + return BAN::Error::from_errno(ENAMETOOLONG); + + for (auto& entry : m_entries) + if (name == entry.name) + return BAN::Error::from_errno(EEXIST); + TRY(m_entries.push_back({ })); Entry& entry = m_entries.back(); strcpy(entry.name, name.data()); diff --git a/kernel/kernel/FS/VirtualFileSystem.cpp b/kernel/kernel/FS/VirtualFileSystem.cpp index 35e5a2f9f7..f1189d5387 100644 --- a/kernel/kernel/FS/VirtualFileSystem.cpp +++ b/kernel/kernel/FS/VirtualFileSystem.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -22,13 +22,11 @@ namespace Kernel ASSERT(root.size() >= 5 && root.substring(0, 5) == "/dev/"sv);; root = root.substring(5); - auto partition_inode = MUST(DeviceManager::get().directory_find_inode(root)); + auto partition_inode = MUST(DevFileSystem::get().root_inode()->directory_find_inode(root)); s_instance->m_root_fs = MUST(Ext2FS::create(*(Partition*)partition_inode.ptr())); Credentials root_creds { 0, 0, 0, 0 }; - - DeviceManager::get().set_blksize(s_instance->m_root_fs->root_inode()->blksize()); - MUST(s_instance->mount(root_creds, &DeviceManager::get(), "/dev")); + MUST(s_instance->mount(root_creds, &DevFileSystem::get(), "/dev")); mode_t tmpfs_mode = Inode::Mode::IFDIR | Inode::Mode::IRUSR | Inode::Mode::IWUSR | Inode::Mode::IXUSR diff --git a/kernel/kernel/Input/PS2Controller.cpp b/kernel/kernel/Input/PS2Controller.cpp index 30608694c2..8a6cf088a8 100644 --- a/kernel/kernel/Input/PS2Controller.cpp +++ b/kernel/kernel/Input/PS2Controller.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -258,14 +258,14 @@ namespace Kernel::Input IDT::register_irq_handler(PS2::IRQ::DEVICE0, device0_irq); InterruptController::get().enable_irq(PS2::IRQ::DEVICE0); config |= PS2::Config::INTERRUPT_FIRST_PORT; - DeviceManager::get().add_device(m_devices[0]); + DevFileSystem::get().add_device("input0", m_devices[0]); } if (m_devices[1]) { IDT::register_irq_handler(PS2::IRQ::DEVICE1, device1_irq); InterruptController::get().enable_irq(PS2::IRQ::DEVICE1); config |= PS2::Config::INTERRUPT_SECOND_PORT; - DeviceManager::get().add_device(m_devices[1]); + DevFileSystem::get().add_device("input1", m_devices[1]); } controller_send_command(PS2::Command::WRITE_CONFIG, config); diff --git a/kernel/kernel/Input/PS2Keyboard.cpp b/kernel/kernel/Input/PS2Keyboard.cpp index 9b5c7378f6..37e2c7eeb8 100644 --- a/kernel/kernel/Input/PS2Keyboard.cpp +++ b/kernel/kernel/Input/PS2Keyboard.cpp @@ -1,7 +1,10 @@ #include #include +#include #include +#include + #define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask))) #define TOGGLE_MASK(byte, mask) ((byte) ^ (mask)) @@ -50,8 +53,7 @@ namespace Kernel::Input PS2Keyboard::PS2Keyboard(PS2Controller& controller) : m_controller(controller) - , m_name(BAN::String::formatted("input{}", DeviceManager::get().get_next_input_dev())) - , m_rdev(makedev(DeviceManager::get().get_next_rdev(), 0)) + , m_rdev(makedev(DevFileSystem::get().get_next_rdev(), 0)) { } void PS2Keyboard::on_byte(uint8_t byte) diff --git a/kernel/kernel/PCI.cpp b/kernel/kernel/PCI.cpp index de7fdabffb..f378abea66 100644 --- a/kernel/kernel/PCI.cpp +++ b/kernel/kernel/PCI.cpp @@ -1,5 +1,6 @@ #include #include +#include #define INVALID 0xFFFF #define MULTI_FUNCTION 0x80 @@ -18,6 +19,7 @@ namespace Kernel s_instance = new PCI(); ASSERT(s_instance); s_instance->check_all_buses(); + s_instance->initialize_devices(); } PCI& PCI::get() @@ -91,6 +93,32 @@ namespace Kernel } } + void PCI::initialize_devices() + { + for (const auto& pci_device : PCI::get().devices()) + { + switch (pci_device.class_code()) + { + case 0x01: + { + switch (pci_device.subclass()) + { + case 0x01: + if (auto res = ATAController::create(pci_device); res.is_error()) + dprintln("{}", res.error()); + break; + default: + dprintln("unsupported storage device (pci {2H}.{2H}.{2H})", pci_device.class_code(), pci_device.subclass(), pci_device.prog_if()); + break; + } + break; + } + default: + break; + } + } + } + PCIDevice::PCIDevice(uint8_t bus, uint8_t dev, uint8_t func) : m_bus(bus), m_dev(dev), m_func(func) { diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index c769159e2c..c0a3cb33ba 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -11,6 +11,7 @@ #include #include +#include namespace Kernel { @@ -749,8 +750,9 @@ namespace Kernel LockGuard _(m_lock); if (m_tty == nullptr) buffer[0] = '\0'; - strcpy(buffer, "/dev/"); - strcpy(buffer + 5, m_tty->name().data()); + ASSERT(minor(m_tty->rdev()) < 10); + strcpy(buffer, "/dev/tty1"); + buffer[8] += minor(m_tty->rdev()); return 0; } diff --git a/kernel/kernel/Storage/ATABus.cpp b/kernel/kernel/Storage/ATABus.cpp index d7c53d70f6..bacd47eb44 100644 --- a/kernel/kernel/Storage/ATABus.cpp +++ b/kernel/kernel/Storage/ATABus.cpp @@ -44,7 +44,7 @@ namespace Kernel ASSERT_NOT_REACHED(); } - ATABus* ATABus::create(ATAController* controller, uint16_t base, uint16_t ctrl, uint8_t irq) + ATABus* ATABus::create(ATAController& controller, uint16_t base, uint16_t ctrl, uint8_t irq) { ATABus* bus = new ATABus(controller, base, ctrl); ASSERT(bus); @@ -62,17 +62,20 @@ namespace Kernel for (uint8_t i = 0; i < 2; i++) { - m_devices[i] = new ATADevice(this); - ATADevice* device = m_devices[i]; - ASSERT(device); + { + auto* temp_ptr = new ATADevice(*this); + ASSERT(temp_ptr); + m_devices[i] = BAN::RefPtr::adopt(temp_ptr); + } + ATADevice& device = *m_devices[i]; - BAN::ScopeGuard guard([this, i] { m_devices[i]->unref(); m_devices[i] = nullptr; }); + BAN::ScopeGuard guard([this, i] { m_devices[i] = nullptr; }); auto type = identify(device, identify_buffer); if (type == DeviceType::None) continue; - auto res = device->initialize(type, identify_buffer); + auto res = device.initialize(type, identify_buffer); if (res.is_error()) { dprintln("{}", res.error()); @@ -87,19 +90,19 @@ namespace Kernel { if (!m_devices[i]) continue; - select_device(m_devices[i]); + select_device(*m_devices[i]); io_write(ATA_PORT_CONTROL, 0); } } - void ATABus::select_device(const ATADevice* device) + void ATABus::select_device(const ATADevice& device) { uint8_t device_index = this->device_index(device); io_write(ATA_PORT_DRIVE_SELECT, 0xA0 | (device_index << 4)); PIT::sleep(1); } - ATABus::DeviceType ATABus::identify(const ATADevice* device, uint16_t* buffer) + ATABus::DeviceType ATABus::identify(const ATADevice& device, uint16_t* buffer) { select_device(device); @@ -242,15 +245,15 @@ namespace Kernel return BAN::Error::from_error_code(ErrorCode::None); } - uint8_t ATABus::device_index(const ATADevice* device) const + uint8_t ATABus::device_index(const ATADevice& device) const { - ASSERT(device == m_devices[0] || device == m_devices[1]); - return (device == m_devices[0]) ? 0 : 1; + ASSERT(&device == m_devices[0].ptr() || &device == m_devices[1].ptr()); + return (&device == m_devices[0].ptr()) ? 0 : 1; } - BAN::ErrorOr ATABus::read(ATADevice* device, uint64_t lba, uint8_t sector_count, uint8_t* buffer) + BAN::ErrorOr ATABus::read(ATADevice& device, uint64_t lba, uint8_t sector_count, uint8_t* buffer) { - if (lba + sector_count > device->m_lba_count) + if (lba + sector_count > device.m_lba_count) return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries); LockGuard _(m_lock); @@ -268,7 +271,7 @@ namespace Kernel for (uint32_t sector = 0; sector < sector_count; sector++) { block_until_irq(); - read_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * device->m_sector_words, device->m_sector_words); + read_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * device.m_sector_words, device.m_sector_words); } } else @@ -280,9 +283,9 @@ namespace Kernel return {}; } - BAN::ErrorOr ATABus::write(ATADevice* device, uint64_t lba, uint8_t sector_count, const uint8_t* buffer) + BAN::ErrorOr ATABus::write(ATADevice& device, uint64_t lba, uint8_t sector_count, const uint8_t* buffer) { - if (lba + sector_count > device->m_lba_count) + if (lba + sector_count > device.m_lba_count) return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries); LockGuard _(m_lock); @@ -301,7 +304,7 @@ namespace Kernel for (uint32_t sector = 0; sector < sector_count; sector++) { - write_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * device->m_sector_words, device->m_sector_words); + write_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * device.m_sector_words, device.m_sector_words); block_until_irq(); } } diff --git a/kernel/kernel/Storage/ATAController.cpp b/kernel/kernel/Storage/ATAController.cpp index e7f1fbdca3..e8f0f18bb5 100644 --- a/kernel/kernel/Storage/ATAController.cpp +++ b/kernel/kernel/Storage/ATAController.cpp @@ -1,14 +1,17 @@ #include +#include #include #include #include #include #include +#include + namespace Kernel { - BAN::ErrorOr ATAController::create(const PCIDevice& device) + BAN::ErrorOr> ATAController::create(const PCIDevice& device) { ATAController* controller = new ATAController(); if (controller == nullptr) @@ -16,9 +19,42 @@ namespace Kernel BAN::ScopeGuard guard([controller] { controller->unref(); }); TRY(controller->initialize(device)); guard.disable(); - return controller; + + auto ref_ptr = BAN::RefPtr::adopt(controller); + + DevFileSystem::get().add_device("hd"sv, ref_ptr); + + auto devices = controller->devices(); + for (size_t i = 0; i < devices.size(); i++) + { + char device_name[4] { 'h', 'd', 'a', '\0' }; + device_name[2] += i; + + DevFileSystem::get().add_device(device_name, devices[i]); + + if (auto res = devices[i]->initialize_partitions(); res.is_error()) + dprintln("{}", res.error()); + else + { + char partition_name[5] { 'h', 'd', 'a', '1', '\0' }; + partition_name[2] += i; + + auto& partitions = devices[i]->partitions(); + for (size_t j = 0; j < partitions.size(); j++) + { + partition_name[3] += j; + DevFileSystem::get().add_device(partition_name, partitions[j]); + } + } + } + + return ref_ptr; } + ATAController::ATAController() + : m_rdev(makedev(DevFileSystem::get().get_next_rdev(), 0)) + { } + BAN::ErrorOr ATAController::initialize(const PCIDevice& pci_device) { struct Bus @@ -48,21 +84,15 @@ namespace Kernel return BAN::Error::from_error_code(ErrorCode::ATA_UnsupportedDevice); } - m_buses[0] = ATABus::create(this, buses[0].base, buses[0].ctrl, 14); - m_buses[1] = ATABus::create(this, buses[1].base, buses[1].ctrl, 15); + m_buses[0] = ATABus::create(*this, buses[0].base, buses[0].ctrl, 14); + m_buses[1] = ATABus::create(*this, buses[1].base, buses[1].ctrl, 15); return {}; } - uint8_t ATAController::next_device_index() const + BAN::Vector> ATAController::devices() { - static uint8_t index = 0; - return index++; - } - - BAN::Vector ATAController::devices() - { - BAN::Vector devices; + BAN::Vector> devices; if (m_buses[0]->m_devices[0]) MUST(devices.push_back(m_buses[0]->m_devices[0])); if (m_buses[0]->m_devices[1]) diff --git a/kernel/kernel/Storage/ATADevice.cpp b/kernel/kernel/Storage/ATADevice.cpp index bfbbee445f..70e5c957aa 100644 --- a/kernel/kernel/Storage/ATADevice.cpp +++ b/kernel/kernel/Storage/ATADevice.cpp @@ -1,11 +1,19 @@ +#include #include #include #include #include +#include + namespace Kernel { + ATADevice::ATADevice(ATABus& bus) + : m_bus(bus) + , m_rdev(makedev(DevFileSystem::get().get_next_rdev(), 0)) + { } + BAN::ErrorOr ATADevice::initialize(ATABus::DeviceType type, const uint16_t* identify_buffer) { m_type = type; @@ -45,13 +53,7 @@ namespace Kernel } m_model[40] = 0; - m_index = m_bus->controller()->next_device_index(); - m_device_name[0] = 'h'; - m_device_name[1] = 'd'; - m_device_name[2] = 'a' + m_index; - m_device_name[3] = '\0'; - - dprintln("{} {} MB", m_device_name, total_size() / 1024 / 1024); + dprintln("ATA disk {} MB", total_size() / 1024 / 1024); add_disk_cache(); @@ -60,13 +62,13 @@ namespace Kernel BAN::ErrorOr ATADevice::read_sectors_impl(uint64_t lba, uint8_t sector_count, uint8_t* buffer) { - TRY(m_bus->read(this, lba, sector_count, buffer)); + TRY(m_bus.read(*this, lba, sector_count, buffer)); return {}; } BAN::ErrorOr ATADevice::write_sectors_impl(uint64_t lba, uint8_t sector_count, const uint8_t* buffer) { - TRY(m_bus->write(this, lba, sector_count, buffer)); + TRY(m_bus.write(*this, lba, sector_count, buffer)); return {}; } diff --git a/kernel/kernel/Storage/StorageDevice.cpp b/kernel/kernel/Storage/StorageDevice.cpp index eb8477ac10..c6bec038ea 100644 --- a/kernel/kernel/Storage/StorageDevice.cpp +++ b/kernel/kernel/Storage/StorageDevice.cpp @@ -7,6 +7,8 @@ #include #include +#include + #define ATA_DEVICE_PRIMARY 0x1F0 #define ATA_DEVICE_SECONDARY 0x170 #define ATA_DEVICE_SLAVE_BIT 0x10 @@ -199,23 +201,18 @@ namespace Kernel } Partition::Partition(StorageDevice& device, const GUID& type, const GUID& guid, uint64_t start, uint64_t end, uint64_t attr, const char* label, uint32_t index) - : m_device(device) + : BlockDevice(0660, 0, 0) + , m_device(device) , m_type(type) , m_guid(guid) , m_lba_start(start) , m_lba_end(end) , m_attributes(attr) - , m_index(index) - , m_device_name(BAN::String::formatted("{}{}", m_device.name(), index)) + , m_rdev(makedev(major(device.rdev()), index)) { memcpy(m_label, label, sizeof(m_label)); } - dev_t Partition::rdev() const - { - return makedev(major(m_device.rdev()), m_index); - } - BAN::ErrorOr Partition::read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer) { const uint32_t sectors_in_partition = m_lba_end - m_lba_start; diff --git a/kernel/kernel/Terminal/TTY.cpp b/kernel/kernel/Terminal/TTY.cpp index f9959efa21..48844e373f 100644 --- a/kernel/kernel/Terminal/TTY.cpp +++ b/kernel/kernel/Terminal/TTY.cpp @@ -2,12 +2,14 @@ #include #include #include +#include #include #include #include #include #include +#include #define BEL 0x07 #define BS 0x08 @@ -26,7 +28,7 @@ namespace Kernel static dev_t next_tty_rdev() { - static dev_t major = DeviceManager::get().get_next_rdev(); + static dev_t major = DevFileSystem::get().get_next_rdev(); static dev_t minor = 1; return makedev(major, minor++); } @@ -34,7 +36,8 @@ namespace Kernel static TTY* s_tty = nullptr; TTY::TTY(TerminalDriver* driver) - : m_terminal_driver(driver) + : CharacterDevice(0444, 0, 0) + , m_terminal_driver(driver) { m_width = m_terminal_driver->width(); m_height = m_terminal_driver->height(); @@ -54,8 +57,12 @@ namespace Kernel void TTY::initialize_device() { m_rdev = next_tty_rdev(); - m_name = BAN::String::formatted("tty{}", minor(m_rdev)); - DeviceManager::get().add_device(this); + + char name[5] { 't', 't', 'y', '1', '\0'}; + name[3] += minor(m_rdev); + ASSERT(minor(m_rdev) < 10); + + DevFileSystem::get().add_device(name, this); if (s_input_process) return; diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index ef625b788a..feaf010d01 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -140,6 +140,9 @@ extern "C" void kernel_main() ASSERT(terminal_driver); dprintln("VESA initialized"); + DevFileSystem::initialize(); + dprintln("devfs initialized"); + TTY* tty1 = new TTY(terminal_driver); ASSERT(tty1); dprintln("TTY initialized"); @@ -147,9 +150,6 @@ extern "C" void kernel_main() parse_command_line(); dprintln("command line parsed, root='{}'", cmdline.root); - PCI::initialize(); - dprintln("PCI initialized"); - MUST(ACPI::initialize()); dprintln("ACPI initialized"); @@ -160,6 +160,8 @@ extern "C" void kernel_main() dprintln("PIT initialized"); MUST(Scheduler::initialize()); + dprintln("Scheduler initialized"); + Scheduler& scheduler = Scheduler::get(); Process::create_kernel(init2, tty1); scheduler.start(); @@ -172,9 +174,13 @@ static void init2(void* tty1) using namespace Kernel; using namespace Kernel::Input; - DeviceManager::get().initialize_pci_devices(); - DeviceManager::get().initialize_updater(); + dprintln("Scheduler started"); + DevFileSystem::get().initialize_device_updater(); + + PCI::initialize(); + dprintln("PCI initialized"); + VirtualFileSystem::initialize(cmdline.root); if (auto res = PS2Controller::initialize(); res.is_error())