Kernel: StorageDevices and Controllers are now devices

This commit is contained in:
Bananymous
2023-03-30 14:22:15 +03:00
parent 88a8bd659d
commit e2791e5260
9 changed files with 190 additions and 112 deletions

View File

@@ -1,12 +1,20 @@
#include <BAN/Time.h>
#include <kernel/Device.h>
#include <kernel/LockGuard.h>
#include <kernel/PCI.h>
#include <kernel/Process.h>
#include <kernel/RTC.h>
#include <kernel/Storage/ATAController.h>
namespace Kernel
{
static DeviceManager* s_instance = nullptr;
Device::Device()
: m_create_time({ BAN::to_unix_time(RTC::get_current_time()), 0 })
{ }
void DeviceManager::initialize()
{
ASSERT(s_instance == nullptr);
@@ -14,6 +22,43 @@ namespace Kernel
s_instance = new DeviceManager;
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(
[](void*)
{

View File

@@ -1,3 +1,4 @@
#include <BAN/ScopeGuard.h>
#include <BAN/StringView.h>
#include <BAN/Vector.h>
#include <kernel/Device.h>
@@ -17,13 +18,13 @@ namespace Kernel
s_instance = new VirtualFileSystem();
if (s_instance == nullptr)
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())
{
delete s_instance;
s_instance = nullptr;
return res;
}
auto partition_inode = TRY(DeviceManager::get().read_directory_inode("hda1"));
s_instance->m_root_fs = TRY(Ext2FS::create(*(Partition*)partition_inode.ptr()));
TRY(s_instance->mount(&DeviceManager::get(), "/dev"));
guard.disable();
return {};
}
@@ -34,91 +35,6 @@ namespace Kernel
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)
{
auto file = TRY(file_from_absolute_path(path));

View File

@@ -94,6 +94,11 @@ namespace Kernel
device.bus = &bus;
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);
PIT::sleep(1);
@@ -162,7 +167,15 @@ namespace Kernel
}
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();
}
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;
}
}

View File

@@ -168,32 +168,41 @@ namespace Kernel
{
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];
BAN::UTF8::from_codepoints(entry.partition_name, 36, utf8_name);
MUST(m_partitions.emplace_back(
Partition* partition = new Partition(
*this,
entry.partition_type_guid,
entry.unique_partition_guid,
entry.starting_lba,
entry.ending_lba,
entry.attributes,
utf8_name
));
utf8_name,
i
);
ASSERT(partition != nullptr);
MUST(m_partitions.push_back(partition));
}
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_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))
{
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)
@@ -214,4 +223,22 @@ namespace Kernel
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;
}
}