mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:37:35 +00:00
Kernel: Introduce the new SysFS
The intention is to add dynamic mechanism for notifying the userspace about hotplug events. Currently, the DMI (SMBIOS) blobs and ACPI tables are exposed in the new filesystem.
This commit is contained in:
parent
dc6defa7af
commit
92c0dab5ab
13 changed files with 839 additions and 202 deletions
|
@ -27,6 +27,79 @@ Parser* Parser::the()
|
||||||
return s_acpi_parser;
|
return s_acpi_parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT NonnullRefPtr<ExposedComponent> ExposedComponent::create(String name, PhysicalAddress paddr, size_t table_size)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) ExposedComponent(name, paddr, table_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<size_t> ExposedComponent::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription*) const
|
||||||
|
{
|
||||||
|
auto blob = try_to_generate_buffer();
|
||||||
|
if (!blob)
|
||||||
|
return KResult(EFAULT);
|
||||||
|
|
||||||
|
if ((size_t)offset >= blob->size())
|
||||||
|
return KSuccess;
|
||||||
|
|
||||||
|
ssize_t nread = min(static_cast<off_t>(blob->size() - offset), static_cast<off_t>(count));
|
||||||
|
if (!buffer.write(blob->data() + offset, nread))
|
||||||
|
return KResult(EFAULT);
|
||||||
|
return nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnPtr<KBuffer> ExposedComponent::try_to_generate_buffer() const
|
||||||
|
{
|
||||||
|
auto acpi_blob = map_typed<u8>((m_paddr), m_length);
|
||||||
|
return KBuffer::try_create_with_bytes(Span<u8> { acpi_blob.ptr(), m_length });
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT ExposedComponent::ExposedComponent(String name, PhysicalAddress paddr, size_t table_size)
|
||||||
|
: SystemExposedComponent(name)
|
||||||
|
, m_paddr(paddr)
|
||||||
|
, m_length(table_size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void ExposedFolder::initialize()
|
||||||
|
{
|
||||||
|
auto acpi_folder = adopt_ref(*new (nothrow) ExposedFolder());
|
||||||
|
SystemRegistrar::the().register_new_component(acpi_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT ExposedFolder::ExposedFolder()
|
||||||
|
: SystemExposedFolder("acpi", SystemRegistrar::the().root_folder())
|
||||||
|
{
|
||||||
|
NonnullRefPtrVector<SystemExposedComponent> components;
|
||||||
|
size_t ssdt_count = 0;
|
||||||
|
ACPI::Parser::the()->enumerate_static_tables([&](const StringView& signature, PhysicalAddress p_table, size_t length) {
|
||||||
|
if (signature == "SSDT") {
|
||||||
|
components.append(ExposedComponent::create(String::formatted("{:4s}{}", signature.characters_without_null_termination(), ssdt_count), p_table, length));
|
||||||
|
ssdt_count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
components.append(ExposedComponent::create(signature, p_table, length));
|
||||||
|
});
|
||||||
|
m_components = components;
|
||||||
|
|
||||||
|
auto rsdp = map_typed<Structures::RSDPDescriptor20>(ACPI::Parser::the()->rsdp());
|
||||||
|
m_components.append(ExposedComponent::create("RSDP", ACPI::Parser::the()->rsdp(), rsdp->base.revision == 0 ? sizeof(Structures::RSDPDescriptor) : rsdp->length));
|
||||||
|
|
||||||
|
auto main_system_description_table = map_typed<Structures::SDTHeader>(ACPI::Parser::the()->main_system_description_table());
|
||||||
|
if (ACPI::Parser::the()->is_xsdt_supported()) {
|
||||||
|
m_components.append(ExposedComponent::create("XSDT", ACPI::Parser::the()->main_system_description_table(), main_system_description_table->length));
|
||||||
|
} else {
|
||||||
|
m_components.append(ExposedComponent::create("RSDT", ACPI::Parser::the()->main_system_description_table(), main_system_description_table->length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::enumerate_static_tables(Function<void(const StringView&, PhysicalAddress, size_t)> callback)
|
||||||
|
{
|
||||||
|
for (auto& p_table : m_sdt_pointers) {
|
||||||
|
auto table = map_typed<Structures::SDTHeader>(p_table);
|
||||||
|
callback({ table->sig, 4 }, p_table, table->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::set_the(Parser& parser)
|
void Parser::set_the(Parser& parser)
|
||||||
{
|
{
|
||||||
VERIFY(!s_acpi_parser);
|
VERIFY(!s_acpi_parser);
|
||||||
|
|
|
@ -9,14 +9,36 @@
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/ACPI/Definitions.h>
|
#include <Kernel/ACPI/Definitions.h>
|
||||||
#include <Kernel/ACPI/Initialize.h>
|
#include <Kernel/ACPI/Initialize.h>
|
||||||
#include <Kernel/FileSystem/File.h>
|
|
||||||
#include <Kernel/PhysicalAddress.h>
|
#include <Kernel/PhysicalAddress.h>
|
||||||
|
#include <Kernel/SystemExposed.h>
|
||||||
#include <Kernel/VM/Region.h>
|
#include <Kernel/VM/Region.h>
|
||||||
#include <Kernel/VirtualAddress.h>
|
#include <Kernel/VirtualAddress.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
namespace ACPI {
|
namespace ACPI {
|
||||||
|
|
||||||
|
class ExposedFolder : public SystemExposedFolder {
|
||||||
|
public:
|
||||||
|
static void initialize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ExposedFolder();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExposedComponent : public SystemExposedComponent {
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<ExposedComponent> create(String name, PhysicalAddress, size_t table_size);
|
||||||
|
|
||||||
|
virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
OwnPtr<KBuffer> try_to_generate_buffer() const;
|
||||||
|
ExposedComponent(String name, PhysicalAddress, size_t table_size);
|
||||||
|
|
||||||
|
PhysicalAddress m_paddr;
|
||||||
|
size_t m_length;
|
||||||
|
};
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
public:
|
public:
|
||||||
static Parser* the();
|
static Parser* the();
|
||||||
|
|
|
@ -1,16 +1,165 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <Kernel/Arch/PC/BIOS.h>
|
#include <Kernel/Arch/PC/BIOS.h>
|
||||||
|
#include <Kernel/FileSystem/FileDescription.h>
|
||||||
|
#include <Kernel/KBufferBuilder.h>
|
||||||
|
#include <Kernel/Sections.h>
|
||||||
#include <Kernel/VM/MemoryManager.h>
|
#include <Kernel/VM/MemoryManager.h>
|
||||||
#include <Kernel/VM/TypedMapping.h>
|
#include <Kernel/VM/TypedMapping.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
#define SMBIOS_BASE_SEARCH_ADDR 0xf0000
|
||||||
|
#define SMBIOS_END_SEARCH_ADDR 0xfffff
|
||||||
|
#define SMBIOS_SEARCH_AREA_SIZE (SMBIOS_END_SEARCH_ADDR - SMBIOS_BASE_SEARCH_ADDR)
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT NonnullRefPtr<DMIEntryPointExposedBlob> DMIEntryPointExposedBlob::create(PhysicalAddress dmi_entry_point, size_t blob_size)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) DMIEntryPointExposedBlob(dmi_entry_point, blob_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT BIOSExposedComponent::BIOSExposedComponent(String name)
|
||||||
|
: SystemExposedComponent(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<size_t> BIOSExposedComponent::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription*) const
|
||||||
|
{
|
||||||
|
auto blob = try_to_generate_buffer();
|
||||||
|
if (!blob)
|
||||||
|
return KResult(EFAULT);
|
||||||
|
|
||||||
|
if ((size_t)offset >= blob->size())
|
||||||
|
return KSuccess;
|
||||||
|
|
||||||
|
ssize_t nread = min(static_cast<off_t>(blob->size() - offset), static_cast<off_t>(count));
|
||||||
|
if (!buffer.write(blob->data() + offset, nread))
|
||||||
|
return KResult(EFAULT);
|
||||||
|
return nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT DMIEntryPointExposedBlob::DMIEntryPointExposedBlob(PhysicalAddress dmi_entry_point, size_t blob_size)
|
||||||
|
: BIOSExposedComponent("smbios_entry_point")
|
||||||
|
, m_dmi_entry_point(dmi_entry_point)
|
||||||
|
, m_dmi_entry_point_length(blob_size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnPtr<KBuffer> DMIEntryPointExposedBlob::try_to_generate_buffer() const
|
||||||
|
{
|
||||||
|
auto dmi_blob = map_typed<u8>((m_dmi_entry_point), m_dmi_entry_point_length);
|
||||||
|
return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_dmi_entry_point_length });
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT NonnullRefPtr<SMBIOSExposedTable> SMBIOSExposedTable::create(PhysicalAddress smbios_structure_table, size_t smbios_structure_table_length)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) SMBIOSExposedTable(smbios_structure_table, smbios_structure_table_length));
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT SMBIOSExposedTable::SMBIOSExposedTable(PhysicalAddress smbios_structure_table, size_t smbios_structure_table_length)
|
||||||
|
: BIOSExposedComponent("DMI")
|
||||||
|
, m_smbios_structure_table(smbios_structure_table)
|
||||||
|
, m_smbios_structure_table_length(smbios_structure_table_length)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnPtr<KBuffer> SMBIOSExposedTable::try_to_generate_buffer() const
|
||||||
|
{
|
||||||
|
auto dmi_blob = map_typed<u8>((m_smbios_structure_table), m_smbios_structure_table_length);
|
||||||
|
return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_smbios_structure_table_length });
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void BIOSExposedFolder::set_dmi_64_bit_entry_initialization_values()
|
||||||
|
{
|
||||||
|
dbgln("BIOSExposedFolder: SMBIOS 64bit Entry point @ {}", m_dmi_entry_point);
|
||||||
|
auto smbios_entry = map_typed<SMBIOS::EntryPoint64bit>(m_dmi_entry_point, SMBIOS_SEARCH_AREA_SIZE);
|
||||||
|
m_smbios_structure_table = PhysicalAddress(smbios_entry.ptr()->table_ptr);
|
||||||
|
m_dmi_entry_point_length = smbios_entry.ptr()->length;
|
||||||
|
m_smbios_structure_table_length = smbios_entry.ptr()->table_maximum_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void BIOSExposedFolder::set_dmi_32_bit_entry_initialization_values()
|
||||||
|
{
|
||||||
|
dbgln("BIOSExposedFolder: SMBIOS 32bit Entry point @ {}", m_dmi_entry_point);
|
||||||
|
auto smbios_entry = map_typed<SMBIOS::EntryPoint32bit>(m_dmi_entry_point, SMBIOS_SEARCH_AREA_SIZE);
|
||||||
|
m_smbios_structure_table = PhysicalAddress(smbios_entry.ptr()->legacy_structure.smbios_table_ptr);
|
||||||
|
m_dmi_entry_point_length = smbios_entry.ptr()->length;
|
||||||
|
m_smbios_structure_table_length = smbios_entry.ptr()->legacy_structure.smboios_table_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void BIOSExposedFolder::initialize()
|
||||||
|
{
|
||||||
|
auto bios_folder = adopt_ref(*new (nothrow) BIOSExposedFolder());
|
||||||
|
SystemRegistrar::the().register_new_component(bios_folder);
|
||||||
|
bios_folder->create_components();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BIOSExposedFolder::create_components()
|
||||||
|
{
|
||||||
|
auto dmi_entry_point = DMIEntryPointExposedBlob::create(m_dmi_entry_point, m_dmi_entry_point_length);
|
||||||
|
m_components.append(dmi_entry_point);
|
||||||
|
auto smbios_table = SMBIOSExposedTable::create(m_smbios_structure_table, m_smbios_structure_table_length);
|
||||||
|
m_components.append(smbios_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BIOSExposedFolder::dmi_entry_point_length() const
|
||||||
|
{
|
||||||
|
return m_dmi_entry_point_length;
|
||||||
|
}
|
||||||
|
size_t BIOSExposedFolder::smbios_structure_table_length() const
|
||||||
|
{
|
||||||
|
return m_smbios_structure_table_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void BIOSExposedFolder::initialize_dmi_exposer()
|
||||||
|
{
|
||||||
|
VERIFY(!(m_dmi_entry_point.is_null()));
|
||||||
|
if (m_using_64bit_dmi_entry_point) {
|
||||||
|
set_dmi_64_bit_entry_initialization_values();
|
||||||
|
} else {
|
||||||
|
set_dmi_32_bit_entry_initialization_values();
|
||||||
|
}
|
||||||
|
dbgln("BIOSExposedFolder: Data table @ {}", m_smbios_structure_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnPtr<KBuffer> BIOSExposedFolder::smbios_structure_table() const
|
||||||
|
{
|
||||||
|
auto dmi_blob = map_typed<u8>(m_smbios_structure_table, m_smbios_structure_table_length);
|
||||||
|
return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_smbios_structure_table_length });
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT BIOSExposedFolder::BIOSExposedFolder()
|
||||||
|
: SystemExposedFolder("bios", SystemRegistrar::the().root_folder())
|
||||||
|
{
|
||||||
|
auto entry_32bit = find_dmi_entry32bit_point();
|
||||||
|
m_dmi_entry_point = entry_32bit.value();
|
||||||
|
|
||||||
|
auto entry_64bit = find_dmi_entry64bit_point();
|
||||||
|
if (entry_64bit.has_value()) {
|
||||||
|
m_dmi_entry_point = entry_64bit.value();
|
||||||
|
m_using_64bit_dmi_entry_point = true;
|
||||||
|
}
|
||||||
|
if (m_dmi_entry_point.is_null())
|
||||||
|
return;
|
||||||
|
initialize_dmi_exposer();
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT Optional<PhysicalAddress> BIOSExposedFolder::find_dmi_entry64bit_point()
|
||||||
|
{
|
||||||
|
return map_bios().find_chunk_starting_with("_SM3_", 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT Optional<PhysicalAddress> BIOSExposedFolder::find_dmi_entry32bit_point()
|
||||||
|
{
|
||||||
|
return map_bios().find_chunk_starting_with("_SM_", 16);
|
||||||
|
}
|
||||||
|
|
||||||
MappedROM map_bios()
|
MappedROM map_bios()
|
||||||
{
|
{
|
||||||
MappedROM mapping;
|
MappedROM mapping;
|
||||||
|
|
|
@ -1,16 +1,123 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Types.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
|
#include <Kernel/FileSystem/SysFS.h>
|
||||||
|
#include <Kernel/KBuffer.h>
|
||||||
|
#include <Kernel/PhysicalAddress.h>
|
||||||
#include <Kernel/VM/MappedROM.h>
|
#include <Kernel/VM/MappedROM.h>
|
||||||
|
#include <Kernel/VM/Region.h>
|
||||||
|
#include <Kernel/VirtualAddress.h>
|
||||||
|
|
||||||
|
namespace Kernel::SMBIOS {
|
||||||
|
|
||||||
|
struct [[gnu::packed]] LegacyEntryPoint32bit {
|
||||||
|
char legacy_sig[5];
|
||||||
|
u8 checksum2;
|
||||||
|
u16 smboios_table_length;
|
||||||
|
u32 smbios_table_ptr;
|
||||||
|
u16 smbios_tables_count;
|
||||||
|
u8 smbios_bcd_revision;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] EntryPoint32bit {
|
||||||
|
char sig[4];
|
||||||
|
u8 checksum;
|
||||||
|
u8 length;
|
||||||
|
u8 major_version;
|
||||||
|
u8 minor_version;
|
||||||
|
u16 maximum_structure_size;
|
||||||
|
u8 implementation_revision;
|
||||||
|
char formatted_area[5];
|
||||||
|
LegacyEntryPoint32bit legacy_structure;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] EntryPoint64bit {
|
||||||
|
char sig[5];
|
||||||
|
u8 checksum;
|
||||||
|
u8 length;
|
||||||
|
u8 major_version;
|
||||||
|
u8 minor_version;
|
||||||
|
u8 document_revision;
|
||||||
|
u8 revision;
|
||||||
|
u8 reserved;
|
||||||
|
u32 table_maximum_size;
|
||||||
|
u64 table_ptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
MappedROM map_bios();
|
MappedROM map_bios();
|
||||||
MappedROM map_ebda();
|
MappedROM map_ebda();
|
||||||
|
|
||||||
|
class BIOSExposedComponent : public SystemExposedComponent {
|
||||||
|
public:
|
||||||
|
virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual OwnPtr<KBuffer> try_to_generate_buffer() const = 0;
|
||||||
|
explicit BIOSExposedComponent(String name);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DMIEntryPointExposedBlob : public BIOSExposedComponent {
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<DMIEntryPointExposedBlob> create(PhysicalAddress dmi_entry_point, size_t blob_size);
|
||||||
|
virtual size_t size() const override { return m_dmi_entry_point_length; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
DMIEntryPointExposedBlob(PhysicalAddress dmi_entry_point, size_t blob_size);
|
||||||
|
virtual OwnPtr<KBuffer> try_to_generate_buffer() const override;
|
||||||
|
PhysicalAddress m_dmi_entry_point;
|
||||||
|
size_t m_dmi_entry_point_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SMBIOSExposedTable : public BIOSExposedComponent {
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<SMBIOSExposedTable> create(PhysicalAddress, size_t blob_size);
|
||||||
|
virtual size_t size() const override { return m_smbios_structure_table_length; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SMBIOSExposedTable(PhysicalAddress dmi_entry_point, size_t blob_size);
|
||||||
|
virtual OwnPtr<KBuffer> try_to_generate_buffer() const override;
|
||||||
|
|
||||||
|
PhysicalAddress m_smbios_structure_table;
|
||||||
|
size_t m_smbios_structure_table_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BIOSExposedFolder : public SystemExposedFolder {
|
||||||
|
public:
|
||||||
|
static void initialize();
|
||||||
|
|
||||||
|
void create_components();
|
||||||
|
|
||||||
|
private:
|
||||||
|
OwnPtr<KBuffer> dmi_entry_point() const;
|
||||||
|
OwnPtr<KBuffer> smbios_structure_table() const;
|
||||||
|
size_t dmi_entry_point_length() const;
|
||||||
|
size_t smbios_structure_table_length() const;
|
||||||
|
|
||||||
|
BIOSExposedFolder();
|
||||||
|
|
||||||
|
void set_dmi_64_bit_entry_initialization_values();
|
||||||
|
void set_dmi_32_bit_entry_initialization_values();
|
||||||
|
void initialize_dmi_exposer();
|
||||||
|
|
||||||
|
Optional<PhysicalAddress> find_dmi_entry64bit_point();
|
||||||
|
Optional<PhysicalAddress> find_dmi_entry32bit_point();
|
||||||
|
|
||||||
|
PhysicalAddress m_dmi_entry_point;
|
||||||
|
PhysicalAddress m_smbios_structure_table;
|
||||||
|
bool m_using_64bit_dmi_entry_point { false };
|
||||||
|
size_t m_smbios_structure_table_length { 0 };
|
||||||
|
size_t m_dmi_entry_point_length { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ set(KERNEL_SOURCES
|
||||||
CommandLine.cpp
|
CommandLine.cpp
|
||||||
ConsoleDevice.cpp
|
ConsoleDevice.cpp
|
||||||
CoreDump.cpp
|
CoreDump.cpp
|
||||||
DMI.cpp
|
|
||||||
Devices/AsyncDeviceRequest.cpp
|
Devices/AsyncDeviceRequest.cpp
|
||||||
Devices/BlockDevice.cpp
|
Devices/BlockDevice.cpp
|
||||||
Devices/CharacterDevice.cpp
|
Devices/CharacterDevice.cpp
|
||||||
|
@ -107,6 +106,7 @@ set(KERNEL_SOURCES
|
||||||
FileSystem/InodeWatcher.cpp
|
FileSystem/InodeWatcher.cpp
|
||||||
FileSystem/Plan9FileSystem.cpp
|
FileSystem/Plan9FileSystem.cpp
|
||||||
FileSystem/ProcFS.cpp
|
FileSystem/ProcFS.cpp
|
||||||
|
FileSystem/SysFS.cpp
|
||||||
FileSystem/TmpFS.cpp
|
FileSystem/TmpFS.cpp
|
||||||
FileSystem/VirtualFileSystem.cpp
|
FileSystem/VirtualFileSystem.cpp
|
||||||
FutexQueue.cpp
|
FutexQueue.cpp
|
||||||
|
@ -225,6 +225,7 @@ set(KERNEL_SOURCES
|
||||||
Syscalls/waitid.cpp
|
Syscalls/waitid.cpp
|
||||||
Syscalls/inode_watcher.cpp
|
Syscalls/inode_watcher.cpp
|
||||||
Syscalls/write.cpp
|
Syscalls/write.cpp
|
||||||
|
SystemExposed.cpp
|
||||||
TTY/ConsoleManagement.cpp
|
TTY/ConsoleManagement.cpp
|
||||||
TTY/MasterPTY.cpp
|
TTY/MasterPTY.cpp
|
||||||
TTY/PTYMultiplexer.cpp
|
TTY/PTYMultiplexer.cpp
|
||||||
|
|
111
Kernel/DMI.cpp
111
Kernel/DMI.cpp
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <AK/Format.h>
|
|
||||||
#include <AK/Singleton.h>
|
|
||||||
#include <AK/StringView.h>
|
|
||||||
#include <AK/Types.h>
|
|
||||||
#include <Kernel/Arch/PC/BIOS.h>
|
|
||||||
#include <Kernel/DMI.h>
|
|
||||||
#include <Kernel/Sections.h>
|
|
||||||
#include <Kernel/StdLib.h>
|
|
||||||
#include <Kernel/VM/MappedROM.h>
|
|
||||||
#include <Kernel/VM/TypedMapping.h>
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
#define SMBIOS_BASE_SEARCH_ADDR 0xf0000
|
|
||||||
#define SMBIOS_END_SEARCH_ADDR 0xfffff
|
|
||||||
#define SMBIOS_SEARCH_AREA_SIZE (SMBIOS_END_SEARCH_ADDR - SMBIOS_BASE_SEARCH_ADDR)
|
|
||||||
|
|
||||||
AK::Singleton<DMIExpose> s_the;
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT void DMIExpose::set_64_bit_entry_initialization_values()
|
|
||||||
{
|
|
||||||
dbgln("DMIExpose: SMBIOS 64bit Entry point @ {}", m_entry_point);
|
|
||||||
auto smbios_entry = map_typed<SMBIOS::EntryPoint64bit>(m_entry_point, SMBIOS_SEARCH_AREA_SIZE);
|
|
||||||
m_structure_table = PhysicalAddress(smbios_entry.ptr()->table_ptr);
|
|
||||||
m_entry_point_length = smbios_entry.ptr()->length;
|
|
||||||
m_structure_table_length = smbios_entry.ptr()->table_maximum_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT void DMIExpose::set_32_bit_entry_initialization_values()
|
|
||||||
{
|
|
||||||
dbgln("DMIExpose: SMBIOS 32bit Entry point @ {}", m_entry_point);
|
|
||||||
auto smbios_entry = map_typed<SMBIOS::EntryPoint32bit>(m_entry_point, SMBIOS_SEARCH_AREA_SIZE);
|
|
||||||
m_structure_table = PhysicalAddress(smbios_entry.ptr()->legacy_structure.smbios_table_ptr);
|
|
||||||
m_entry_point_length = smbios_entry.ptr()->length;
|
|
||||||
m_structure_table_length = smbios_entry.ptr()->legacy_structure.smboios_table_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT void DMIExpose::initialize()
|
|
||||||
{
|
|
||||||
s_the.ensure_instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
DMIExpose& DMIExpose::the()
|
|
||||||
{
|
|
||||||
return *s_the;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DMIExpose::entry_point_length() const
|
|
||||||
{
|
|
||||||
return m_entry_point_length;
|
|
||||||
}
|
|
||||||
size_t DMIExpose::structure_table_length() const
|
|
||||||
{
|
|
||||||
return m_structure_table_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT void DMIExpose::initialize_exposer()
|
|
||||||
{
|
|
||||||
VERIFY(!(m_entry_point.is_null()));
|
|
||||||
if (m_using_64bit_entry_point) {
|
|
||||||
set_64_bit_entry_initialization_values();
|
|
||||||
} else {
|
|
||||||
set_32_bit_entry_initialization_values();
|
|
||||||
}
|
|
||||||
dbgln("DMIExpose: Data table @ {}", m_structure_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
OwnPtr<KBuffer> DMIExpose::entry_point() const
|
|
||||||
{
|
|
||||||
auto dmi_blob = map_typed<u8>((m_entry_point), m_entry_point_length);
|
|
||||||
return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_entry_point_length });
|
|
||||||
}
|
|
||||||
OwnPtr<KBuffer> DMIExpose::structure_table() const
|
|
||||||
{
|
|
||||||
auto dmi_blob = map_typed<u8>(m_structure_table, m_structure_table_length);
|
|
||||||
return KBuffer::try_create_with_bytes(Span<u8> { dmi_blob.ptr(), m_structure_table_length });
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT DMIExpose::DMIExpose()
|
|
||||||
{
|
|
||||||
auto entry_32bit = find_entry32bit_point();
|
|
||||||
m_entry_point = entry_32bit.value();
|
|
||||||
|
|
||||||
auto entry_64bit = find_entry64bit_point();
|
|
||||||
if (entry_64bit.has_value()) {
|
|
||||||
m_entry_point = entry_64bit.value();
|
|
||||||
m_using_64bit_entry_point = true;
|
|
||||||
}
|
|
||||||
if (m_entry_point.is_null())
|
|
||||||
return;
|
|
||||||
m_available = true;
|
|
||||||
initialize_exposer();
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT Optional<PhysicalAddress> DMIExpose::find_entry64bit_point()
|
|
||||||
{
|
|
||||||
return map_bios().find_chunk_starting_with("_SM3_", 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT Optional<PhysicalAddress> DMIExpose::find_entry32bit_point()
|
|
||||||
{
|
|
||||||
return map_bios().find_chunk_starting_with("_SM_", 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
87
Kernel/DMI.h
87
Kernel/DMI.h
|
@ -1,87 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <AK/SinglyLinkedList.h>
|
|
||||||
#include <AK/Types.h>
|
|
||||||
#include <AK/Vector.h>
|
|
||||||
#include <Kernel/KBuffer.h>
|
|
||||||
#include <Kernel/PhysicalAddress.h>
|
|
||||||
#include <Kernel/VM/Region.h>
|
|
||||||
#include <Kernel/VirtualAddress.h>
|
|
||||||
|
|
||||||
namespace Kernel::SMBIOS {
|
|
||||||
|
|
||||||
struct [[gnu::packed]] LegacyEntryPoint32bit {
|
|
||||||
char legacy_sig[5];
|
|
||||||
u8 checksum2;
|
|
||||||
u16 smboios_table_length;
|
|
||||||
u32 smbios_table_ptr;
|
|
||||||
u16 smbios_tables_count;
|
|
||||||
u8 smbios_bcd_revision;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct [[gnu::packed]] EntryPoint32bit {
|
|
||||||
char sig[4];
|
|
||||||
u8 checksum;
|
|
||||||
u8 length;
|
|
||||||
u8 major_version;
|
|
||||||
u8 minor_version;
|
|
||||||
u16 maximum_structure_size;
|
|
||||||
u8 implementation_revision;
|
|
||||||
char formatted_area[5];
|
|
||||||
LegacyEntryPoint32bit legacy_structure;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct [[gnu::packed]] EntryPoint64bit {
|
|
||||||
char sig[5];
|
|
||||||
u8 checksum;
|
|
||||||
u8 length;
|
|
||||||
u8 major_version;
|
|
||||||
u8 minor_version;
|
|
||||||
u8 document_revision;
|
|
||||||
u8 revision;
|
|
||||||
u8 reserved;
|
|
||||||
u32 table_maximum_size;
|
|
||||||
u64 table_ptr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
class DMIExpose {
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void initialize();
|
|
||||||
|
|
||||||
DMIExpose();
|
|
||||||
|
|
||||||
static DMIExpose& the();
|
|
||||||
|
|
||||||
bool is_available() const { return m_available; }
|
|
||||||
OwnPtr<KBuffer> entry_point() const;
|
|
||||||
OwnPtr<KBuffer> structure_table() const;
|
|
||||||
size_t entry_point_length() const;
|
|
||||||
size_t structure_table_length() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void set_64_bit_entry_initialization_values();
|
|
||||||
void set_32_bit_entry_initialization_values();
|
|
||||||
void initialize_exposer();
|
|
||||||
|
|
||||||
Optional<PhysicalAddress> find_entry64bit_point();
|
|
||||||
Optional<PhysicalAddress> find_entry32bit_point();
|
|
||||||
|
|
||||||
PhysicalAddress m_entry_point;
|
|
||||||
PhysicalAddress m_structure_table;
|
|
||||||
bool m_using_64bit_entry_point { false };
|
|
||||||
bool m_available { false };
|
|
||||||
size_t m_structure_table_length { 0 };
|
|
||||||
size_t m_entry_point_length { 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
220
Kernel/FileSystem/SysFS.cpp
Normal file
220
Kernel/FileSystem/SysFS.cpp
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/Singleton.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
|
#include <AK/StringView.h>
|
||||||
|
#include <Kernel/FileSystem/SysFS.h>
|
||||||
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||||
|
#include <Kernel/Sections.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
static InodeIndex s_next_inode_index;
|
||||||
|
static AK::Singleton<SystemRegistrar> s_the;
|
||||||
|
|
||||||
|
SystemRegistrar& SystemRegistrar::the()
|
||||||
|
{
|
||||||
|
return *s_the;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void SystemRegistrar::initialize()
|
||||||
|
{
|
||||||
|
VERIFY(!s_the.is_initialized());
|
||||||
|
s_next_inode_index = 0;
|
||||||
|
s_the.ensure_instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT SystemRegistrar::SystemRegistrar()
|
||||||
|
: m_root_folder(SysFSRootFolder::create())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UNMAP_AFTER_INIT void SystemRegistrar::register_new_component(SystemExposedComponent& component)
|
||||||
|
{
|
||||||
|
Locker locker(m_lock);
|
||||||
|
m_root_folder->m_components.append(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<SysFSRootFolder> SysFSRootFolder::create()
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) SysFSRootFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SysFSRootFolder::traverse_as_directory(unsigned fsid, Function<bool(const FS::DirectoryEntryView&)> callback) const
|
||||||
|
{
|
||||||
|
Locker locker(SystemRegistrar::the().m_lock);
|
||||||
|
callback({ ".", { fsid, component_index() }, 0 });
|
||||||
|
callback({ "..", { fsid, 0 }, 0 });
|
||||||
|
|
||||||
|
for (auto& component : m_components) {
|
||||||
|
InodeIdentifier identifier = { fsid, component.component_index() };
|
||||||
|
callback({ component.name(), identifier, 0 });
|
||||||
|
}
|
||||||
|
return KSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFSRootFolder::SysFSRootFolder()
|
||||||
|
: SystemExposedFolder(".")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<SysFS> SysFS::create()
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) SysFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFS::SysFS()
|
||||||
|
: m_root_inode(SystemRegistrar::the().m_root_folder->to_inode(*this))
|
||||||
|
{
|
||||||
|
Locker locker(m_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFS::~SysFS()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SysFS::initialize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<Inode> SysFS::root_inode() const
|
||||||
|
{
|
||||||
|
return *m_root_inode;
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<SysFSInode> SysFSInode::create(const SysFS& fs, const SystemExposedComponent& component)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) SysFSInode(fs, component));
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFSInode::SysFSInode(const SysFS& fs, const SystemExposedComponent& component)
|
||||||
|
: Inode(const_cast<SysFS&>(fs), component.component_index())
|
||||||
|
, m_associated_component(component)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<size_t> SysFSInode::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* fd) const
|
||||||
|
{
|
||||||
|
return m_associated_component->read_bytes(offset, count, buffer, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SysFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const
|
||||||
|
{
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<Inode> SysFSInode::lookup(StringView)
|
||||||
|
{
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
InodeMetadata SysFSInode::metadata() const
|
||||||
|
{
|
||||||
|
Locker locker(m_lock);
|
||||||
|
InodeMetadata metadata;
|
||||||
|
metadata.inode = { fsid(), m_associated_component->component_index() };
|
||||||
|
metadata.mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
|
||||||
|
metadata.uid = 0;
|
||||||
|
metadata.gid = 0;
|
||||||
|
metadata.size = m_associated_component->size();
|
||||||
|
metadata.mtime = mepoch;
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysFSInode::flush_metadata()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<size_t> SysFSInode::write_bytes(off_t offset, size_t count, const UserOrKernelBuffer& buffer, FileDescription* fd)
|
||||||
|
{
|
||||||
|
return m_associated_component->write_bytes(offset, count, buffer, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<NonnullRefPtr<Inode>> SysFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
|
||||||
|
{
|
||||||
|
return EROFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SysFSInode::add_child(Inode&, const StringView&, mode_t)
|
||||||
|
{
|
||||||
|
return EROFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SysFSInode::remove_child(const StringView&)
|
||||||
|
{
|
||||||
|
return EROFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<size_t> SysFSInode::directory_entry_count() const
|
||||||
|
{
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SysFSInode::chmod(mode_t)
|
||||||
|
{
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SysFSInode::chown(uid_t, gid_t)
|
||||||
|
{
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SysFSInode::truncate(u64)
|
||||||
|
{
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<SysFSDirectoryInode> SysFSDirectoryInode::create(const SysFS& sysfs, const SystemExposedComponent& component)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) SysFSDirectoryInode(sysfs, component));
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFSDirectoryInode::SysFSDirectoryInode(const SysFS& fs, const SystemExposedComponent& component)
|
||||||
|
: SysFSInode(fs, component)
|
||||||
|
, m_parent_fs(const_cast<SysFS&>(fs))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFSDirectoryInode::~SysFSDirectoryInode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
InodeMetadata SysFSDirectoryInode::metadata() const
|
||||||
|
{
|
||||||
|
Locker locker(m_lock);
|
||||||
|
InodeMetadata metadata;
|
||||||
|
metadata.inode = { fsid(), m_associated_component->component_index() };
|
||||||
|
metadata.mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXOTH;
|
||||||
|
metadata.uid = 0;
|
||||||
|
metadata.gid = 0;
|
||||||
|
metadata.size = 0;
|
||||||
|
metadata.mtime = mepoch;
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
KResult SysFSDirectoryInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)> callback) const
|
||||||
|
{
|
||||||
|
Locker locker(m_parent_fs.m_lock);
|
||||||
|
return m_associated_component->traverse_as_directory(m_parent_fs.fsid(), move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<Inode> SysFSDirectoryInode::lookup(StringView name)
|
||||||
|
{
|
||||||
|
Locker locker(m_parent_fs.m_lock);
|
||||||
|
auto component = m_associated_component->lookup(name);
|
||||||
|
if (!component)
|
||||||
|
return {};
|
||||||
|
return component->to_inode(m_parent_fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<size_t> SysFSDirectoryInode::directory_entry_count() const
|
||||||
|
{
|
||||||
|
Locker locker(m_lock);
|
||||||
|
return m_associated_component->entries_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
121
Kernel/FileSystem/SysFS.h
Normal file
121
Kernel/FileSystem/SysFS.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Singleton.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <AK/Types.h>
|
||||||
|
#include <Kernel/FileSystem/FileSystem.h>
|
||||||
|
#include <Kernel/FileSystem/Inode.h>
|
||||||
|
#include <Kernel/FileSystem/InodeMetadata.h>
|
||||||
|
#include <Kernel/SystemExposed.h>
|
||||||
|
#include <Kernel/TTY/SlavePTY.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
class SysFS;
|
||||||
|
class SysFSInode;
|
||||||
|
class SysFSDirectoryInode;
|
||||||
|
|
||||||
|
class SysFSRootFolder final : public SystemExposedFolder {
|
||||||
|
friend class SystemRegistrar;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<SysFSRootFolder> create();
|
||||||
|
virtual KResult traverse_as_directory(unsigned, Function<bool(const FS::DirectoryEntryView&)>) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SysFSRootFolder();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemRegistrar {
|
||||||
|
friend class SysFS;
|
||||||
|
friend class SystemExposedComponent;
|
||||||
|
friend class SystemExposedFolder;
|
||||||
|
friend class SysFSRootFolder;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static SystemRegistrar& the();
|
||||||
|
|
||||||
|
static void initialize();
|
||||||
|
|
||||||
|
SystemRegistrar();
|
||||||
|
void register_new_component(SystemExposedComponent&);
|
||||||
|
|
||||||
|
NonnullRefPtr<SystemExposedFolder> root_folder() { return m_root_folder; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Lock m_lock;
|
||||||
|
NonnullRefPtr<SysFSRootFolder> m_root_folder;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SysFS final : public FS {
|
||||||
|
friend class SysFSInode;
|
||||||
|
friend class SysFSDirectoryInode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~SysFS() override;
|
||||||
|
static NonnullRefPtr<SysFS> create();
|
||||||
|
|
||||||
|
virtual bool initialize() override;
|
||||||
|
virtual const char* class_name() const override { return "SysFS"; }
|
||||||
|
|
||||||
|
virtual NonnullRefPtr<Inode> root_inode() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SysFS();
|
||||||
|
|
||||||
|
NonnullRefPtr<SysFSInode> m_root_inode;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SysFSInode : public Inode {
|
||||||
|
friend class SysFS;
|
||||||
|
friend class SysFSDirectoryInode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<SysFSInode> create(const SysFS&, const SystemExposedComponent&);
|
||||||
|
StringView name() const { return m_associated_component->name(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SysFSInode(const SysFS&, const SystemExposedComponent&);
|
||||||
|
virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
|
||||||
|
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
|
||||||
|
virtual RefPtr<Inode> lookup(StringView name) override;
|
||||||
|
virtual void flush_metadata() override;
|
||||||
|
virtual InodeMetadata metadata() const override;
|
||||||
|
virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
|
||||||
|
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
|
||||||
|
virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
|
||||||
|
virtual KResult remove_child(const StringView& name) override;
|
||||||
|
virtual KResultOr<size_t> directory_entry_count() const override;
|
||||||
|
virtual KResult chmod(mode_t) override;
|
||||||
|
virtual KResult chown(uid_t, gid_t) override;
|
||||||
|
virtual KResult truncate(u64) override;
|
||||||
|
|
||||||
|
NonnullRefPtr<SystemExposedComponent> m_associated_component;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SysFSDirectoryInode : public SysFSInode {
|
||||||
|
friend class SysFS;
|
||||||
|
friend class SysFSRootDirectoryInode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<SysFSDirectoryInode> create(const SysFS&, const SystemExposedComponent&);
|
||||||
|
virtual ~SysFSDirectoryInode() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SysFSDirectoryInode(const SysFS&, const SystemExposedComponent&);
|
||||||
|
// ^Inode
|
||||||
|
virtual InodeMetadata metadata() const override;
|
||||||
|
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
|
||||||
|
virtual RefPtr<Inode> lookup(StringView name) override;
|
||||||
|
virtual KResultOr<size_t> directory_entry_count() const override;
|
||||||
|
|
||||||
|
SysFS& m_parent_fs;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
#include <Kernel/FileSystem/Ext2FileSystem.h>
|
#include <Kernel/FileSystem/Ext2FileSystem.h>
|
||||||
#include <Kernel/FileSystem/Plan9FileSystem.h>
|
#include <Kernel/FileSystem/Plan9FileSystem.h>
|
||||||
#include <Kernel/FileSystem/ProcFS.h>
|
#include <Kernel/FileSystem/ProcFS.h>
|
||||||
|
#include <Kernel/FileSystem/SysFS.h>
|
||||||
#include <Kernel/FileSystem/TmpFS.h>
|
#include <Kernel/FileSystem/TmpFS.h>
|
||||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
|
@ -89,6 +90,8 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*>
|
||||||
fs = DevPtsFS::create();
|
fs = DevPtsFS::create();
|
||||||
} else if (fs_type == "dev" || fs_type == "DevFS") {
|
} else if (fs_type == "dev" || fs_type == "DevFS") {
|
||||||
fs = DevFS::create();
|
fs = DevFS::create();
|
||||||
|
} else if (fs_type == "sys" || fs_type == "SysFS") {
|
||||||
|
fs = SysFS::create();
|
||||||
} else if (fs_type == "tmp" || fs_type == "TmpFS") {
|
} else if (fs_type == "tmp" || fs_type == "TmpFS") {
|
||||||
fs = TmpFS::create();
|
fs = TmpFS::create();
|
||||||
} else {
|
} else {
|
||||||
|
|
74
Kernel/SystemExposed.cpp
Normal file
74
Kernel/SystemExposed.cpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Kernel/FileSystem/SysFS.h>
|
||||||
|
#include <Kernel/SystemExposed.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
static SpinLock<u8> s_index_lock;
|
||||||
|
static InodeIndex s_next_inode_index { 0 };
|
||||||
|
|
||||||
|
static size_t allocate_inode_index()
|
||||||
|
{
|
||||||
|
ScopedSpinLock lock(s_index_lock);
|
||||||
|
s_next_inode_index = s_next_inode_index.value() + 1;
|
||||||
|
VERIFY(s_next_inode_index > 0);
|
||||||
|
return s_next_inode_index.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemExposedComponent::SystemExposedComponent(StringView name)
|
||||||
|
: m_name(KString::try_create(name).release_nonnull())
|
||||||
|
, m_component_index(allocate_inode_index())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KResult SystemExposedFolder::traverse_as_directory(unsigned fsid, Function<bool(const FS::DirectoryEntryView&)> callback) const
|
||||||
|
{
|
||||||
|
Locker locker(SystemRegistrar::the().m_lock);
|
||||||
|
VERIFY(m_parent_folder);
|
||||||
|
callback({ ".", { fsid, component_index() }, 0 });
|
||||||
|
callback({ "..", { fsid, m_parent_folder->component_index() }, 0 });
|
||||||
|
|
||||||
|
for (auto& component : m_components) {
|
||||||
|
InodeIdentifier identifier = { fsid, component.component_index() };
|
||||||
|
callback({ component.name(), identifier, 0 });
|
||||||
|
}
|
||||||
|
return KSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<SystemExposedComponent> SystemExposedFolder::lookup(StringView name)
|
||||||
|
{
|
||||||
|
for (auto& component : m_components) {
|
||||||
|
if (component.name() == name) {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemExposedFolder::SystemExposedFolder(String name)
|
||||||
|
: SystemExposedComponent(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemExposedFolder::SystemExposedFolder(String name, const SystemExposedFolder& parent_folder)
|
||||||
|
: SystemExposedComponent(name)
|
||||||
|
, m_parent_folder(parent_folder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<Inode> SystemExposedFolder::to_inode(const SysFS& sysfs_instance) const
|
||||||
|
{
|
||||||
|
return SysFSDirectoryInode::create(sysfs_instance, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<Inode> SystemExposedComponent::to_inode(const SysFS& sysfs_instance) const
|
||||||
|
{
|
||||||
|
return SysFSInode::create(sysfs_instance, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
62
Kernel/SystemExposed.h
Normal file
62
Kernel/SystemExposed.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Function.h>
|
||||||
|
#include <AK/RefCounted.h>
|
||||||
|
#include <AK/RefPtr.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <AK/Types.h>
|
||||||
|
#include <Kernel/FileSystem/File.h>
|
||||||
|
#include <Kernel/FileSystem/FileSystem.h>
|
||||||
|
#include <Kernel/KResult.h>
|
||||||
|
#include <Kernel/UserOrKernelBuffer.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
class SysFS;
|
||||||
|
class SystemExposedComponent : public RefCounted<SystemExposedComponent> {
|
||||||
|
public:
|
||||||
|
virtual KResultOr<size_t> entries_count() const { VERIFY_NOT_REACHED(); };
|
||||||
|
virtual StringView name() const { return m_name->view(); }
|
||||||
|
virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const { VERIFY_NOT_REACHED(); }
|
||||||
|
virtual KResult traverse_as_directory(unsigned, Function<bool(const FS::DirectoryEntryView&)>) const { VERIFY_NOT_REACHED(); }
|
||||||
|
virtual RefPtr<SystemExposedComponent> lookup(StringView) { VERIFY_NOT_REACHED(); };
|
||||||
|
virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, FileDescription*) { return -EROFS; }
|
||||||
|
virtual size_t size() const { return 0; }
|
||||||
|
|
||||||
|
virtual NonnullRefPtr<Inode> to_inode(const SysFS& sysfs_instance) const;
|
||||||
|
|
||||||
|
size_t component_index() const { return m_component_index; };
|
||||||
|
|
||||||
|
virtual ~SystemExposedComponent() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit SystemExposedComponent(StringView name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NonnullOwnPtr<KString> m_name;
|
||||||
|
size_t m_component_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SystemExposedFolder : public SystemExposedComponent {
|
||||||
|
public:
|
||||||
|
virtual KResultOr<size_t> entries_count() const override { return m_components.size(); };
|
||||||
|
virtual KResult traverse_as_directory(unsigned, Function<bool(const FS::DirectoryEntryView&)>) const override;
|
||||||
|
virtual RefPtr<SystemExposedComponent> lookup(StringView name) override;
|
||||||
|
void add_component(const SystemExposedComponent&);
|
||||||
|
|
||||||
|
virtual NonnullRefPtr<Inode> to_inode(const SysFS& sysfs_instance) const override final;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit SystemExposedFolder(String name);
|
||||||
|
SystemExposedFolder(String name, const SystemExposedFolder& parent_folder);
|
||||||
|
NonnullRefPtrVector<SystemExposedComponent> m_components;
|
||||||
|
RefPtr<SystemExposedFolder> m_parent_folder;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -9,9 +9,9 @@
|
||||||
#include <Kernel/ACPI/Initialize.h>
|
#include <Kernel/ACPI/Initialize.h>
|
||||||
#include <Kernel/ACPI/MultiProcessorParser.h>
|
#include <Kernel/ACPI/MultiProcessorParser.h>
|
||||||
#include <Kernel/Arch/x86/Processor.h>
|
#include <Kernel/Arch/x86/Processor.h>
|
||||||
|
#include <Kernel/Arch/PC/BIOS.h>
|
||||||
#include <Kernel/CMOS.h>
|
#include <Kernel/CMOS.h>
|
||||||
#include <Kernel/CommandLine.h>
|
#include <Kernel/CommandLine.h>
|
||||||
#include <Kernel/DMI.h>
|
|
||||||
#include <Kernel/Devices/FullDevice.h>
|
#include <Kernel/Devices/FullDevice.h>
|
||||||
#include <Kernel/Devices/HID/HIDManagement.h>
|
#include <Kernel/Devices/HID/HIDManagement.h>
|
||||||
#include <Kernel/Devices/MemoryDevice.h>
|
#include <Kernel/Devices/MemoryDevice.h>
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
#include <Kernel/Devices/VMWareBackdoor.h>
|
#include <Kernel/Devices/VMWareBackdoor.h>
|
||||||
#include <Kernel/Devices/ZeroDevice.h>
|
#include <Kernel/Devices/ZeroDevice.h>
|
||||||
#include <Kernel/FileSystem/Ext2FileSystem.h>
|
#include <Kernel/FileSystem/Ext2FileSystem.h>
|
||||||
|
#include <Kernel/FileSystem/SysFS.h>
|
||||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||||
#include <Kernel/Graphics/GraphicsManagement.h>
|
#include <Kernel/Graphics/GraphicsManagement.h>
|
||||||
#include <Kernel/Heap/SlabAllocator.h>
|
#include <Kernel/Heap/SlabAllocator.h>
|
||||||
|
@ -146,6 +147,7 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init()
|
||||||
ACPI::initialize();
|
ACPI::initialize();
|
||||||
|
|
||||||
// Initialize the PCI Bus as early as possible, for early boot (PCI based) serial logging
|
// Initialize the PCI Bus as early as possible, for early boot (PCI based) serial logging
|
||||||
|
SystemRegistrar::initialize();
|
||||||
PCI::initialize();
|
PCI::initialize();
|
||||||
PCISerialDevice::detect();
|
PCISerialDevice::detect();
|
||||||
|
|
||||||
|
@ -237,7 +239,8 @@ void init_stage2(void*)
|
||||||
|
|
||||||
USB::UHCIController::detect();
|
USB::UHCIController::detect();
|
||||||
|
|
||||||
DMIExpose::initialize();
|
BIOSExposedFolder::initialize();
|
||||||
|
ACPI::ExposedFolder::initialize();
|
||||||
|
|
||||||
VirtIO::detect();
|
VirtIO::detect();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue