summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/ACPI/Parser.cpp73
-rw-r--r--Kernel/ACPI/Parser.h24
-rw-r--r--Kernel/Arch/PC/BIOS.cpp149
-rw-r--r--Kernel/Arch/PC/BIOS.h107
-rw-r--r--Kernel/CMakeLists.txt3
-rw-r--r--Kernel/DMI.cpp111
-rw-r--r--Kernel/DMI.h87
-rw-r--r--Kernel/FileSystem/SysFS.cpp220
-rw-r--r--Kernel/FileSystem/SysFS.h121
-rw-r--r--Kernel/Syscalls/mount.cpp3
-rw-r--r--Kernel/SystemExposed.cpp74
-rw-r--r--Kernel/SystemExposed.h62
-rw-r--r--Kernel/init.cpp7
13 files changed, 839 insertions, 202 deletions
diff --git a/Kernel/ACPI/Parser.cpp b/Kernel/ACPI/Parser.cpp
index 1706445c7e..e86f27f33a 100644
--- a/Kernel/ACPI/Parser.cpp
+++ b/Kernel/ACPI/Parser.cpp
@@ -27,6 +27,79 @@ Parser* Parser::the()
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)
{
VERIFY(!s_acpi_parser);
diff --git a/Kernel/ACPI/Parser.h b/Kernel/ACPI/Parser.h
index e31e355396..c9fbd5dd2e 100644
--- a/Kernel/ACPI/Parser.h
+++ b/Kernel/ACPI/Parser.h
@@ -9,14 +9,36 @@
#include <AK/Types.h>
#include <Kernel/ACPI/Definitions.h>
#include <Kernel/ACPI/Initialize.h>
-#include <Kernel/FileSystem/File.h>
#include <Kernel/PhysicalAddress.h>
+#include <Kernel/SystemExposed.h>
#include <Kernel/VM/Region.h>
#include <Kernel/VirtualAddress.h>
namespace Kernel {
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 {
public:
static Parser* the();
diff --git a/Kernel/Arch/PC/BIOS.cpp b/Kernel/Arch/PC/BIOS.cpp
index 8dd0b58dad..fc86d756d7 100644
--- a/Kernel/Arch/PC/BIOS.cpp
+++ b/Kernel/Arch/PC/BIOS.cpp
@@ -1,16 +1,165 @@
/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/StringView.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/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)
+
+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 mapping;
diff --git a/Kernel/Arch/PC/BIOS.h b/Kernel/Arch/PC/BIOS.h
index a3289d47b0..39bc11c73d 100644
--- a/Kernel/Arch/PC/BIOS.h
+++ b/Kernel/Arch/PC/BIOS.h
@@ -1,16 +1,123 @@
/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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/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 {
MappedROM map_bios();
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 };
+};
+
}
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt
index d991bac2e9..9652fbace8 100644
--- a/Kernel/CMakeLists.txt
+++ b/Kernel/CMakeLists.txt
@@ -30,7 +30,6 @@ set(KERNEL_SOURCES
CommandLine.cpp
ConsoleDevice.cpp
CoreDump.cpp
- DMI.cpp
Devices/AsyncDeviceRequest.cpp
Devices/BlockDevice.cpp
Devices/CharacterDevice.cpp
@@ -107,6 +106,7 @@ set(KERNEL_SOURCES
FileSystem/InodeWatcher.cpp
FileSystem/Plan9FileSystem.cpp
FileSystem/ProcFS.cpp
+ FileSystem/SysFS.cpp
FileSystem/TmpFS.cpp
FileSystem/VirtualFileSystem.cpp
FutexQueue.cpp
@@ -225,6 +225,7 @@ set(KERNEL_SOURCES
Syscalls/waitid.cpp
Syscalls/inode_watcher.cpp
Syscalls/write.cpp
+ SystemExposed.cpp
TTY/ConsoleManagement.cpp
TTY/MasterPTY.cpp
TTY/PTYMultiplexer.cpp
diff --git a/Kernel/DMI.cpp b/Kernel/DMI.cpp
deleted file mode 100644
index 8d821c3287..0000000000
--- a/Kernel/DMI.cpp
+++ /dev/null
@@ -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);
-}
-
-}
diff --git a/Kernel/DMI.h b/Kernel/DMI.h
deleted file mode 100644
index 90c0cee305..0000000000
--- a/Kernel/DMI.h
+++ /dev/null
@@ -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 };
-};
-
-}
diff --git a/Kernel/FileSystem/SysFS.cpp b/Kernel/FileSystem/SysFS.cpp
new file mode 100644
index 0000000000..09cb9ec78d
--- /dev/null
+++ b/Kernel/FileSystem/SysFS.cpp
@@ -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();
+}
+
+}
diff --git a/Kernel/FileSystem/SysFS.h b/Kernel/FileSystem/SysFS.h
new file mode 100644
index 0000000000..97269d624a
--- /dev/null
+++ b/Kernel/FileSystem/SysFS.h
@@ -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;
+};
+
+}
diff --git a/Kernel/Syscalls/mount.cpp b/Kernel/Syscalls/mount.cpp
index c6b9f7c5b8..f42c1bb213 100644
--- a/Kernel/Syscalls/mount.cpp
+++ b/Kernel/Syscalls/mount.cpp
@@ -10,6 +10,7 @@
#include <Kernel/FileSystem/Ext2FileSystem.h>
#include <Kernel/FileSystem/Plan9FileSystem.h>
#include <Kernel/FileSystem/ProcFS.h>
+#include <Kernel/FileSystem/SysFS.h>
#include <Kernel/FileSystem/TmpFS.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/Process.h>
@@ -89,6 +90,8 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*>
fs = DevPtsFS::create();
} else if (fs_type == "dev" || fs_type == "DevFS") {
fs = DevFS::create();
+ } else if (fs_type == "sys" || fs_type == "SysFS") {
+ fs = SysFS::create();
} else if (fs_type == "tmp" || fs_type == "TmpFS") {
fs = TmpFS::create();
} else {
diff --git a/Kernel/SystemExposed.cpp b/Kernel/SystemExposed.cpp
new file mode 100644
index 0000000000..12598dad7d
--- /dev/null
+++ b/Kernel/SystemExposed.cpp
@@ -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);
+}
+
+}
diff --git a/Kernel/SystemExposed.h b/Kernel/SystemExposed.h
new file mode 100644
index 0000000000..6ef0f29305
--- /dev/null
+++ b/Kernel/SystemExposed.h
@@ -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;
+};
+
+}
diff --git a/Kernel/init.cpp b/Kernel/init.cpp
index f67bb8bd86..10e4e8b1eb 100644
--- a/Kernel/init.cpp
+++ b/Kernel/init.cpp
@@ -9,9 +9,9 @@
#include <Kernel/ACPI/Initialize.h>
#include <Kernel/ACPI/MultiProcessorParser.h>
#include <Kernel/Arch/x86/Processor.h>
+#include <Kernel/Arch/PC/BIOS.h>
#include <Kernel/CMOS.h>
#include <Kernel/CommandLine.h>
-#include <Kernel/DMI.h>
#include <Kernel/Devices/FullDevice.h>
#include <Kernel/Devices/HID/HIDManagement.h>
#include <Kernel/Devices/MemoryDevice.h>
@@ -24,6 +24,7 @@
#include <Kernel/Devices/VMWareBackdoor.h>
#include <Kernel/Devices/ZeroDevice.h>
#include <Kernel/FileSystem/Ext2FileSystem.h>
+#include <Kernel/FileSystem/SysFS.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/Graphics/GraphicsManagement.h>
#include <Kernel/Heap/SlabAllocator.h>
@@ -146,6 +147,7 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init()
ACPI::initialize();
// Initialize the PCI Bus as early as possible, for early boot (PCI based) serial logging
+ SystemRegistrar::initialize();
PCI::initialize();
PCISerialDevice::detect();
@@ -237,7 +239,8 @@ void init_stage2(void*)
USB::UHCIController::detect();
- DMIExpose::initialize();
+ BIOSExposedFolder::initialize();
+ ACPI::ExposedFolder::initialize();
VirtIO::detect();