Kernel: Move Partition to its own file

This commit is contained in:
Bananymous 2023-11-21 15:16:04 +02:00
parent 19ed0cb9bf
commit 6a068fb9f9
5 changed files with 133 additions and 132 deletions

View File

@ -59,6 +59,7 @@ set(KERNEL_SOURCES
kernel/Storage/ATA/ATAController.cpp kernel/Storage/ATA/ATAController.cpp
kernel/Storage/ATA/ATADevice.cpp kernel/Storage/ATA/ATADevice.cpp
kernel/Storage/DiskCache.cpp kernel/Storage/DiskCache.cpp
kernel/Storage/Partition.cpp
kernel/Storage/StorageDevice.cpp kernel/Storage/StorageDevice.cpp
kernel/Syscall.cpp kernel/Syscall.cpp
kernel/Syscall.S kernel/Syscall.S

View File

@ -0,0 +1,50 @@
#pragma once
#include <BAN/GUID.h>
#include <kernel/Device/Device.h>
namespace Kernel
{
class Partition final : public BlockDevice
{
public:
static BAN::ErrorOr<BAN::RefPtr<Partition>> create(BAN::RefPtr<BlockDevice>, const BAN::GUID& type, const BAN::GUID& guid, uint64_t first_sector, uint64_t last_sector, uint64_t attr, const char* label, uint32_t index);
const BAN::GUID& partition_type() const { return m_type; }
const BAN::GUID& partition_guid() const { return m_guid; }
const BAN::RefPtr<BlockDevice> device() const { return m_device; }
virtual blksize_t blksize() const { return m_device->blksize(); }
virtual BAN::ErrorOr<void> read_sectors(uint64_t first_sector, size_t sector_count, BAN::ByteSpan) override;
virtual BAN::ErrorOr<void> write_sectors(uint64_t first_sector, size_t sector_count, BAN::ConstByteSpan) override;
virtual BAN::StringView name() const override { return m_name; }
private:
Partition(BAN::RefPtr<BlockDevice>, const BAN::GUID&, const BAN::GUID&, uint64_t, uint64_t, uint64_t, const char*, uint32_t);
private:
BAN::RefPtr<BlockDevice> m_device;
const BAN::GUID m_type;
const BAN::GUID m_guid;
const uint64_t m_first_sector;
const uint64_t m_last_sector;
const uint64_t m_attributes;
char m_label[36 * 4 + 1];
const BAN::String m_name;
public:
virtual bool is_partition() const override { return true; }
virtual dev_t rdev() const override { return m_rdev; }
protected:
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
private:
const dev_t m_rdev;
};
}

View File

@ -3,63 +3,11 @@
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <kernel/Device/Device.h> #include <kernel/Device/Device.h>
#include <kernel/Storage/DiskCache.h> #include <kernel/Storage/DiskCache.h>
#include <kernel/Storage/Partition.h>
namespace Kernel namespace Kernel
{ {
struct GUID
{
uint32_t data1;
uint16_t data2;
uint16_t data3;
uint8_t data4[8];
};
class StorageDevice;
class Partition final : public BlockDevice
{
public:
static BAN::ErrorOr<BAN::RefPtr<Partition>> create(StorageDevice&, const GUID& type, const GUID& guid, uint64_t start, uint64_t end, uint64_t attr, const char* label, uint32_t index);
const GUID& partition_type() const { return m_type; }
const GUID& partition_guid() const { return m_guid; }
uint64_t lba_start() const { return m_lba_start; }
uint64_t lba_end() const { return m_lba_end; }
uint64_t attributes() const { return m_attributes; }
const char* label() const { return m_label; }
const StorageDevice& device() const { return m_device; }
BAN::ErrorOr<void> read_sectors(uint64_t lba, uint8_t sector_count, BAN::ByteSpan);
BAN::ErrorOr<void> write_sectors(uint64_t lba, uint8_t sector_count, BAN::ConstByteSpan);
virtual BAN::StringView name() const override { return m_name; }
private:
Partition(StorageDevice&, const GUID&, const GUID&, uint64_t, uint64_t, uint64_t, const char*, uint32_t);
private:
StorageDevice& m_device;
const GUID m_type;
const GUID m_guid;
const uint64_t m_lba_start;
const uint64_t m_lba_end;
const uint64_t m_attributes;
char m_label[36 * 4 + 1];
const BAN::String m_name;
public:
virtual bool is_partition() const override { return true; }
virtual dev_t rdev() const override { return m_rdev; }
protected:
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
private:
const dev_t m_rdev;
};
class StorageDevice : public BlockDevice class StorageDevice : public BlockDevice
{ {
public: public:
@ -70,8 +18,8 @@ namespace Kernel
BAN::ErrorOr<void> initialize_partitions(); BAN::ErrorOr<void> initialize_partitions();
BAN::ErrorOr<void> read_sectors(uint64_t lba, uint64_t sector_count, BAN::ByteSpan); BAN::ErrorOr<void> read_sectors(uint64_t lba, size_t sector_count, BAN::ByteSpan);
BAN::ErrorOr<void> write_sectors(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan); BAN::ErrorOr<void> write_sectors(uint64_t lba, size_t sector_count, BAN::ConstByteSpan);
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;

View File

@ -0,0 +1,70 @@
#include <kernel/Storage/Partition.h>
#include <sys/sysmacros.h>
namespace Kernel
{
BAN::ErrorOr<BAN::RefPtr<Partition>> Partition::create(BAN::RefPtr<BlockDevice> device, const BAN::GUID& type, const BAN::GUID& guid, uint64_t first_sector, uint64_t last_sector, uint64_t attr, const char* label, uint32_t index)
{
auto partition_ptr = new Partition(device, type, guid, first_sector, last_sector, attr, label, index);
if (partition_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::RefPtr<Partition>::adopt(partition_ptr);
}
Partition::Partition(BAN::RefPtr<BlockDevice> device, const BAN::GUID& type, const BAN::GUID& guid, uint64_t first_sector, uint64_t last_sector, uint64_t attr, const char* label, uint32_t index)
: BlockDevice(0660, 0, 0)
, m_device(device)
, m_type(type)
, m_guid(guid)
, m_first_sector(first_sector)
, m_last_sector(last_sector)
, m_attributes(attr)
, m_name(BAN::String::formatted("{}{}", device->name(), index))
, m_rdev(makedev(major(device->rdev()), index))
{
memcpy(m_label, label, sizeof(m_label));
}
BAN::ErrorOr<void> Partition::read_sectors(uint64_t first_sector, size_t sector_count, BAN::ByteSpan buffer)
{
ASSERT(buffer.size() >= sector_count * m_device->blksize());
const uint32_t sectors_in_partition = m_last_sector - m_first_sector + 1;
if (first_sector + sector_count > sectors_in_partition)
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
TRY(m_device->read_sectors(m_first_sector + first_sector, sector_count, buffer));
return {};
}
BAN::ErrorOr<void> Partition::write_sectors(uint64_t first_sector, size_t sector_count, BAN::ConstByteSpan buffer)
{
ASSERT(buffer.size() >= sector_count * m_device->blksize());
const uint32_t sectors_in_partition = m_last_sector - m_first_sector + 1;
if (m_first_sector + sector_count > sectors_in_partition)
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
TRY(m_device->write_sectors(m_first_sector + first_sector, sector_count, buffer));
return {};
}
BAN::ErrorOr<size_t> Partition::read_impl(off_t offset, BAN::ByteSpan buffer)
{
ASSERT(offset >= 0);
if (offset % m_device->blksize() || buffer.size() % m_device->blksize())
return BAN::Error::from_errno(ENOTSUP);
const uint32_t sectors_in_partition = m_last_sector - m_first_sector + 1;
uint32_t first_sector = offset / m_device->blksize();
uint32_t sector_count = buffer.size() / m_device->blksize();
if (first_sector >= sectors_in_partition)
return 0;
if (first_sector + sector_count > sectors_in_partition)
sector_count = sectors_in_partition - first_sector;
TRY(read_sectors(first_sector, sector_count, buffer));
return sector_count * m_device->blksize();
}
}

View File

@ -9,12 +9,6 @@
#include <kernel/Storage/StorageDevice.h> #include <kernel/Storage/StorageDevice.h>
#include <kernel/Thread.h> #include <kernel/Thread.h>
#include <sys/sysmacros.h>
#define ATA_DEVICE_PRIMARY 0x1F0
#define ATA_DEVICE_SECONDARY 0x170
#define ATA_DEVICE_SLAVE_BIT 0x10
namespace Kernel namespace Kernel
{ {
@ -29,7 +23,7 @@ namespace Kernel
BAN::LittleEndian<uint64_t> alternate_lba; BAN::LittleEndian<uint64_t> alternate_lba;
BAN::LittleEndian<uint64_t> first_usable_lba; BAN::LittleEndian<uint64_t> first_usable_lba;
BAN::LittleEndian<uint64_t> last_usable_lba; BAN::LittleEndian<uint64_t> last_usable_lba;
GUID disk_guid; BAN::GUID disk_guid;
BAN::LittleEndian<uint64_t> partition_entry_lba; BAN::LittleEndian<uint64_t> partition_entry_lba;
BAN::LittleEndian<uint32_t> partition_entry_count; BAN::LittleEndian<uint32_t> partition_entry_count;
BAN::LittleEndian<uint32_t> partition_entry_size; BAN::LittleEndian<uint32_t> partition_entry_size;
@ -38,8 +32,8 @@ namespace Kernel
struct PartitionEntry struct PartitionEntry
{ {
GUID partition_type_guid; BAN::GUID partition_type_guid;
GUID unique_partition_guid; BAN::GUID unique_partition_guid;
BAN::LittleEndian<uint64_t> starting_lba; BAN::LittleEndian<uint64_t> starting_lba;
BAN::LittleEndian<uint64_t> ending_lba; BAN::LittleEndian<uint64_t> ending_lba;
BAN::LittleEndian<uint64_t> attributes; BAN::LittleEndian<uint64_t> attributes;
@ -180,15 +174,15 @@ 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 {}; BAN::GUID zero {};
if (memcmp(&entry.partition_type_guid, &zero, sizeof(GUID)) == 0) if (memcmp(&entry.partition_type_guid, &zero, sizeof(BAN::GUID)) == 0)
continue; 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);
auto partition = TRY(Partition::create( auto partition = TRY(Partition::create(
*this, this,
entry.partition_type_guid, entry.partition_type_guid,
entry.unique_partition_guid, entry.unique_partition_guid,
entry.starting_lba, entry.starting_lba,
@ -206,68 +200,6 @@ namespace Kernel
return {}; return {};
} }
BAN::ErrorOr<BAN::RefPtr<Partition>> Partition::create(StorageDevice& device, const GUID& type, const GUID& guid, uint64_t start, uint64_t end, uint64_t attr, const char* label, uint32_t index)
{
auto partition_ptr = new Partition(device, type, guid, start, end, attr, label, index);
if (partition_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::RefPtr<Partition>::adopt(partition_ptr);
}
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)
: 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_name(BAN::String::formatted("{}{}", device.name(), index))
, m_rdev(makedev(major(device.rdev()), index))
{
memcpy(m_label, label, sizeof(m_label));
}
BAN::ErrorOr<void> Partition::read_sectors(uint64_t lba, uint8_t sector_count, BAN::ByteSpan buffer)
{
ASSERT(buffer.size() >= sector_count * m_device.sector_size());
const uint32_t sectors_in_partition = m_lba_end - m_lba_start;
if (lba + sector_count > sectors_in_partition)
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
TRY(m_device.read_sectors(m_lba_start + lba, sector_count, buffer));
return {};
}
BAN::ErrorOr<void> Partition::write_sectors(uint64_t lba, uint8_t sector_count, BAN::ConstByteSpan buffer)
{
ASSERT(buffer.size() >= sector_count * m_device.sector_size());
const uint32_t sectors_in_partition = m_lba_end - m_lba_start;
if (lba + sector_count > sectors_in_partition)
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
TRY(m_device.write_sectors(m_lba_start + lba, sector_count, buffer));
return {};
}
BAN::ErrorOr<size_t> Partition::read_impl(off_t offset, BAN::ByteSpan buffer)
{
ASSERT(offset >= 0);
if (offset % m_device.sector_size() || buffer.size() % m_device.sector_size())
return BAN::Error::from_errno(ENOTSUP);
const uint32_t sectors_in_partition = m_lba_end - m_lba_start;
uint32_t lba = offset / m_device.sector_size();
uint32_t sector_count = buffer.size() / m_device.sector_size();
if (lba == sectors_in_partition)
return 0;
if (lba + sector_count > sectors_in_partition)
sector_count = sectors_in_partition - lba;
TRY(read_sectors(lba, sector_count, buffer));
return sector_count * m_device.sector_size();
}
StorageDevice::~StorageDevice() StorageDevice::~StorageDevice()
{ {
} }
@ -287,7 +219,7 @@ namespace Kernel
return {}; return {};
} }
BAN::ErrorOr<void> StorageDevice::read_sectors(uint64_t lba, uint64_t sector_count, BAN::ByteSpan buffer) BAN::ErrorOr<void> StorageDevice::read_sectors(uint64_t lba, size_t sector_count, BAN::ByteSpan buffer)
{ {
ASSERT(buffer.size() >= sector_count * sector_size()); ASSERT(buffer.size() >= sector_count * sector_size());
@ -313,7 +245,7 @@ namespace Kernel
return {}; return {};
} }
BAN::ErrorOr<void> StorageDevice::write_sectors(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan buffer) BAN::ErrorOr<void> StorageDevice::write_sectors(uint64_t lba, size_t sector_count, BAN::ConstByteSpan buffer)
{ {
ASSERT(buffer.size() >= sector_count * sector_size()); ASSERT(buffer.size() >= sector_count * sector_size());
@ -337,4 +269,4 @@ namespace Kernel
return {}; return {};
} }
} }