forked from Bananymous/banan-os
Kernel: StorageDevices and Controllers are now devices
This commit is contained in:
parent
c9badb5a1c
commit
0ce9fd8597
|
@ -34,13 +34,17 @@ namespace Kernel
|
||||||
IFREG = 0x8000,
|
IFREG = 0x8000,
|
||||||
IFLNK = 0xA000,
|
IFLNK = 0xA000,
|
||||||
IFSOCK = 0xC000,
|
IFSOCK = 0xC000,
|
||||||
|
TYPE_MASK = 0xF000,
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Inode() {}
|
virtual ~Inode() {}
|
||||||
|
|
||||||
bool ifdir() const { return mode() & Mode::IFDIR; }
|
bool ifdir() const { return (mode() & Mode::TYPE_MASK) == Mode::IFDIR; }
|
||||||
bool ifreg() const { return mode() & Mode::IFREG; }
|
bool ifblk() const { return (mode() & Mode::TYPE_MASK) == Mode::IFBLK; }
|
||||||
|
bool ifreg() const { return (mode() & Mode::TYPE_MASK) == Mode::IFREG; }
|
||||||
|
bool iflnk() const { return (mode() & Mode::TYPE_MASK) == Mode::IFLNK; }
|
||||||
|
bool ifsock() const { return (mode() & Mode::TYPE_MASK) == Mode::IFSOCK; }
|
||||||
|
|
||||||
bool operator==(const Inode& other) const { return dev() == other.dev() && rdev() == other.rdev() && ino() == other.ino(); }
|
bool operator==(const Inode& other) const { return dev() == other.dev() && rdev() == other.rdev() && ino() == other.ino(); }
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Kernel
|
||||||
static VirtualFileSystem& get();
|
static VirtualFileSystem& get();
|
||||||
virtual ~VirtualFileSystem() {};
|
virtual ~VirtualFileSystem() {};
|
||||||
|
|
||||||
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
|
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_fs->root_inode(); }
|
||||||
|
|
||||||
BAN::ErrorOr<void> mount(FileSystem*, BAN::StringView);
|
BAN::ErrorOr<void> mount(FileSystem*, BAN::StringView);
|
||||||
|
|
||||||
|
@ -36,10 +36,9 @@ namespace Kernel
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VirtualFileSystem() = default;
|
VirtualFileSystem() = default;
|
||||||
BAN::ErrorOr<void> initialize_impl();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::RefPtr<Inode> m_root_inode;
|
FileSystem* m_root_fs = nullptr;
|
||||||
BAN::Vector<MountPoint> m_mount_points;
|
BAN::Vector<MountPoint> m_mount_points;
|
||||||
BAN::Vector<StorageController*> m_storage_controllers;
|
BAN::Vector<StorageController*> m_storage_controllers;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <BAN/Errors.h>
|
#include <kernel/PCI.h>
|
||||||
#include <kernel/Storage/StorageController.h>
|
#include <kernel/Storage/StorageController.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
|
@ -38,6 +38,24 @@ namespace Kernel
|
||||||
ATAController* controller;
|
ATAController* controller;
|
||||||
|
|
||||||
friend class ATAController;
|
friend class ATAController;
|
||||||
|
|
||||||
|
char device_name[4] {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ino_t ino() const override { return !!slave_bit; }
|
||||||
|
virtual mode_t mode() const override { return Mode::IFBLK; }
|
||||||
|
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 blksize_t blksize() const override { return sector_size(); }
|
||||||
|
virtual blkcnt_t blocks() const override { return 0; }
|
||||||
|
virtual dev_t dev() const override;
|
||||||
|
virtual dev_t rdev() const override { return 0x5429; }
|
||||||
|
|
||||||
|
virtual BAN::StringView name() const override { return BAN::StringView(device_name, sizeof(device_name) - 1); }
|
||||||
|
|
||||||
|
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ATABus
|
struct ATABus
|
||||||
|
@ -54,7 +72,7 @@ namespace Kernel
|
||||||
BAN::Error error();
|
BAN::Error error();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ATAController : public StorageController
|
class ATAController final : public StorageController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<ATAController*> create(const PCIDevice&);
|
static BAN::ErrorOr<ATAController*> create(const PCIDevice&);
|
||||||
|
@ -71,6 +89,22 @@ namespace Kernel
|
||||||
const PCIDevice& m_pci_device;
|
const PCIDevice& m_pci_device;
|
||||||
|
|
||||||
friend class ATADevice;
|
friend class ATADevice;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ino_t ino() const override { return 0; }
|
||||||
|
virtual mode_t mode() const override { return Mode::IFCHR; }
|
||||||
|
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 blksize_t blksize() const override { return 0; }
|
||||||
|
virtual blkcnt_t blocks() const override { return 0; }
|
||||||
|
virtual dev_t dev() const override { return DeviceManager::get().dev(); }
|
||||||
|
virtual dev_t rdev() const override { return 0x8594; }
|
||||||
|
|
||||||
|
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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,18 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/PCI.h>
|
|
||||||
#include <kernel/Storage/StorageDevice.h>
|
#include <kernel/Storage/StorageDevice.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
class StorageController
|
class StorageController : public CharacterDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BAN::Vector<StorageDevice*>& devices() { return m_devices; }
|
BAN::Vector<StorageDevice*>& devices() { return m_devices; }
|
||||||
const BAN::Vector<StorageDevice*>& devices() const { return m_devices; }
|
const BAN::Vector<StorageDevice*>& devices() const { return m_devices; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void add_device(StorageDevice* device)
|
||||||
|
{
|
||||||
|
ASSERT(device);
|
||||||
|
MUST(m_devices.push_back(device));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
BAN::Vector<StorageDevice*> m_devices;
|
BAN::Vector<StorageDevice*> m_devices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ namespace Kernel
|
||||||
|
|
||||||
class StorageDevice;
|
class StorageDevice;
|
||||||
|
|
||||||
class Partition
|
class Partition final : public BlockDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Partition(StorageDevice&, const GUID&, const GUID&, uint64_t, uint64_t, uint64_t, const char*);
|
Partition(StorageDevice&, const GUID&, const GUID&, uint64_t, uint64_t, uint64_t, const char*, uint32_t);
|
||||||
|
|
||||||
const GUID& partition_type() const { return m_type; }
|
const GUID& partition_type() const { return m_type; }
|
||||||
const GUID& partition_guid() const { return m_guid; }
|
const GUID& partition_guid() const { return m_guid; }
|
||||||
|
@ -31,7 +31,6 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer);
|
BAN::ErrorOr<void> read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer);
|
||||||
BAN::ErrorOr<void> write_sectors(uint64_t lba, uint8_t sector_count, const uint8_t* buffer);
|
BAN::ErrorOr<void> write_sectors(uint64_t lba, uint8_t sector_count, const uint8_t* buffer);
|
||||||
bool is_used() const { uint8_t zero[16] {}; return memcmp(&m_type, zero, 16); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StorageDevice& m_device;
|
StorageDevice& m_device;
|
||||||
|
@ -41,9 +40,29 @@ namespace Kernel
|
||||||
const uint64_t m_lba_end;
|
const uint64_t m_lba_end;
|
||||||
const uint64_t m_attributes;
|
const uint64_t m_attributes;
|
||||||
char m_label[36 * 4 + 1];
|
char m_label[36 * 4 + 1];
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ino_t ino() const override { return m_index; }
|
||||||
|
virtual mode_t mode() const override { return Mode::IFBLK | Mode::IRUSR | Mode::IRGRP; }
|
||||||
|
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 blksize_t blksize() const;
|
||||||
|
virtual blkcnt_t blocks() const override { return 0; }
|
||||||
|
virtual dev_t dev() const override;
|
||||||
|
virtual dev_t rdev() const { return 0x7459; }
|
||||||
|
|
||||||
|
virtual BAN::StringView name() const override { return m_device_name; }
|
||||||
|
|
||||||
|
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint32_t m_index;
|
||||||
|
BAN::String m_device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StorageDevice
|
class StorageDevice : public BlockDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~StorageDevice() {}
|
virtual ~StorageDevice() {}
|
||||||
|
@ -55,10 +74,11 @@ namespace Kernel
|
||||||
virtual uint32_t sector_size() const = 0;
|
virtual uint32_t sector_size() const = 0;
|
||||||
virtual uint64_t total_size() const = 0;
|
virtual uint64_t total_size() const = 0;
|
||||||
|
|
||||||
BAN::Vector<Partition>& partitions() { return m_partitions; }
|
BAN::Vector<Partition*>& partitions() { return m_partitions; }
|
||||||
|
const BAN::Vector<Partition*>& partitions() const { return m_partitions; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::Vector<Partition> m_partitions;
|
BAN::Vector<Partition*> m_partitions;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,12 +1,20 @@
|
||||||
|
#include <BAN/Time.h>
|
||||||
#include <kernel/Device.h>
|
#include <kernel/Device.h>
|
||||||
#include <kernel/LockGuard.h>
|
#include <kernel/LockGuard.h>
|
||||||
|
#include <kernel/PCI.h>
|
||||||
#include <kernel/Process.h>
|
#include <kernel/Process.h>
|
||||||
|
#include <kernel/RTC.h>
|
||||||
|
#include <kernel/Storage/ATAController.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
static DeviceManager* s_instance = nullptr;
|
static DeviceManager* s_instance = nullptr;
|
||||||
|
|
||||||
|
Device::Device()
|
||||||
|
: m_create_time({ BAN::to_unix_time(RTC::get_current_time()), 0 })
|
||||||
|
{ }
|
||||||
|
|
||||||
void DeviceManager::initialize()
|
void DeviceManager::initialize()
|
||||||
{
|
{
|
||||||
ASSERT(s_instance == nullptr);
|
ASSERT(s_instance == nullptr);
|
||||||
|
@ -14,6 +22,43 @@ namespace Kernel
|
||||||
s_instance = new DeviceManager;
|
s_instance = new DeviceManager;
|
||||||
ASSERT(s_instance != nullptr);
|
ASSERT(s_instance != nullptr);
|
||||||
|
|
||||||
|
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 subclass {2H})", pci_device.subclass());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controller)
|
||||||
|
{
|
||||||
|
s_instance->add_device(controller);
|
||||||
|
for (auto* device : controller->devices())
|
||||||
|
{
|
||||||
|
s_instance->add_device(device);
|
||||||
|
for (auto* partition : device->partitions())
|
||||||
|
s_instance->add_device(partition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MUST(Process::create_kernel(
|
MUST(Process::create_kernel(
|
||||||
[](void*)
|
[](void*)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/StringView.h>
|
||||||
#include <BAN/Vector.h>
|
#include <BAN/Vector.h>
|
||||||
#include <kernel/Device.h>
|
#include <kernel/Device.h>
|
||||||
|
@ -17,13 +18,13 @@ namespace Kernel
|
||||||
s_instance = new VirtualFileSystem();
|
s_instance = new VirtualFileSystem();
|
||||||
if (s_instance == nullptr)
|
if (s_instance == nullptr)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
|
BAN::ScopeGuard guard([] { delete s_instance; s_instance = nullptr; } );
|
||||||
|
|
||||||
if (auto res = s_instance->initialize_impl(); res.is_error())
|
auto partition_inode = TRY(DeviceManager::get().read_directory_inode("hda1"));
|
||||||
{
|
s_instance->m_root_fs = TRY(Ext2FS::create(*(Partition*)partition_inode.ptr()));
|
||||||
delete s_instance;
|
TRY(s_instance->mount(&DeviceManager::get(), "/dev"));
|
||||||
s_instance = nullptr;
|
|
||||||
return res;
|
guard.disable();
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -34,91 +35,6 @@ namespace Kernel
|
||||||
return *s_instance;
|
return *s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> VirtualFileSystem::initialize_impl()
|
|
||||||
{
|
|
||||||
// Initialize all storage controllers
|
|
||||||
for (auto& device : PCI::get().devices())
|
|
||||||
{
|
|
||||||
if (device.class_code() != 0x01)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (device.subclass())
|
|
||||||
{
|
|
||||||
case 0x0:
|
|
||||||
dwarnln("unsupported SCSI Bus Controller");
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
case 0x5:
|
|
||||||
TRY(m_storage_controllers.push_back(TRY(ATAController::create(device))));
|
|
||||||
break;
|
|
||||||
case 0x2:
|
|
||||||
dwarnln("unsupported Floppy Disk Controller");
|
|
||||||
break;
|
|
||||||
case 0x3:
|
|
||||||
dwarnln("unsupported IPI Bus Controller");
|
|
||||||
break;
|
|
||||||
case 0x4:
|
|
||||||
dwarnln("unsupported RAID Controller");
|
|
||||||
break;
|
|
||||||
case 0x6:
|
|
||||||
dwarnln("unsupported Serial ATA Controller");
|
|
||||||
break;
|
|
||||||
case 0x7:
|
|
||||||
dwarnln("unsupported Serial Attached SCSI Controller");
|
|
||||||
break;
|
|
||||||
case 0x8:
|
|
||||||
dwarnln("unsupported Non-Volatile Memory Controller");
|
|
||||||
break;
|
|
||||||
case 0x80:
|
|
||||||
dwarnln("unsupported Unknown Storage Controller");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize partitions on all devices on found controllers
|
|
||||||
for (auto controller : m_storage_controllers)
|
|
||||||
{
|
|
||||||
for (auto device : controller->devices())
|
|
||||||
{
|
|
||||||
if (device->total_size() == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto result = device->initialize_partitions();
|
|
||||||
if (result.is_error())
|
|
||||||
{
|
|
||||||
dwarnln("{}", result.error());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& partition : device->partitions())
|
|
||||||
{
|
|
||||||
if (partition.label() == "banan-root"sv)
|
|
||||||
{
|
|
||||||
if (root_inode())
|
|
||||||
dwarnln("multiple root partitions found");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto ext2fs_or_error = Ext2FS::create(partition);
|
|
||||||
if (ext2fs_or_error.is_error())
|
|
||||||
dwarnln("{}", ext2fs_or_error.error());
|
|
||||||
else
|
|
||||||
// FIXME: We leave a dangling pointer to ext2fs. This might be okay since
|
|
||||||
// root fs sould probably be always mounted
|
|
||||||
m_root_inode = ext2fs_or_error.value()->root_inode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!root_inode())
|
|
||||||
derrorln("Could not locate root partition");
|
|
||||||
|
|
||||||
TRY(mount(&DeviceManager::get(), "/dev"));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> VirtualFileSystem::mount(FileSystem* file_system, BAN::StringView path)
|
BAN::ErrorOr<void> VirtualFileSystem::mount(FileSystem* file_system, BAN::StringView path)
|
||||||
{
|
{
|
||||||
auto file = TRY(file_from_absolute_path(path));
|
auto file = TRY(file_from_absolute_path(path));
|
||||||
|
|
|
@ -94,6 +94,11 @@ namespace Kernel
|
||||||
device.bus = &bus;
|
device.bus = &bus;
|
||||||
device.controller = this;
|
device.controller = this;
|
||||||
|
|
||||||
|
device.device_name[0] = 'h';
|
||||||
|
device.device_name[1] = 'd';
|
||||||
|
device.device_name[2] = 'a' + bus_index * 2 + device_index;
|
||||||
|
device.device_name[3] = '\0';
|
||||||
|
|
||||||
bus.write(ATA_PORT_DRIVE_SELECT, 0xA0 | device.slave_bit);
|
bus.write(ATA_PORT_DRIVE_SELECT, 0xA0 | device.slave_bit);
|
||||||
PIT::sleep(1);
|
PIT::sleep(1);
|
||||||
|
|
||||||
|
@ -162,7 +167,15 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
device.model[40] = 0;
|
device.model[40] = 0;
|
||||||
|
|
||||||
TRY(m_devices.push_back(&device));
|
if (auto res = device.initialize_partitions(); res.is_error())
|
||||||
|
{
|
||||||
|
dprintln("could not initialize partitions on device {}", device.device_name);
|
||||||
|
device.type = ATADevice::DeviceType::Unknown;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
add_device(&device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,4 +355,18 @@ namespace Kernel
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_t ATADevice::dev() const
|
||||||
|
{
|
||||||
|
ASSERT(controller);
|
||||||
|
return controller->dev();
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<size_t> ATADevice::read(size_t offset, void* buffer, size_t bytes)
|
||||||
|
{
|
||||||
|
if (offset % sector_size() || bytes % sector_size())
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
TRY(read_sectors(offset / sector_size(), bytes / sector_size(), (uint8_t*)buffer));
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -168,32 +168,41 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
const PartitionEntry& entry = *(const PartitionEntry*)(entry_array.data() + header.partition_entry_size * i);
|
const PartitionEntry& entry = *(const PartitionEntry*)(entry_array.data() + header.partition_entry_size * i);
|
||||||
|
|
||||||
|
GUID zero {};
|
||||||
|
if (memcmp(&entry.partition_type_guid, &zero, sizeof(GUID)) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
char utf8_name[36 * 4 + 1];
|
char utf8_name[36 * 4 + 1];
|
||||||
BAN::UTF8::from_codepoints(entry.partition_name, 36, utf8_name);
|
BAN::UTF8::from_codepoints(entry.partition_name, 36, utf8_name);
|
||||||
|
|
||||||
MUST(m_partitions.emplace_back(
|
Partition* partition = new Partition(
|
||||||
*this,
|
*this,
|
||||||
entry.partition_type_guid,
|
entry.partition_type_guid,
|
||||||
entry.unique_partition_guid,
|
entry.unique_partition_guid,
|
||||||
entry.starting_lba,
|
entry.starting_lba,
|
||||||
entry.ending_lba,
|
entry.ending_lba,
|
||||||
entry.attributes,
|
entry.attributes,
|
||||||
utf8_name
|
utf8_name,
|
||||||
));
|
i
|
||||||
|
);
|
||||||
|
ASSERT(partition != nullptr);
|
||||||
|
MUST(m_partitions.push_back(partition));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Partition::Partition(StorageDevice& device, const GUID& type, const GUID& guid, uint64_t start, uint64_t end, uint64_t attr, const char* label)
|
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)
|
: m_device(device)
|
||||||
, m_type(type)
|
, m_type(type)
|
||||||
, m_guid(guid)
|
, m_guid(guid)
|
||||||
, m_lba_start(start)
|
, m_lba_start(start)
|
||||||
, m_lba_end(end)
|
, m_lba_end(end)
|
||||||
, m_attributes(attr)
|
, m_attributes(attr)
|
||||||
|
, m_index(index)
|
||||||
|
, m_device_name(BAN::String::formatted("{}{}", m_device.name(), index))
|
||||||
{
|
{
|
||||||
memcpy(m_label, label, sizeof(m_label));
|
memcpy(m_label, label, sizeof(m_label));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Partition::read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer)
|
BAN::ErrorOr<void> Partition::read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer)
|
||||||
|
@ -214,4 +223,22 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blksize_t Partition::blksize() const
|
||||||
|
{
|
||||||
|
return m_device.blksize();
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_t Partition::dev() const
|
||||||
|
{
|
||||||
|
return m_device.dev();
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<size_t> Partition::read(size_t offset, void* buffer, size_t bytes)
|
||||||
|
{
|
||||||
|
if (offset % m_device.sector_size() || bytes % m_device.sector_size())
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
TRY(read_sectors(offset / m_device.sector_size(), bytes / m_device.sector_size(), (uint8_t*)buffer));
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue