forked from Bananymous/banan-os
Kernel: Rewrite whole device structure
We now have DevFileSystem which is derived from RamFileSystem. All devices are RamInodes. We don't have separate DeviceManager anymore. To iterate over devices, you can loop througn every inode in devfs.
This commit is contained in:
parent
9174a89971
commit
74c79c7eff
|
@ -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
|
||||
|
|
|
@ -1,53 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include <kernel/DeviceManager.h>
|
||||
#include <kernel/FS/RamFS/Inode.h>
|
||||
|
||||
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());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/StringView.h>
|
||||
#include <kernel/FS/FileSystem.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
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<Inode> root_inode() override { return this; }
|
||||
|
||||
virtual BAN::StringView name() const override { return "device-manager"; }
|
||||
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_inode(BAN::StringView) override;
|
||||
virtual BAN::ErrorOr<void> directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override;
|
||||
|
||||
private:
|
||||
DeviceManager() = default;
|
||||
|
||||
private:
|
||||
SpinLock m_lock;
|
||||
BAN::Vector<Device*> m_devices;
|
||||
|
||||
friend class BAN::RefPtr<DeviceManager>;
|
||||
|
||||
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<size_t> read(size_t, void*, size_t) { return BAN::Error::from_errno(EISDIR); }
|
||||
virtual BAN::ErrorOr<void> 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;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <kernel/Device.h>
|
||||
#include <kernel/FS/RamFS/FileSystem.h>
|
||||
|
||||
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<Device>);
|
||||
|
||||
dev_t get_next_rdev();
|
||||
|
||||
private:
|
||||
DevFileSystem(size_t size)
|
||||
: RamFileSystem(size)
|
||||
{ }
|
||||
|
||||
private:
|
||||
SpinLock m_device_lock;
|
||||
};
|
||||
|
||||
}
|
|
@ -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<BAN::String> link_target() override;
|
||||
|
||||
virtual BAN::ErrorOr<void> directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override;
|
||||
|
|
|
@ -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<BAN::String> link_target() { ASSERT_NOT_REACHED(); }
|
||||
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_inode(BAN::StringView) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||
|
|
|
@ -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<size_t> read(size_t, void*, size_t) override;
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) override;
|
||||
|
||||
|
|
|
@ -8,13 +8,15 @@ namespace Kernel
|
|||
{
|
||||
|
||||
class RamInode;
|
||||
class RamDirectoryInode;
|
||||
|
||||
class RamFileSystem final : public FileSystem
|
||||
class RamFileSystem : public FileSystem
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<RamFileSystem*> create(size_t size, mode_t, uid_t, gid_t);
|
||||
~RamFileSystem() = default;
|
||||
virtual ~RamFileSystem() = default;
|
||||
|
||||
BAN::ErrorOr<void> set_root_inode(BAN::RefPtr<RamDirectoryInode>);
|
||||
virtual BAN::RefPtr<Inode> root_inode() override { return m_inodes[m_root_inode]; }
|
||||
|
||||
BAN::ErrorOr<void> add_inode(BAN::RefPtr<RamInode>);
|
||||
|
@ -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<RamInode>));
|
||||
|
||||
protected:
|
||||
RamFileSystem(size_t size)
|
||||
: m_size(size)
|
||||
{ }
|
||||
|
||||
private:
|
||||
SpinLock m_lock;
|
||||
RecursiveSpinLock m_lock;
|
||||
size_t m_size { 0 };
|
||||
|
||||
BAN::HashMap<ino_t, BAN::RefPtr<RamInode>> 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 };
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace Kernel
|
|||
class RamInode : public Inode
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<RamInode>> 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<size_t> read(size_t, void*, size_t) override;
|
||||
virtual BAN::ErrorOr<size_t> 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<BAN::RefPtr<RamInode>> 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<BAN::RefPtr<RamDirectoryInode>> create(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t);
|
||||
~RamDirectoryInode() = default;
|
||||
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_inode(BAN::StringView) override;
|
||||
virtual BAN::ErrorOr<void> directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override;
|
||||
virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t) override;
|
||||
|
||||
BAN::ErrorOr<void> add_inode(BAN::StringView, BAN::RefPtr<RamInode>);
|
||||
|
||||
private:
|
||||
RamDirectoryInode(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t);
|
||||
static BAN::ErrorOr<BAN::RefPtr<RamDirectoryInode>> create(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t);
|
||||
|
||||
private:
|
||||
static constexpr size_t m_name_max = NAME_MAX;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<size_t> read(size_t, void*, size_t) override;
|
||||
|
||||
private:
|
||||
const BAN::String m_name;
|
||||
const dev_t m_rdev;
|
||||
};
|
||||
|
||||
|
|
|
@ -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<PCIDevice> m_devices;
|
||||
|
|
|
@ -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<void> read(ATADevice*, uint64_t, uint8_t, uint8_t*);
|
||||
BAN::ErrorOr<void> write(ATADevice*, uint64_t, uint8_t, const uint8_t*);
|
||||
BAN::ErrorOr<void> read(ATADevice&, uint64_t, uint8_t, uint8_t*);
|
||||
BAN::ErrorOr<void> 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<ATADevice> m_devices[2] {};
|
||||
|
||||
friend class ATAController;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <kernel/DeviceManager.h>
|
||||
#include <kernel/PCI.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
#include <kernel/Storage/StorageController.h>
|
||||
|
@ -13,16 +12,12 @@ namespace Kernel
|
|||
class ATAController final : public StorageController
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<ATAController*> create(const PCIDevice&);
|
||||
static BAN::ErrorOr<BAN::RefPtr<ATAController>> create(const PCIDevice&);
|
||||
|
||||
virtual BAN::Vector<StorageDevice*> devices() override;
|
||||
|
||||
uint8_t next_device_index() const;
|
||||
virtual BAN::Vector<BAN::RefPtr<StorageDevice>> devices() override;
|
||||
|
||||
private:
|
||||
ATAController()
|
||||
: m_rdev(makedev(DeviceManager::get().get_next_rdev(), 0))
|
||||
{ }
|
||||
ATAController();
|
||||
BAN::ErrorOr<void> 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<size_t> read(size_t, void*, size_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
|
||||
private:
|
||||
|
|
|
@ -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<void> 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<void> 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<size_t> read(size_t, void*, size_t) override;
|
||||
|
||||
public:
|
||||
const dev_t m_rdev;
|
||||
char m_device_name[4] {};
|
||||
};
|
||||
|
||||
}
|
|
@ -8,7 +8,10 @@ namespace Kernel
|
|||
class StorageController : public CharacterDevice
|
||||
{
|
||||
public:
|
||||
virtual BAN::Vector<StorageDevice*> devices() = 0;
|
||||
StorageController()
|
||||
: CharacterDevice(0660, 0, 0)
|
||||
{ }
|
||||
virtual BAN::Vector<BAN::RefPtr<StorageDevice>> devices() = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -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<size_t> 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<void> initialize_partitions();
|
||||
|
@ -74,7 +74,7 @@ namespace Kernel
|
|||
|
||||
BAN::Vector<Partition*>& partitions() { return m_partitions; }
|
||||
const BAN::Vector<Partition*>& partitions() const { return m_partitions; }
|
||||
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint8_t sector_count, uint8_t* buffer) = 0;
|
||||
virtual BAN::ErrorOr<void> write_sectors_impl(uint64_t lba, uint8_t sector_count, const uint8_t* buffer) = 0;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
#include <BAN/Time.h>
|
||||
#include <kernel/Device.h>
|
||||
#include <kernel/RTC.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
|
||||
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)
|
||||
{ }
|
||||
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
#include <kernel/DeviceManager.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/PCI.h>
|
||||
#include <kernel/Process.h>
|
||||
#include <kernel/Storage/ATAController.h>
|
||||
|
||||
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<BAN::RefPtr<Inode>> DeviceManager::directory_find_inode(BAN::StringView name)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
if (name == "."sv || name == ".."sv)
|
||||
return BAN::RefPtr<Inode>(this);
|
||||
for (Device* device : m_devices)
|
||||
if (device->name() == name)
|
||||
return BAN::RefPtr<Inode>(device);
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> 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 {};
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/FS/RamFS/Inode.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Process.h>
|
||||
|
||||
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<RamInode> 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> device)
|
||||
{
|
||||
ASSERT(!path.contains('/'));
|
||||
MUST(reinterpret_cast<RamDirectoryInode*>(root_inode().ptr())->add_inode(path, device));
|
||||
}
|
||||
|
||||
dev_t DevFileSystem::get_next_rdev()
|
||||
{
|
||||
static dev_t next_rdev = 1;
|
||||
return next_rdev++;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,22 +9,29 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<RamFileSystem*> 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<void> RamFileSystem::set_root_inode(BAN::RefPtr<RamDirectoryInode> root_inode)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
ASSERT(m_root_inode == 0);
|
||||
TRY(add_inode(root_inode));
|
||||
m_root_inode = root_inode->ino();
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> RamFileSystem::add_inode(BAN::RefPtr<RamInode> inode)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
@ -42,4 +49,11 @@ namespace Kernel
|
|||
return m_inodes[ino];
|
||||
}
|
||||
|
||||
void RamFileSystem::for_each_inode(void (*callback)(BAN::RefPtr<RamInode>))
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
for (auto& [_, inode] : m_inodes)
|
||||
callback(inode);
|
||||
}
|
||||
|
||||
}
|
|
@ -180,13 +180,6 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> 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<RamInode> 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<void> RamDirectoryInode::add_inode(BAN::StringView name, BAN::RefPtr<RamInode> 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());
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <BAN/StringView.h>
|
||||
#include <kernel/DeviceManager.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/FS/Ext2.h>
|
||||
#include <kernel/FS/RamFS/FileSystem.h>
|
||||
#include <kernel/FS/RamFS/Inode.h>
|
||||
|
@ -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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <kernel/ACPI.h>
|
||||
#include <kernel/DeviceManager.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/IDT.h>
|
||||
#include <kernel/Input/PS2Controller.h>
|
||||
#include <kernel/Input/PS2Keyboard.h>
|
||||
|
@ -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);
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <kernel/CriticalScope.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Input/PS2Keyboard.h>
|
||||
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#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)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <kernel/IO.h>
|
||||
#include <kernel/PCI.h>
|
||||
#include <kernel/Storage/ATAController.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ATADevice>::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<void> ATABus::read(ATADevice* device, uint64_t lba, uint8_t sector_count, uint8_t* buffer)
|
||||
BAN::ErrorOr<void> 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<void> ATABus::write(ATADevice* device, uint64_t lba, uint8_t sector_count, const uint8_t* buffer)
|
||||
BAN::ErrorOr<void> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Storage/ATABus.h>
|
||||
#include <kernel/Storage/ATAController.h>
|
||||
#include <kernel/Storage/ATADefinitions.h>
|
||||
#include <kernel/Storage/ATADevice.h>
|
||||
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
BAN::ErrorOr<ATAController*> ATAController::create(const PCIDevice& device)
|
||||
BAN::ErrorOr<BAN::RefPtr<ATAController>> 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<ATAController>::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<void> 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<BAN::RefPtr<StorageDevice>> ATAController::devices()
|
||||
{
|
||||
static uint8_t index = 0;
|
||||
return index++;
|
||||
}
|
||||
|
||||
BAN::Vector<StorageDevice*> ATAController::devices()
|
||||
{
|
||||
BAN::Vector<StorageDevice*> devices;
|
||||
BAN::Vector<BAN::RefPtr<StorageDevice>> 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])
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/IO.h>
|
||||
#include <kernel/Storage/ATABus.h>
|
||||
#include <kernel/Storage/ATADefinitions.h>
|
||||
#include <kernel/Storage/ATADevice.h>
|
||||
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
ATADevice::ATADevice(ATABus& bus)
|
||||
: m_bus(bus)
|
||||
, m_rdev(makedev(DevFileSystem::get().get_next_rdev(), 0))
|
||||
{ }
|
||||
|
||||
BAN::ErrorOr<void> 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<void> 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<void> 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 {};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <kernel/PCI.h>
|
||||
#include <kernel/Storage/StorageDevice.h>
|
||||
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#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<void> 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;
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <BAN/UTF8.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Process.h>
|
||||
#include <kernel/Terminal/TTY.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/ACPI.h>
|
||||
#include <kernel/Arch.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/DeviceManager.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/GDT.h>
|
||||
#include <kernel/IDT.h>
|
||||
|
@ -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())
|
||||
|
|
Loading…
Reference in New Issue