From 51024f879d5051c2fcb1b578f52d779df4774f8e Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 3 Feb 2023 22:19:26 +0100 Subject: [PATCH 01/44] SharedPtr: Delete ptr on failure in all adopt_shared* functions --- luna/include/luna/SharedPtr.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/luna/include/luna/SharedPtr.h b/luna/include/luna/SharedPtr.h index cdf02fb5..5eb9f918 100644 --- a/luna/include/luna/SharedPtr.h +++ b/luna/include/luna/SharedPtr.h @@ -117,12 +117,17 @@ template Result> make_shared(Args... ar return SharedPtr { ptr, ref_count }; } +// NOTE: ptr is deleted if any of the adopt_shared* functions fail to construct a SharedPtr. template Result> adopt_shared(T* ptr) { using RefCount = __detail::RefCount; + auto guard = make_scope_guard([ptr] { delete ptr; }); + RefCount* const ref_count = TRY(make()); + guard.deactivate(); + return SharedPtr { ptr, ref_count }; } @@ -138,13 +143,7 @@ template Result> adopt_shared_from_owned(OwnedPtr&& T* ptr = other.m_ptr; other.m_ptr = nullptr; - // FIXME: Should the pointee magically vanish on failure? Or go back into the OwnedPtr, even though it's been - // moved... - auto guard = make_scope_guard([&] { delete ptr; }); - const SharedPtr shared_ptr = TRY(adopt_shared(ptr)); - guard.deactivate(); - return shared_ptr; } -- 2.34.1 From cb4246b98df40e0ce729dda42d726c436bcb7902 Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 3 Feb 2023 22:18:52 +0100 Subject: [PATCH 02/44] kernel: Start working on a VFS implementation using OOP and SharedPtr --- kernel/CMakeLists.txt | 2 ++ kernel/src/fs/VFS.cpp | 6 ++++ kernel/src/fs/VFS.h | 37 ++++++++++++++++++++++ kernel/src/fs/tmpfs/FileSystem.cpp | 33 +++++++++++++++++++ kernel/src/fs/tmpfs/FileSystem.h | 51 ++++++++++++++++++++++++++++++ kernel/src/main.cpp | 3 ++ 6 files changed, 132 insertions(+) create mode 100644 kernel/src/fs/VFS.cpp create mode 100644 kernel/src/fs/VFS.h create mode 100644 kernel/src/fs/tmpfs/FileSystem.cpp create mode 100644 kernel/src/fs/tmpfs/FileSystem.h diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 6a341657..f71b3d48 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -27,6 +27,8 @@ set(SOURCES src/sys/clock_gettime.cpp src/sys/allocate_memory.cpp src/sys/usleep.cpp + src/fs/VFS.cpp + src/fs/tmpfs/FileSystem.cpp src/InitRD.cpp src/ELF.cpp ) diff --git a/kernel/src/fs/VFS.cpp b/kernel/src/fs/VFS.cpp new file mode 100644 index 00000000..dfa9b609 --- /dev/null +++ b/kernel/src/fs/VFS.cpp @@ -0,0 +1,6 @@ +#include "fs/VFS.h" + +namespace VFS +{ + SharedPtr root_fs; +} diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h new file mode 100644 index 00000000..ea9a8084 --- /dev/null +++ b/kernel/src/fs/VFS.h @@ -0,0 +1,37 @@ +#pragma once +#include + +namespace VFS +{ + enum class InodeType + { + RegularFile, + Directory + }; + + class FileSystem; + + class Inode + { + public: + virtual Result find(const char* name) const = 0; + + virtual FileSystem& fs() const = 0; + + virtual ~Inode() = default; + + InodeType type; + }; + + class FileSystem + { + public: + virtual Inode& root() const = 0; + + virtual ~FileSystem() = default; + }; + + extern SharedPtr root_fs; + + Result resolve_path(const char* path); +} diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp new file mode 100644 index 00000000..45631fc4 --- /dev/null +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -0,0 +1,33 @@ +#include "fs/tmpfs/FileSystem.h" +#include + +namespace TmpFS +{ + Result> FileSystem::create() + { + SharedPtr root = TRY(make_shared()); + SharedPtr fs = TRY(adopt_shared(new (std::nothrow) FileSystem())); + root->set_fs(*fs, {}); + TRY(fs->set_root(root)); + return (SharedPtr)fs; + } + + FileSystem::FileSystem() + { + } + + Result FileSystem::set_root(SharedPtr root) + { + m_root_inode = root; + return m_inodes.try_append(root); + } + + Inode::Inode() + { + } + + void Inode::set_fs(FileSystem& fs, Badge) + { + m_fs = &fs; + } +} diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h new file mode 100644 index 00000000..81a4b996 --- /dev/null +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -0,0 +1,51 @@ +#pragma once +#include "fs/VFS.h" +#include +#include + +namespace TmpFS +{ + class FileSystem : public VFS::FileSystem + { + public: + VFS::Inode& root() const override + { + return *m_root_inode; + } + + static Result> create(); + + virtual ~FileSystem() = default; + + private: + FileSystem(); + + Result set_root(SharedPtr root); + + SharedPtr m_root_inode; + Vector> m_inodes; + }; + + class Inode : public VFS::Inode + { + public: + Inode(); + + void set_fs(FileSystem& fs, Badge); + + Result find(const char*) const override + { + return err(ENOTSUP); + } + + VFS::FileSystem& fs() const override + { + return *m_fs; + } + + virtual ~Inode() = default; + + private: + VFS::FileSystem* m_fs; + }; +} diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 4a8d08c1..aad0a78d 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -7,6 +7,7 @@ #include "arch/Timer.h" #include "boot/Init.h" #include "config.h" +#include "fs/tmpfs/FileSystem.h" #include "memory/Heap.h" #include "memory/KernelVM.h" #include "memory/MemoryManager.h" @@ -55,6 +56,8 @@ Result init() Thread::init(); Scheduler::init(); + VFS::root_fs = TRY(TmpFS::FileSystem::create()); + TarStream::Entry entry; while (TRY(g_initrd.read_next_entry(entry))) { -- 2.34.1 From 79078ff21e80c389dc239d964af601a58bd146ea Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 14 Feb 2023 19:59:44 +0100 Subject: [PATCH 03/44] SharedPtr: Implement make_shared using adopt_shared --- luna/include/luna/SharedPtr.h | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/luna/include/luna/SharedPtr.h b/luna/include/luna/SharedPtr.h index 5eb9f918..728cc229 100644 --- a/luna/include/luna/SharedPtr.h +++ b/luna/include/luna/SharedPtr.h @@ -104,19 +104,6 @@ template class SharedPtr RefCount* m_ref_count; }; -template Result> make_shared(Args... args) -{ - using RefCount = __detail::RefCount; - - RefCount* const ref_count = TRY(make()); - auto guard = make_scope_guard([&] { delete ref_count; }); - - T* const ptr = TRY(make(args...)); - guard.deactivate(); - - return SharedPtr { ptr, ref_count }; -} - // NOTE: ptr is deleted if any of the adopt_shared* functions fail to construct a SharedPtr. template Result> adopt_shared(T* ptr) { @@ -131,6 +118,12 @@ template Result> adopt_shared(T* ptr) return SharedPtr { ptr, ref_count }; } +template Result> make_shared(Args... args) +{ + T* raw_ptr = TRY(make(args...)); + return adopt_shared(raw_ptr); +} + template Result> adopt_shared_if_nonnull(T* ptr) { if (ptr) return adopt_shared(ptr); -- 2.34.1 From 6eff41e7af9a10bdfda539097c0f411122ee81bb Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 14 Feb 2023 20:03:29 +0100 Subject: [PATCH 04/44] Option: Use __builtin_launder to ensure that the compiler doesn't label this as UB --- luna/include/luna/Option.h | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/luna/include/luna/Option.h b/luna/include/luna/Option.h index bbe09698..ce5a57dd 100644 --- a/luna/include/luna/Option.h +++ b/luna/include/luna/Option.h @@ -138,26 +138,16 @@ template class Option private: struct Storage { - u8 buffer[sizeof(T)]; - - T* fetch_ptr() - { - return (T*)buffer; - } + alignas(T) u8 buffer[sizeof(T)]; T& fetch_reference() { - return *fetch_ptr(); - } - - const T* fetch_ptr() const - { - return (const T*)buffer; + return *__builtin_launder(reinterpret_cast(&buffer)); } const T& fetch_reference() const { - return *fetch_ptr(); + return *__builtin_launder(reinterpret_cast(&buffer)); } void store_reference(const T& ref) -- 2.34.1 From 4e88a7482ce73b9bca242362698a88a6e485b370 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 14 Feb 2023 20:05:00 +0100 Subject: [PATCH 05/44] kernel, luna: Move Spinlock.h to luna --- kernel/CMakeLists.txt | 1 - kernel/src/Log.cpp | 2 +- kernel/src/memory/KernelVM.cpp | 2 +- kernel/src/memory/MemoryManager.cpp | 2 +- luna/CMakeLists.txt | 2 ++ .../thread => luna/include/luna}/Spinlock.h | 23 ++++++------------- {kernel/src/thread => luna/src}/Spinlock.cpp | 19 +++++++++------ 7 files changed, 24 insertions(+), 27 deletions(-) rename {kernel/src/thread => luna/include/luna}/Spinlock.h (86%) rename {kernel/src/thread => luna/src}/Spinlock.cpp (66%) diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index f71b3d48..7cc661f6 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -18,7 +18,6 @@ set(SOURCES src/arch/Serial.cpp src/arch/Timer.cpp src/arch/PCI.cpp - src/thread/Spinlock.cpp src/thread/Thread.cpp src/thread/Scheduler.cpp src/sys/Syscall.cpp diff --git a/kernel/src/Log.cpp b/kernel/src/Log.cpp index d28a5e2d..20ecc26a 100644 --- a/kernel/src/Log.cpp +++ b/kernel/src/Log.cpp @@ -2,10 +2,10 @@ #include "arch/CPU.h" #include "arch/Serial.h" #include "arch/Timer.h" -#include "thread/Spinlock.h" #include "video/TextConsole.h" #include #include +#include static bool g_debug_enabled = true; static bool g_serial_enabled = true; diff --git a/kernel/src/memory/KernelVM.cpp b/kernel/src/memory/KernelVM.cpp index 48c4b80a..1773ba14 100644 --- a/kernel/src/memory/KernelVM.cpp +++ b/kernel/src/memory/KernelVM.cpp @@ -1,7 +1,7 @@ #include "memory/KernelVM.h" #include "arch/MMU.h" -#include "thread/Spinlock.h" #include +#include static const u64 KERNEL_VM_RANGE_START = 0xffffffffc0000000; diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 3c010cda..96818eb7 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -2,10 +2,10 @@ #include "arch/MMU.h" #include "memory/KernelVM.h" #include "memory/MemoryMap.h" -#include "thread/Spinlock.h" #include #include #include +#include #include #include diff --git a/luna/CMakeLists.txt b/luna/CMakeLists.txt index 1b01daf5..b3eba9a3 100644 --- a/luna/CMakeLists.txt +++ b/luna/CMakeLists.txt @@ -16,6 +16,8 @@ set(FREESTANDING_SOURCES src/TarStream.cpp src/DebugLog.cpp src/Heap.cpp + src/Spinlock.cpp + src/UBSAN.cpp ) set(SOURCES diff --git a/kernel/src/thread/Spinlock.h b/luna/include/luna/Spinlock.h similarity index 86% rename from kernel/src/thread/Spinlock.h rename to luna/include/luna/Spinlock.h index 2b8f2e5a..0b284c17 100644 --- a/kernel/src/thread/Spinlock.h +++ b/luna/include/luna/Spinlock.h @@ -1,6 +1,4 @@ #pragma once -#include "Log.h" -#include "arch/CPU.h" #include #include @@ -30,8 +28,15 @@ class ScopeLock ScopeLock(const ScopeLock&) = delete; ScopeLock(ScopeLock&&) = delete; + Spinlock& take_over() + { + m_taken_over = true; + return m_lock; + } + private: Spinlock& m_lock; + bool m_taken_over { false }; }; class SafeScopeLock @@ -107,25 +112,11 @@ template class LockedValue { } -#ifndef LOCKED_VALUE_DEBUG LockedValueGuard lock() { m_lock.lock(); return { *this }; } -#else - LockedValueGuard lock() - { - if (m_lock.try_lock()) { return { *this }; } - - kwarnln("Spinning on a locked LockedValue. This might lead to a deadlock..."); - - CPU::print_stack_trace(); - - m_lock.lock(); - return { *this }; - } -#endif Option try_lock() { diff --git a/kernel/src/thread/Spinlock.cpp b/luna/src/Spinlock.cpp similarity index 66% rename from kernel/src/thread/Spinlock.cpp rename to luna/src/Spinlock.cpp index b1744f09..2896aebe 100644 --- a/kernel/src/thread/Spinlock.cpp +++ b/luna/src/Spinlock.cpp @@ -1,6 +1,11 @@ -#include "thread/Spinlock.h" -#include "Log.h" -#include "arch/CPU.h" +#include +#include + +#ifdef ARCH_X86_64 +#define pause() asm volatile("pause") +#else +#error "Unsupported architecture" +#endif void Spinlock::lock() { @@ -8,7 +13,7 @@ void Spinlock::lock() while (!m_lock.compare_exchange_strong(expected, 1)) { expected = 0; - CPU::pause(); + pause(); } } @@ -23,7 +28,7 @@ void Spinlock::unlock() int expected = 1; if (!m_lock.compare_exchange_strong(expected, 0)) { - kwarnln("Spinlock::unlock() called on an unlocked lock with value %d", expected); + dbgln("Spinlock::unlock() called on an unlocked lock with value %d", expected); } } @@ -34,7 +39,7 @@ ScopeLock::ScopeLock(Spinlock& lock) : m_lock(lock) ScopeLock::~ScopeLock() { - m_lock.unlock(); + if (!m_taken_over) m_lock.unlock(); } const u32 RETRIES = 5000000; @@ -42,7 +47,7 @@ const u32 RETRIES = 5000000; SafeScopeLock::SafeScopeLock(Spinlock& lock) : m_lock(lock) { u32 tries_left = RETRIES; - while (!lock.try_lock() && --tries_left) { CPU::pause(); } + while (!lock.try_lock() && --tries_left) { pause(); } if (tries_left) m_success = true; } -- 2.34.1 From 38bd3d3eef10cb28db2088a25240bfd179228304 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 14 Feb 2023 20:07:30 +0100 Subject: [PATCH 06/44] luna: Use spinlocks in the heap implementation --- luna/src/Heap.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/luna/src/Heap.cpp b/luna/src/Heap.cpp index 2e9b686f..25623a71 100644 --- a/luna/src/Heap.cpp +++ b/luna/src/Heap.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #ifdef USE_FREESTANDING @@ -45,9 +46,10 @@ static_assert(sizeof(HeapBlock) == 48UL); static const isize HEAP_BLOCK_SIZE = 48; static LinkedList heap; +static Spinlock g_heap_lock; -// If we're allocating a large amount of memory, map enough pages for it, but otherwise just use the default amount of -// pages. +// If we're allocating a large amount of memory, map enough pages for it, but otherwise just use the default amount +// of pages. static usize get_pages_for_allocation(usize bytes) { usize pages = get_blocks_from_size(bytes, PAGE_SIZE); @@ -178,6 +180,8 @@ Result malloc_impl(usize size, bool should_scrub) { if (!size) return (void*)BLOCK_MAGIC; + ScopeLock lock(g_heap_lock); + size = align_up<16>(size); Option block = heap.first(); @@ -231,6 +235,8 @@ Result free_impl(void* ptr) if (ptr == (void*)BLOCK_MAGIC) return {}; // This pointer was returned from a call to malloc(0) if (!ptr) return {}; + ScopeLock lock(g_heap_lock); + HeapBlock* block = get_heap_block_for_pointer(ptr); if (block->magic != BLOCK_MAGIC) @@ -286,6 +292,8 @@ Result realloc_impl(void* ptr, usize size) return (void*)BLOCK_MAGIC; } + ScopeLock lock(g_heap_lock); + HeapBlock* const block = get_heap_block_for_pointer(ptr); if (block->magic != BLOCK_MAGIC) @@ -327,6 +335,8 @@ Result realloc_impl(void* ptr, usize size) usize old_size = block->req_size; + lock.take_over().unlock(); + void* const new_ptr = TRY(malloc_impl(size, false)); memcpy(new_ptr, ptr, old_size > size ? size : old_size); TRY(free_impl(ptr)); -- 2.34.1 From 08d5d727ee7b938f93d58f3bafa68c5ddb109eda Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 14 Feb 2023 20:10:02 +0100 Subject: [PATCH 07/44] luna: Skip UBSAN.cpp in CMakeLists as that's not implemented yet --- luna/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/luna/CMakeLists.txt b/luna/CMakeLists.txt index b3eba9a3..652c341c 100644 --- a/luna/CMakeLists.txt +++ b/luna/CMakeLists.txt @@ -17,7 +17,6 @@ set(FREESTANDING_SOURCES src/DebugLog.cpp src/Heap.cpp src/Spinlock.cpp - src/UBSAN.cpp ) set(SOURCES -- 2.34.1 From 4697a16206583dd29377c6590c86b869316d22ff Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 14 Feb 2023 20:17:31 +0100 Subject: [PATCH 08/44] Heap: Avoid accessing a block after it's potentially deleted --- luna/src/Heap.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/luna/src/Heap.cpp b/luna/src/Heap.cpp index 25623a71..12507913 100644 --- a/luna/src/Heap.cpp +++ b/luna/src/Heap.cpp @@ -130,6 +130,8 @@ static Result combine_forward(HeapBlock* block) heap.remove(next); next->magic = BLOCK_DEAD; + block->full_size += next->full_size + sizeof(HeapBlock); + if (next->status & BLOCK_END_MEM) { if (next->status & BLOCK_START_MEM) @@ -142,8 +144,6 @@ static Result combine_forward(HeapBlock* block) block->status |= BLOCK_END_MEM; } - block->full_size += next->full_size + sizeof(HeapBlock); - return {}; } @@ -159,6 +159,8 @@ static Result combine_backward(HeapBlock* block) heap.remove(block); block->magic = BLOCK_DEAD; + last->full_size += block->full_size + sizeof(HeapBlock); + if (block->status & BLOCK_END_MEM) { if (block->status & BLOCK_START_MEM) @@ -171,8 +173,6 @@ static Result combine_backward(HeapBlock* block) last->status |= BLOCK_END_MEM; } - last->full_size += block->full_size + sizeof(HeapBlock); - return last; } -- 2.34.1 From 37bbc04719442a18562aeffacc03a31f57466788 Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 17 Feb 2023 22:47:15 +0100 Subject: [PATCH 09/44] Heap: Fix GPF caused when making many small allocations Apparently space was too tight to split(), but we did it anyways, corrupting the next block. This patch fixes this behavior. --- luna/src/Heap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/luna/src/Heap.cpp b/luna/src/Heap.cpp index 12507913..81c6c45f 100644 --- a/luna/src/Heap.cpp +++ b/luna/src/Heap.cpp @@ -99,7 +99,7 @@ static Option split(HeapBlock* block, usize size) const usize old_size = block->full_size; // Save the old value of this variable since we are going to use it after modifying it - if (available < (size + sizeof(HeapBlock))) + if (available <= (size + sizeof(HeapBlock))) return {}; // This block hasn't got enough free space to hold the requested size. const usize offset = get_fair_offset_to_split_at(block, size + sizeof(HeapBlock)); -- 2.34.1 From d842443869f01de7e0b61b4ca5ad49bcaef4517a Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 18 Feb 2023 00:18:42 +0100 Subject: [PATCH 10/44] kernel: Switch to a stack we control for the main task as soon as we leave early boot This is probably pointless as the main task only exists up until the point where the Scheduler starts running, but some init code was running into a stack overflow due to the fact that we only had one bootloader-provided page of stack. This should probably be changed afterwards. --- kernel/src/arch/CPU.h | 2 ++ kernel/src/arch/x86_64/CPU.cpp | 9 +++++++++ kernel/src/main.cpp | 14 +++++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/kernel/src/arch/CPU.h b/kernel/src/arch/CPU.h index 54422463..3e56d105 100644 --- a/kernel/src/arch/CPU.h +++ b/kernel/src/arch/CPU.h @@ -26,5 +26,7 @@ namespace CPU void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg); void print_stack_trace_at(Registers* regs); + [[noreturn]] void bootstrap_switch_stack(u64 stack, void* function); + void pause(); } diff --git a/kernel/src/arch/x86_64/CPU.cpp b/kernel/src/arch/x86_64/CPU.cpp index 5a56a7c8..b703071c 100644 --- a/kernel/src/arch/x86_64/CPU.cpp +++ b/kernel/src/arch/x86_64/CPU.cpp @@ -295,6 +295,15 @@ namespace CPU &frame_index); } + [[noreturn]] void bootstrap_switch_stack(u64 stack, void* function) + { + asm volatile("mov %0, %%rsp\n" + "jmp *%1" + : + : "r"(stack), "r"(function)); + __builtin_unreachable(); + } + void pause() { asm volatile("pause"); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index aad0a78d..2b3e3ffc 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -90,11 +90,19 @@ Result init() return {}; } -extern "C" [[noreturn]] void _start() +[[noreturn]] void init_wrapper() { - Init::check_magic(); - Init::early_init(); auto rc = init(); if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string()); CPU::idle_loop(); } + +// FIXME: Add a guard page to make sure the stack doesn't end up in random kernel memory. Also reclaim this memory after +// leaving the init task. +extern "C" [[noreturn]] void _start() +{ + Init::check_magic(); + Init::early_init(); + Stack stack { MemoryManager::alloc_for_kernel(8, MMU::ReadWrite | MMU::NoExecute).value(), 8 * ARCH_PAGE_SIZE }; + CPU::bootstrap_switch_stack(stack.top(), (void*)init_wrapper); +} -- 2.34.1 From ae22321648f7b05f998ab905e0e892d5bb57f34c Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 16:22:11 +0100 Subject: [PATCH 11/44] Option, Result: Make try_move_value() non-const since it modifies the Option --- luna/include/luna/Option.h | 2 +- luna/include/luna/Result.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/luna/include/luna/Option.h b/luna/include/luna/Option.h index ce5a57dd..70266c0f 100644 --- a/luna/include/luna/Option.h +++ b/luna/include/luna/Option.h @@ -101,7 +101,7 @@ template class Option return true; } - bool try_move_value(T& ref) const + bool try_move_value(T& ref) { if (!has_value()) return false; m_has_value = false; diff --git a/luna/include/luna/Result.h b/luna/include/luna/Result.h index 8fd56785..9f833b8e 100644 --- a/luna/include/luna/Result.h +++ b/luna/include/luna/Result.h @@ -110,7 +110,7 @@ template class Result return m_value.try_set_value(ref); } - bool try_move_value(T& ref) const + bool try_move_value(T& ref) { return m_value.try_move_value(ref); } -- 2.34.1 From e9e1bef89c7930a1ccfd78c7166ae8b4af19eb27 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 16:27:36 +0100 Subject: [PATCH 12/44] OwnedPtr, SharedPtr: Add operator bool --- luna/include/luna/OwnedPtr.h | 5 +++++ luna/include/luna/SharedPtr.h | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/luna/include/luna/OwnedPtr.h b/luna/include/luna/OwnedPtr.h index 319b8160..b831f65f 100644 --- a/luna/include/luna/OwnedPtr.h +++ b/luna/include/luna/OwnedPtr.h @@ -59,6 +59,11 @@ template class OwnedPtr return *m_ptr; } + operator bool() const + { + return m_ptr != nullptr; + } + template friend Result> adopt_shared_from_owned(OwnedPtr&&); private: diff --git a/luna/include/luna/SharedPtr.h b/luna/include/luna/SharedPtr.h index 728cc229..020c37a5 100644 --- a/luna/include/luna/SharedPtr.h +++ b/luna/include/luna/SharedPtr.h @@ -99,6 +99,11 @@ template class SharedPtr return *m_ptr; } + operator bool() const + { + return m_ptr != nullptr; + } + private: T* m_ptr; RefCount* m_ref_count; -- 2.34.1 From 96a213ec5c04e31d5e4a27b84858c14e3a3f7c21 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 17:36:03 +0100 Subject: [PATCH 13/44] libc: Make dbgln() also print a newline in userspace Previously, dbgln() only printed a newline in kernel-space. --- libc/src/stdio.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libc/src/stdio.cpp b/libc/src/stdio.cpp index 276518a8..96f9422b 100644 --- a/libc/src/stdio.cpp +++ b/libc/src/stdio.cpp @@ -84,4 +84,5 @@ void debug_log_impl(const char* format, va_list ap) { pure_cstyle_format( format, [](char c, void*) { console_write(&c, 1); }, nullptr, ap); + console_write("\n", 1); } -- 2.34.1 From d82b3f809ba99c92a84e363c5f0930b699ef0189 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 17:37:38 +0100 Subject: [PATCH 14/44] luna: Add UB sanitizer, for both kernel-space and userspace --- luna/CMakeLists.txt | 1 + luna/include/luna/UBSAN.h | 74 +++++++++++++++++++++++ luna/src/UBSAN.cpp | 121 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 luna/include/luna/UBSAN.h create mode 100644 luna/src/UBSAN.cpp diff --git a/luna/CMakeLists.txt b/luna/CMakeLists.txt index 652c341c..b3eba9a3 100644 --- a/luna/CMakeLists.txt +++ b/luna/CMakeLists.txt @@ -17,6 +17,7 @@ set(FREESTANDING_SOURCES src/DebugLog.cpp src/Heap.cpp src/Spinlock.cpp + src/UBSAN.cpp ) set(SOURCES diff --git a/luna/include/luna/UBSAN.h b/luna/include/luna/UBSAN.h new file mode 100644 index 00000000..2e9202f5 --- /dev/null +++ b/luna/include/luna/UBSAN.h @@ -0,0 +1,74 @@ +#pragma once +#include + +namespace UBSAN +{ + struct SourceLocation + { + const char* file; + u32 line; + u32 column; + }; + + struct TypeDescriptor + { + u16 kind; + u16 info; + char name[]; + }; + + namespace UBInfo + { + struct TypeMismatchInfo + { + SourceLocation location; + TypeDescriptor* type; + usize alignment; + u8 type_check_kind; + }; + + struct TypeMismatchInfo_v1 + { + SourceLocation location; + TypeDescriptor* type; + u8 log_alignment; + u8 type_check_kind; + }; + + struct OverflowInfo + { + SourceLocation location; + TypeDescriptor* type; + }; + + struct UnreachableInfo + { + SourceLocation location; + }; + + struct OutOfBoundsInfo + { + SourceLocation location; + TypeDescriptor* array_type; + TypeDescriptor* index_type; + }; + + struct InvalidValueInfo + { + SourceLocation location; + TypeDescriptor* type; + }; + + struct ShiftOutOfBoundsInfo + { + SourceLocation location; + TypeDescriptor* lhs_type; + TypeDescriptor* rhs_type; + }; + + struct PointerOverflowInfo + { + SourceLocation location; + }; + } +} diff --git a/luna/src/UBSAN.cpp b/luna/src/UBSAN.cpp new file mode 100644 index 00000000..15e52676 --- /dev/null +++ b/luna/src/UBSAN.cpp @@ -0,0 +1,121 @@ +#include +#include +#include +#include + +using namespace UBSAN::UBInfo; + +[[noreturn]] void ub_panic(SourceLocation caller = SourceLocation::current()) +{ + expect_at(false, caller, "Undefined behavior"); +} + +#define DISPLAY(loc) loc.file, loc.line, loc.column + +extern "C" +{ + void __ubsan_handle_builtin_unreachable(UnreachableInfo* info) + { + const auto& location = info->location; + dbgln("ubsan: __builtin_unreachable reached at %s:%d:%d", DISPLAY(location)); + ub_panic(); + } + + void __ubsan_handle_pointer_overflow(PointerOverflowInfo* info) + { + const auto& location = info->location; + dbgln("ubsan: pointer overflow occurred at %s:%d:%d", DISPLAY(location)); + ub_panic(); + } + + void __ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsInfo* info) + { + const auto& location = info->location; + dbgln("ubsan: shift out of bounds for type %s at %s:%d:%d", info->lhs_type->name, DISPLAY(location)); + ub_panic(); + } + + void __ubsan_handle_load_invalid_value(InvalidValueInfo* info) + { + const auto& location = info->location; + dbgln("ubsan: load invalid value for type %s at %s:%d:%d", info->type->name, DISPLAY(location)); + ub_panic(); + } + + void __ubsan_handle_out_of_bounds(OutOfBoundsInfo* info, usize index) + { + const auto& location = info->location; + dbgln("ubsan: out of bounds array (of type %s) access (index %zu of type %s) at %s:%d:%d", + info->array_type->name, index, info->index_type->name, DISPLAY(location)); + ub_panic(); + } + + void ubsan_handle_generic_overflow(OverflowInfo* info, const char* overflow_type) + { + const auto& location = info->location; + dbgln("ubsan: %s overflow (value cannot fit into type %s) at %s:%d:%d", overflow_type, info->type->name, + DISPLAY(location)); + ub_panic(); + } + +#define UBSAN_OVERFLOW_BINARY(operation) \ + void __ubsan_handle_##operation##_overflow(OverflowInfo* info, usize, usize) \ + { \ + ubsan_handle_generic_overflow(info, #operation); \ + } + +#define UBSAN_OVERFLOW_UNARY(operation) \ + void __ubsan_handle_##operation##_overflow(OverflowInfo* info, usize) \ + { \ + ubsan_handle_generic_overflow(info, #operation); \ + } + + UBSAN_OVERFLOW_BINARY(add); + UBSAN_OVERFLOW_BINARY(sub); + UBSAN_OVERFLOW_BINARY(mul); + UBSAN_OVERFLOW_UNARY(negate); + UBSAN_OVERFLOW_BINARY(divrem); + +#define is_aligned(value, alignment) !(value & (alignment - 1)) + + const char* g_type_check_kinds[] = { + "load of", + "store to", + "reference binding to", + "member access within", + "member call on", + "constructor call on", + "downcast of", + "downcast of", + "upcast of", + "cast to virtual base of", + }; + + void __ubsan_handle_type_mismatch(TypeMismatchInfo* info, usize pointer) + { + const auto& location = info->location; + + if (pointer == 0) { dbgln("ubsan: null pointer access at %s:%d:%d", DISPLAY(location)); } + else if (info->alignment != 0 && is_aligned(pointer, info->alignment)) + { + dbgln("ubsan: unaligned pointer access (address %p) at %s:%d:%d", (void*)pointer, DISPLAY(location)); + } + else + { + dbgln("ubsan: %s address %p with insufficient space for object of type %s at %s:%d:%d", + g_type_check_kinds[info->type_check_kind], (void*)pointer, info->type->name, DISPLAY(location)); + } + ub_panic(); + } + + void __ubsan_handle_type_mismatch_v1(TypeMismatchInfo_v1* v1_info, usize pointer) + { + TypeMismatchInfo info = { + .location = v1_info->location, + .type = v1_info->type, + .alignment = 1UL << v1_info->log_alignment, + .type_check_kind = v1_info->type_check_kind, + }; + __ubsan_handle_type_mismatch(&info, pointer); + } +} -- 2.34.1 From 5f6a659fa11e14dfc3ddb666771daf7630cc8a46 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 17:37:50 +0100 Subject: [PATCH 15/44] kernel: Enable UBSAN when building in debug mode --- kernel/debug.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/debug.cmake b/kernel/debug.cmake index 74074888..c775e522 100644 --- a/kernel/debug.cmake +++ b/kernel/debug.cmake @@ -1 +1,2 @@ target_compile_definitions(moon PRIVATE LOCKED_VALUE_DEBUG) +target_compile_options(moon PRIVATE -fsanitize=undefined) -- 2.34.1 From dc795ff4912f78c1aa2c3bf4a4b0ff6c98cd01d5 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 17:41:28 +0100 Subject: [PATCH 16/44] luna: Introduce fail(...), a replacement for expect(false, ...) --- luna/include/luna/Check.h | 4 ++++ luna/src/UBSAN.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/luna/include/luna/Check.h b/luna/include/luna/Check.h index ce3b0472..07c5279c 100644 --- a/luna/include/luna/Check.h +++ b/luna/include/luna/Check.h @@ -19,6 +19,10 @@ if (!(expr)) [[unlikely]] { __check_failed(location, message); } \ } while (0) +// Fail with an error message and location. +#define fail(message) __check_failed(SourceLocation::current(), message) +#define fail_at(location, message) __check_failed(location, message) + // Like assert(), but always enabled. #define check(expr) \ do { \ diff --git a/luna/src/UBSAN.cpp b/luna/src/UBSAN.cpp index 15e52676..4f3c25d2 100644 --- a/luna/src/UBSAN.cpp +++ b/luna/src/UBSAN.cpp @@ -7,7 +7,7 @@ using namespace UBSAN::UBInfo; [[noreturn]] void ub_panic(SourceLocation caller = SourceLocation::current()) { - expect_at(false, caller, "Undefined behavior"); + fail_at(caller, "Undefined behavior"); } #define DISPLAY(loc) loc.file, loc.line, loc.column -- 2.34.1 From 32ada00b72db0c929e22b4dcc154fb6df061f893 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 17:42:32 +0100 Subject: [PATCH 17/44] kernel: Add a guard page to the bootstrap stack so that we can catch more stack overflows --- kernel/src/main.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 2b3e3ffc..b743d553 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -97,12 +97,27 @@ Result init() CPU::idle_loop(); } -// FIXME: Add a guard page to make sure the stack doesn't end up in random kernel memory. Also reclaim this memory after -// leaving the init task. +static constexpr u64 BOOTSTRAP_STACK_PAGES = 8; + +// FIXME: Reclaim this memory as soon as we leave the init task (so as soon as the Scheduler runs a task switch) +static u64 allocate_initial_kernel_stack() +{ + u64 address = MemoryManager::alloc_for_kernel(BOOTSTRAP_STACK_PAGES + 1, MMU::ReadWrite | MMU::NoExecute).value(); + // First page is a guard page, the rest is stack. + MMU::unmap(address); // Unmap (without deallocating VM) one guard page so that attempts to access it fail with a + // non-present page fault. + kdbgln("stack guard page: %p", (void*)address); + + // The actual stack. + Stack stack { address + ARCH_PAGE_SIZE, BOOTSTRAP_STACK_PAGES * ARCH_PAGE_SIZE }; + + return stack.top(); +} + extern "C" [[noreturn]] void _start() { Init::check_magic(); Init::early_init(); - Stack stack { MemoryManager::alloc_for_kernel(8, MMU::ReadWrite | MMU::NoExecute).value(), 8 * ARCH_PAGE_SIZE }; - CPU::bootstrap_switch_stack(stack.top(), (void*)init_wrapper); + u64 bootstrap_stack_top = allocate_initial_kernel_stack(); + CPU::bootstrap_switch_stack(bootstrap_stack_top, (void*)init_wrapper); } -- 2.34.1 From 620810d720d1942a1daf34e600e607d0122dc4df Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 3 Feb 2023 22:19:26 +0100 Subject: [PATCH 18/44] SharedPtr: Delete ptr on failure in all adopt_shared* functions --- luna/include/luna/SharedPtr.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/luna/include/luna/SharedPtr.h b/luna/include/luna/SharedPtr.h index 020c37a5..2ddf3b5d 100644 --- a/luna/include/luna/SharedPtr.h +++ b/luna/include/luna/SharedPtr.h @@ -123,10 +123,18 @@ template Result> adopt_shared(T* ptr) return SharedPtr { ptr, ref_count }; } -template Result> make_shared(Args... args) +// NOTE: ptr is deleted if any of the adopt_shared* functions fail to construct a SharedPtr. +template Result> adopt_shared(T* ptr) { - T* raw_ptr = TRY(make(args...)); - return adopt_shared(raw_ptr); + using RefCount = __detail::RefCount; + + auto guard = make_scope_guard([ptr] { delete ptr; }); + + RefCount* const ref_count = TRY(make()); + + guard.deactivate(); + + return SharedPtr { ptr, ref_count }; } template Result> adopt_shared_if_nonnull(T* ptr) -- 2.34.1 From 6fc02e042afcd26d7fa74117da2bcb74645a1642 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 14 Feb 2023 19:59:44 +0100 Subject: [PATCH 19/44] SharedPtr: Implement make_shared using adopt_shared --- luna/include/luna/SharedPtr.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/luna/include/luna/SharedPtr.h b/luna/include/luna/SharedPtr.h index 2ddf3b5d..8197f4ab 100644 --- a/luna/include/luna/SharedPtr.h +++ b/luna/include/luna/SharedPtr.h @@ -137,6 +137,12 @@ template Result> adopt_shared(T* ptr) return SharedPtr { ptr, ref_count }; } +template Result> make_shared(Args... args) +{ + T* raw_ptr = TRY(make(args...)); + return adopt_shared(raw_ptr); +} + template Result> adopt_shared_if_nonnull(T* ptr) { if (ptr) return adopt_shared(ptr); -- 2.34.1 From 045efc7046b81528389c3504f6c175d24097685d Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 17:09:03 +0100 Subject: [PATCH 20/44] kernel, luna: Port non-VFS changes over from pull request #22 OwnedPtr, SharedPtr: Add operator bool Option, Result: Make try_move_value() non-const since it modifies the Option kernel: Switch to a stack we control for the main task as soon as we leave early boot Heap: Fix GPF caused when making many small allocations Heap: Avoid accessing a block after it's potentially deleted luna: Skip UBSAN.cpp in CMakeLists as that's not implemented yet luna: Use spinlocks in the heap implementation kernel, luna: Move Spinlock.h to luna Option: Use __builtin_launder to ensure that the compiler doesn't label this as UB SharedPtr: Implement make_shared using adopt_shared SharedPtr: Delete ptr on failure in all adopt_shared* functions --- luna/include/luna/SharedPtr.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/luna/include/luna/SharedPtr.h b/luna/include/luna/SharedPtr.h index 8197f4ab..020c37a5 100644 --- a/luna/include/luna/SharedPtr.h +++ b/luna/include/luna/SharedPtr.h @@ -123,20 +123,6 @@ template Result> adopt_shared(T* ptr) return SharedPtr { ptr, ref_count }; } -// NOTE: ptr is deleted if any of the adopt_shared* functions fail to construct a SharedPtr. -template Result> adopt_shared(T* ptr) -{ - using RefCount = __detail::RefCount; - - auto guard = make_scope_guard([ptr] { delete ptr; }); - - RefCount* const ref_count = TRY(make()); - - guard.deactivate(); - - return SharedPtr { ptr, ref_count }; -} - template Result> make_shared(Args... args) { T* raw_ptr = TRY(make(args...)); -- 2.34.1 From 5edd3161989696eb6d76b0d1b0a3f081ee66d91d Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 17:54:01 +0100 Subject: [PATCH 21/44] kernel: Add a subclass of VFS::Inode to make it easier to implement file inodes --- kernel/src/fs/VFS.h | 18 +++++++++++++++++- kernel/src/fs/tmpfs/FileSystem.h | 7 +------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index ea9a8084..5e5e6387 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -20,7 +20,23 @@ namespace VFS virtual ~Inode() = default; - InodeType type; + virtual InodeType type() const = 0; + }; + + class FileInode : Inode + { + public: + Result find(const char*) const override + { + return err(ENOTDIR); + } + + InodeType type() const override + { + return InodeType::RegularFile; + } + + virtual ~FileInode() = default; }; class FileSystem diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 81a4b996..2b41105f 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -26,18 +26,13 @@ namespace TmpFS Vector> m_inodes; }; - class Inode : public VFS::Inode + class Inode : public VFS::FileInode { public: Inode(); void set_fs(FileSystem& fs, Badge); - Result find(const char*) const override - { - return err(ENOTSUP); - } - VFS::FileSystem& fs() const override { return *m_fs; -- 2.34.1 From ddc4692671a70e993e9a9cc534a4c04322693f66 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 18:03:11 +0100 Subject: [PATCH 22/44] kernel: Make a factory function for filesystem creation of inodes, and add inode numbers Now every filesystem must provide fs->create_file_inode() for new inodes :) --- kernel/src/fs/VFS.h | 4 ++++ kernel/src/fs/tmpfs/FileSystem.cpp | 25 ++++++++++--------------- kernel/src/fs/tmpfs/FileSystem.h | 26 ++++++++++++++++++++++---- kernel/src/main.cpp | 3 +++ 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 5e5e6387..ac1ec564 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -21,6 +21,8 @@ namespace VFS virtual ~Inode() = default; virtual InodeType type() const = 0; + + virtual usize inode_number() const = 0; }; class FileInode : Inode @@ -44,6 +46,8 @@ namespace VFS public: virtual Inode& root() const = 0; + virtual Result> create_file_inode() = 0; + virtual ~FileSystem() = default; }; diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index 45631fc4..eefac905 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -5,29 +5,24 @@ namespace TmpFS { Result> FileSystem::create() { - SharedPtr root = TRY(make_shared()); SharedPtr fs = TRY(adopt_shared(new (std::nothrow) FileSystem())); - root->set_fs(*fs, {}); - TRY(fs->set_root(root)); + SharedPtr root = TRY(fs->create_file_inode()); + fs->set_root(root); return (SharedPtr)fs; } - FileSystem::FileSystem() + Result> FileSystem::create_file_inode() { + SharedPtr inode = TRY(make_shared()); + inode->set_fs(*this, {}); + inode->set_inode_number(m_next_inode_number, {}); + TRY(m_inodes.try_append(inode)); + m_next_inode_number++; + return (SharedPtr)inode; } - Result FileSystem::set_root(SharedPtr root) + void FileSystem::set_root(SharedPtr root) { m_root_inode = root; - return m_inodes.try_append(root); - } - - Inode::Inode() - { - } - - void Inode::set_fs(FileSystem& fs, Badge) - { - m_fs = &fs; } } diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 2b41105f..75929143 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -13,34 +13,52 @@ namespace TmpFS return *m_root_inode; } + Result> create_file_inode() override; + static Result> create(); virtual ~FileSystem() = default; private: - FileSystem(); + FileSystem() = default; - Result set_root(SharedPtr root); + void set_root(SharedPtr root); SharedPtr m_root_inode; Vector> m_inodes; + + usize m_next_inode_number { 2 }; }; class Inode : public VFS::FileInode { public: - Inode(); + Inode() = default; - void set_fs(FileSystem& fs, Badge); + void set_fs(FileSystem& fs, Badge) + { + m_fs = &fs; + } + + void set_inode_number(usize inum, Badge) + { + m_inode_number = inum; + } VFS::FileSystem& fs() const override { return *m_fs; } + usize inode_number() const override + { + return m_inode_number; + } + virtual ~Inode() = default; private: VFS::FileSystem* m_fs; + usize m_inode_number; }; } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index b743d553..f0c83f7b 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -58,6 +58,9 @@ Result init() VFS::root_fs = TRY(TmpFS::FileSystem::create()); + VFS::Inode& root_inode = VFS::root_fs->root(); + kinfoln("root inode number: %zu", root_inode.inode_number()); + TarStream::Entry entry; while (TRY(g_initrd.read_next_entry(entry))) { -- 2.34.1 From 6daad7787ae03b156d70c2bf20f4fccfa9d563d0 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 18:05:25 +0100 Subject: [PATCH 23/44] kernel: Rename FileSystem::root() to root_inode() and add a shortcut for the root filesystem's root inode --- kernel/src/fs/VFS.cpp | 5 +++++ kernel/src/fs/VFS.h | 4 +++- kernel/src/fs/tmpfs/FileSystem.h | 2 +- kernel/src/main.cpp | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/kernel/src/fs/VFS.cpp b/kernel/src/fs/VFS.cpp index dfa9b609..1da679c4 100644 --- a/kernel/src/fs/VFS.cpp +++ b/kernel/src/fs/VFS.cpp @@ -3,4 +3,9 @@ namespace VFS { SharedPtr root_fs; + + Inode& root_inode() + { + return root_fs->root_inode(); + } } diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index ac1ec564..78801006 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -44,7 +44,7 @@ namespace VFS class FileSystem { public: - virtual Inode& root() const = 0; + virtual Inode& root_inode() const = 0; virtual Result> create_file_inode() = 0; @@ -54,4 +54,6 @@ namespace VFS extern SharedPtr root_fs; Result resolve_path(const char* path); + + Inode& root_inode(); } diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 75929143..77c012c1 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -8,7 +8,7 @@ namespace TmpFS class FileSystem : public VFS::FileSystem { public: - VFS::Inode& root() const override + VFS::Inode& root_inode() const override { return *m_root_inode; } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index f0c83f7b..b65c997d 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -58,7 +58,7 @@ Result init() VFS::root_fs = TRY(TmpFS::FileSystem::create()); - VFS::Inode& root_inode = VFS::root_fs->root(); + VFS::Inode& root_inode = VFS::root_inode(); kinfoln("root inode number: %zu", root_inode.inode_number()); TarStream::Entry entry; -- 2.34.1 From 05b627d03717fd1b1a7a0aa6f4dc5505fd836c56 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 18:06:23 +0100 Subject: [PATCH 24/44] tmpfs: Make m_next_inode_number atomic --- kernel/src/fs/tmpfs/FileSystem.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 77c012c1..b92a5072 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -1,5 +1,6 @@ #pragma once #include "fs/VFS.h" +#include #include #include @@ -27,7 +28,7 @@ namespace TmpFS SharedPtr m_root_inode; Vector> m_inodes; - usize m_next_inode_number { 2 }; + Atomic m_next_inode_number { 2 }; }; class Inode : public VFS::FileInode -- 2.34.1 From b71d899b5223877f8a2393837966cf89dae12f58 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 18:11:39 +0100 Subject: [PATCH 25/44] tmpfs: rename tmpfs::Inode to tmpfs::FileInode --- kernel/src/fs/tmpfs/FileSystem.cpp | 2 +- kernel/src/fs/tmpfs/FileSystem.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index eefac905..14010ee7 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -13,7 +13,7 @@ namespace TmpFS Result> FileSystem::create_file_inode() { - SharedPtr inode = TRY(make_shared()); + SharedPtr inode = TRY(make_shared()); inode->set_fs(*this, {}); inode->set_inode_number(m_next_inode_number, {}); TRY(m_inodes.try_append(inode)); diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index b92a5072..070a6e51 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -31,10 +31,10 @@ namespace TmpFS Atomic m_next_inode_number { 2 }; }; - class Inode : public VFS::FileInode + class FileInode : public VFS::FileInode { public: - Inode() = default; + FileInode() = default; void set_fs(FileSystem& fs, Badge) { @@ -56,7 +56,7 @@ namespace TmpFS return m_inode_number; } - virtual ~Inode() = default; + virtual ~FileInode() = default; private: VFS::FileSystem* m_fs; -- 2.34.1 From 0635f1c243ccfe6ec5e8a75f93d0eb1a771c3168 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 18:19:00 +0100 Subject: [PATCH 26/44] Update README.md with realism --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index badbb794..c845198c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A simple kernel and userspace for desktop computers, written mostly in C++ and C - [System call](kernel/src/sys/) interface and [C Library](libc/), aiming to be mostly POSIX-compatible. - Designed to be [portable](kernel/src/arch), no need to be restricted to x86_64. - Fully [UTF-8 aware](luna/include/luna/Utf8.h), **everywhere**. -- [Thread](luna/include/luna/Atomic.h) [safety](kernel/src/thread/Spinlock.h). +- [Thread](luna/include/luna/Atomic.h) [safety](kernel/src/thread/Spinlock.h) (supposedly). - Environment-agnostic [utility library](luna/), which can be used in both kernel and userspace. - Return-oriented [error propagation](luna/include/luna/Result.h), inspired by Rust and SerenityOS. - Build system uses [CMake](CMakeLists.txt). @@ -72,7 +72,7 @@ These images do reflect the latest changes on the `main` branch, but are obvious ## Is there third-party software I can use on Luna? -Not right now, but hopefully we can start porting some software soon! +Not right now, but hopefully we can start porting some software soon! (After the VFS and fork/exec are done, of course. So, in a long time.) ## License Luna is open-source and free software under the [BSD-2 License](LICENSE). -- 2.34.1 From cca4743a510b0f54ab4fef25ebbc7d475ac3abb1 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 19:06:50 +0100 Subject: [PATCH 27/44] tmpfs: add DirInode skeleton --- kernel/src/fs/VFS.h | 4 +-- kernel/src/fs/tmpfs/FileSystem.cpp | 7 ++++++ kernel/src/fs/tmpfs/FileSystem.h | 39 ++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 78801006..843ad15c 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -14,7 +14,7 @@ namespace VFS class Inode { public: - virtual Result find(const char* name) const = 0; + virtual Result> find(const char* name) const = 0; virtual FileSystem& fs() const = 0; @@ -28,7 +28,7 @@ namespace VFS class FileInode : Inode { public: - Result find(const char*) const override + Result> find(const char*) const override { return err(ENOTDIR); } diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index 14010ee7..934e8437 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -1,5 +1,6 @@ #include "fs/tmpfs/FileSystem.h" #include +#include namespace TmpFS { @@ -25,4 +26,10 @@ namespace TmpFS { m_root_inode = root; } + + Result> DirInode::find(const char* name) const + { + ignore(name); + todo(); + } } diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 070a6e51..817af741 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -62,4 +62,43 @@ namespace TmpFS VFS::FileSystem* m_fs; usize m_inode_number; }; + + class DirInode : public VFS::Inode + { + public: + DirInode() = default; + + void set_fs(FileSystem& fs, Badge) + { + m_fs = &fs; + } + + void set_inode_number(usize inum, Badge) + { + m_inode_number = inum; + } + + Result> find(const char* name) const override; + + VFS::FileSystem& fs() const override + { + return *m_fs; + } + + usize inode_number() const override + { + return m_inode_number; + } + + VFS::InodeType type() const override + { + return VFS::InodeType::Directory; + } + + virtual ~DirInode() = default; + + private: + VFS::FileSystem* m_fs; + usize m_inode_number; + }; } -- 2.34.1 From 9248a5b3cc1d22ea7e6f5bcf03f6ba3ee8d53e98 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 19:08:55 +0100 Subject: [PATCH 28/44] tmpfs: make the root inode a DirInode instead of a FileInode --- kernel/src/fs/VFS.h | 2 ++ kernel/src/fs/tmpfs/FileSystem.cpp | 12 +++++++++++- kernel/src/fs/tmpfs/FileSystem.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 843ad15c..92c4d98e 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -48,6 +48,8 @@ namespace VFS virtual Result> create_file_inode() = 0; + virtual Result> create_dir_inode() = 0; + virtual ~FileSystem() = default; }; diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index 934e8437..3d55ffa7 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -7,7 +7,7 @@ namespace TmpFS Result> FileSystem::create() { SharedPtr fs = TRY(adopt_shared(new (std::nothrow) FileSystem())); - SharedPtr root = TRY(fs->create_file_inode()); + SharedPtr root = TRY(fs->create_dir_inode()); fs->set_root(root); return (SharedPtr)fs; } @@ -22,6 +22,16 @@ namespace TmpFS return (SharedPtr)inode; } + Result> FileSystem::create_dir_inode() + { + SharedPtr inode = TRY(make_shared()); + inode->set_fs(*this, {}); + inode->set_inode_number(m_next_inode_number, {}); + TRY(m_inodes.try_append(inode)); + m_next_inode_number++; + return (SharedPtr)inode; + } + void FileSystem::set_root(SharedPtr root) { m_root_inode = root; diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 817af741..c6ac85ae 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -15,6 +15,7 @@ namespace TmpFS } Result> create_file_inode() override; + Result> create_dir_inode() override; static Result> create(); -- 2.34.1 From 5b43345b7d441facf2ab1a40492ec97d5e7c61c0 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 19:22:05 +0100 Subject: [PATCH 29/44] kernel: Implement creating file inodes in tmpfs directories --- kernel/src/fs/VFS.h | 9 +++++++++ kernel/src/fs/tmpfs/FileSystem.cpp | 28 ++++++++++++++++++++++++++-- kernel/src/fs/tmpfs/FileSystem.h | 13 +++++++++++++ kernel/src/main.cpp | 3 +++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 92c4d98e..9c89f273 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -14,8 +14,12 @@ namespace VFS class Inode { public: + // Directory-specific methods virtual Result> find(const char* name) const = 0; + virtual Result> create_file(const char* name) = 0; + + // Generic methods virtual FileSystem& fs() const = 0; virtual ~Inode() = default; @@ -33,6 +37,11 @@ namespace VFS return err(ENOTDIR); } + Result> create_file(const char*) override + { + return err(ENOTDIR); + } + InodeType type() const override { return InodeType::RegularFile; diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index 3d55ffa7..4606743e 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -25,6 +25,8 @@ namespace TmpFS Result> FileSystem::create_dir_inode() { SharedPtr inode = TRY(make_shared()); + TRY(inode->add_entry(inode, ".")); + inode->set_fs(*this, {}); inode->set_inode_number(m_next_inode_number, {}); TRY(m_inodes.try_append(inode)); @@ -39,7 +41,29 @@ namespace TmpFS Result> DirInode::find(const char* name) const { - ignore(name); - todo(); + for (const auto& entry : m_entries) + { + if (!strcmp(name, entry.name.chars())) return entry.inode; + } + + return err(ENOENT); + } + + Result DirInode::add_entry(SharedPtr inode, const char* name) + { + Entry entry = { inode, TRY(OwnedStringView::from_string_literal(name)) }; + + TRY(m_entries.try_append(move(entry))); + + return {}; + } + + Result> DirInode::create_file(const char* name) + { + auto inode = TRY(m_fs->create_file_inode()); + + TRY(add_entry(inode, name)); + + return inode; } } diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index c6ac85ae..044a26a5 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -2,6 +2,7 @@ #include "fs/VFS.h" #include #include +#include #include namespace TmpFS @@ -96,10 +97,22 @@ namespace TmpFS return VFS::InodeType::Directory; } + Result> create_file(const char* name) override; + + Result add_entry(SharedPtr inode, const char* name); + virtual ~DirInode() = default; private: VFS::FileSystem* m_fs; usize m_inode_number; + + struct Entry + { + SharedPtr inode; + OwnedStringView name; + }; + + Vector m_entries; }; } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index b65c997d..3427cf6e 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -61,6 +61,9 @@ Result init() VFS::Inode& root_inode = VFS::root_inode(); kinfoln("root inode number: %zu", root_inode.inode_number()); + TRY(root_inode.create_file("usr")); + kinfoln("root inode's 'usr' entry inode number: %zu", TRY(root_inode.find("usr"))->inode_number()); + TarStream::Entry entry; while (TRY(g_initrd.read_next_entry(entry))) { -- 2.34.1 From 78cea0a47e55e9cc0582eef93ab163f89cd12315 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 12:24:21 +0100 Subject: [PATCH 30/44] x86_64/MMU: Map all physical memory into the higher half instead of using recursive mapping This still has a few problems. Notably, we are not using huge pages for this mapping, which would be a lot more efficient. Right now, used memory is 8.1 MiB at boot for a 256MiB system. But after improving it, this system will be much better than recursive mapping. fork() will be MUCH easier to implement, for example. --- kernel/src/arch/x86_64/MMU.cpp | 225 +++++++++++++++------------------ 1 file changed, 99 insertions(+), 126 deletions(-) diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index 2bd6ee49..2f85f238 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -1,6 +1,8 @@ #include "arch/MMU.h" #include "Log.h" #include "memory/MemoryManager.h" +#include "memory/MemoryMap.h" +#include #include #include #include @@ -12,6 +14,10 @@ PageDirectory* g_kernel_directory; u64 g_kernel_directory_virt; +// The bootloader maps up to 16GiB of physical memory for us at address 0. Using this bootstrap mapping, we'll map (all) +// physical memory at 0xFFFF800000000000. +u64 g_physical_mapping_base = 0; + void PageTableEntry::set_address(u64 addr) { this->address = (addr >> 12); @@ -36,90 +42,9 @@ static bool has_flag(int flags, MMU::Flags flag) namespace MMU { - - constexpr PageDirectory* l4_table() + template T translate_physical(T phys) { - constexpr u64 l4 = sign | (rindex << 39) | (rindex << 30) | (rindex << 21) | (rindex << 12); - return (PageDirectory*)l4; - } - - constexpr u64 l4_index(u64 addr) - { - return (addr >> 39) & 0777; - } - - PageTableEntry& l4_entry(u64 addr) - { - return l4_table()->entries[l4_index(addr)]; - } - - constexpr PageDirectory* raw_l3_table(u64 l4) - { - const u64 l3 = sign | (rindex << 39) | (rindex << 30) | (rindex << 21) | (l4 << 12); - return (PageDirectory*)l3; - } - - constexpr PageDirectory* l3_table(u64 addr) - { - const u64 l4 = l4_index(addr); - return raw_l3_table(l4); - } - - constexpr u64 l3_index(u64 addr) - { - return (addr >> 30) & 0777; - } - - PageTableEntry& l3_entry(u64 addr) - { - return l3_table(addr)->entries[l3_index(addr)]; - } - - constexpr PageDirectory* raw_l2_table(u64 l4, u64 l3) - { - const u64 l2 = sign | (rindex << 39) | (rindex << 30) | (l4 << 21) | (l3 << 12); - return (PageDirectory*)l2; - } - - constexpr PageDirectory* l2_table(u64 addr) - { - const u64 l4 = l4_index(addr); - const u64 l3 = l3_index(addr); - return raw_l2_table(l4, l3); - } - - constexpr u64 l2_index(u64 addr) - { - return (addr >> 21) & 0777; - } - - PageTableEntry& l2_entry(u64 addr) - { - return l2_table(addr)->entries[l2_index(addr)]; - } - - constexpr PageDirectory* raw_l1_table(u64 l4, u64 l3, u64 l2) - { - const u64 l1 = sign | (rindex << 39) | (l4 << 30) | (l3 << 21) | (l2 << 12); - return (PageDirectory*)l1; - } - - constexpr PageDirectory* l1_table(u64 addr) - { - const u64 l4 = l4_index(addr); - const u64 l3 = l3_index(addr); - const u64 l2 = l2_index(addr); - return raw_l1_table(l4, l3, l2); - } - - constexpr u64 l1_index(u64 addr) - { - return (addr >> 12) & 0777; - } - - PageTableEntry& l1_entry(u64 addr) - { - return l1_table(addr)->entries[l1_index(addr)]; + return (T)(g_physical_mapping_base + (u64)phys); } void switch_page_directory(PageDirectory* dir) @@ -134,6 +59,11 @@ namespace MMU return value; } + PageDirectory* get_virtual_page_directory() + { + return translate_physical(get_page_directory()); + } + void flush_all() { switch_page_directory(get_page_directory()); @@ -144,6 +74,26 @@ namespace MMU asm volatile("invlpg (%0)" : : "r"(page) : "memory"); } + constexpr u64 l4_index(u64 addr) + { + return (addr >> 39) & 0777; + } + + constexpr u64 l3_index(u64 addr) + { + return (addr >> 30) & 0777; + } + + constexpr u64 l2_index(u64 addr) + { + return (addr >> 21) & 0777; + } + + constexpr u64 l1_index(u64 addr) + { + return (addr >> 12) & 0777; + } + int arch_flags_to_mmu(const PageTableEntry& entry) { int result = Flags::None; @@ -155,17 +105,46 @@ namespace MMU return result; } + PageTableEntry& l4_entry(u64 virt) + { + auto index = l4_index(virt); + return get_virtual_page_directory()->entries[index]; + } + + PageDirectory& page_table(const PageTableEntry& entry) + { + return *translate_physical((PageDirectory*)entry.get_address()); + } + + PageTableEntry& l3_entry(const PageTableEntry& entry, u64 virt) + { + auto index = l3_index(virt); + return page_table(entry).entries[index]; + } + + PageTableEntry& l2_entry(const PageTableEntry& entry, u64 virt) + { + auto index = l2_index(virt); + return page_table(entry).entries[index]; + } + + PageTableEntry& l1_entry(const PageTableEntry& entry, u64 virt) + { + auto index = l1_index(virt); + return page_table(entry).entries[index]; + } + Result find_entry(u64 virt) { const auto& l4 = l4_entry(virt); if (!l4.present) return err(EFAULT); - auto& l3 = l3_entry(virt); + auto& l3 = l3_entry(l4, virt); if (!l3.present) return err(EFAULT); if (l3.larger_pages) return &l3; - auto& l2 = l2_entry(virt); + auto& l2 = l2_entry(l3, virt); if (!l2.present) return err(EFAULT); if (l2.larger_pages) return &l2; - return &l1_entry(virt); + return &l1_entry(l2, virt); } Result apply_cascading_flags(u64 virt, int flags) @@ -174,17 +153,17 @@ namespace MMU if (!l4.present) return err(EFAULT); if (flags & Flags::ReadWrite) l4.read_write = true; if (flags & Flags::User) l4.user = true; - auto& l3 = l3_entry(virt); + auto& l3 = l3_entry(l4, virt); if (!l3.present) return err(EFAULT); if (l3.larger_pages) return &l3; if (flags & Flags::ReadWrite) l3.read_write = true; if (flags & Flags::User) l3.user = true; - auto& l2 = l2_entry(virt); + auto& l2 = l2_entry(l3, virt); if (!l2.present) return err(EFAULT); if (l2.larger_pages) return &l2; if (flags & Flags::ReadWrite) l2.read_write = true; if (flags & Flags::User) l2.user = true; - auto& l1 = l1_entry(virt); + auto& l1 = l1_entry(l2, virt); return &l1; } @@ -196,38 +175,38 @@ namespace MMU const u64 addr = TRY(MemoryManager::alloc_frame()); l4.present = true; l4.set_address(addr); - memset(l3_table(virt), 0, ARCH_PAGE_SIZE); + memset(&page_table(l4), 0, ARCH_PAGE_SIZE); } if (flags & Flags::ReadWrite) l4.read_write = true; if (flags & Flags::User) l4.user = true; - auto& l3 = l3_entry(virt); + auto& l3 = l3_entry(l4, virt); if (!l3.present) { const u64 addr = TRY(MemoryManager::alloc_frame()); l3.present = true; l3.set_address(addr); - memset(l2_table(virt), 0, ARCH_PAGE_SIZE); + memset(&page_table(l3), 0, ARCH_PAGE_SIZE); } if (flags & Flags::ReadWrite) l3.read_write = true; if (flags & Flags::User) l3.user = true; if (l3.larger_pages) return err(EFIXME); // FIXME: Replacing larger pages is not supported ATM - auto& l2 = l2_entry(virt); + auto& l2 = l2_entry(l3, virt); if (!l2.present) { const u64 addr = TRY(MemoryManager::alloc_frame()); l2.present = true; l2.set_address(addr); - memset(l1_table(virt), 0, ARCH_PAGE_SIZE); + memset(&page_table(l2), 0, ARCH_PAGE_SIZE); } if (flags & Flags::ReadWrite) l2.read_write = true; if (flags & Flags::User) l2.user = true; if (l2.larger_pages) return err(EFIXME); // FIXME: Replacing larger pages is not supported ATM - auto& l1 = l1_entry(virt); + auto& l1 = l1_entry(l2, virt); if (l1.present) return err(EEXIST); // Please explicitly unmap the page before mapping it again. l1.present = true; l1.read_write = has_flag(flags, Flags::ReadWrite); @@ -281,39 +260,38 @@ namespace MMU PageDirectory* const dir = get_page_directory(); g_kernel_directory = dir; - const u64 paddr = (u64)dir; - PageTableEntry& recursive_entry = dir->entries[rindex]; - recursive_entry.read_write = true; - recursive_entry.present = true; - recursive_entry.set_address(paddr); - flush_all(); + const u64 physical_memory_base = 0xFFFF800000000000; - g_kernel_directory_virt = - MemoryManager::get_kernel_mapping_for_frames((u64)dir, 1, MMU::ReadWrite | MMU::NoExecute).value(); + MemoryMapIterator iter; + const MemoryMapEntry highest_entry = iter.highest(); + + const u64 physical_memory_size = highest_entry.address() + highest_entry.size(); + + // FIXME: Do this using 2MiB huge pages. + MemoryManager::map_frames_at(physical_memory_base, 0, physical_memory_size / ARCH_PAGE_SIZE, + MMU::ReadWrite | MMU::NoExecute); + + g_physical_mapping_base = physical_memory_base; + + g_kernel_directory_virt = translate_physical((u64)g_kernel_directory); kdbgln("MMU init page directory (ring0): virt %#.16lx, phys %p", g_kernel_directory_virt, g_kernel_directory); } Result create_page_directory_for_userspace() { - const u64 directory_virt = TRY(MemoryManager::alloc_for_kernel(1, MMU::ReadWrite | MMU::NoExecute)); - const u64 directory_phys = MMU::get_physical(directory_virt).value(); + const u64 directory_phys = TRY(MemoryManager::alloc_frame()); + const u64 directory_virt = translate_physical(directory_phys); PageDirectory* const directory = (PageDirectory*)directory_virt; memset(directory, 0, ARCH_PAGE_SIZE); - PageTableEntry& recursive_entry = directory->entries[rindex]; - recursive_entry.read_write = true; - recursive_entry.present = true; - recursive_entry.set_address(directory_phys); + + constexpr auto HALF_PAGE = ARCH_PAGE_SIZE / 2; + // Copy the upper part of the page directory (higher half) + memcpy(offset_ptr(directory, HALF_PAGE), offset_ptr(g_kernel_directory, HALF_PAGE), HALF_PAGE); kdbgln("MMU init page directory (ring3): virt %p, phys %#.16lx", directory, directory_phys); - directory->entries[511] = ((PageDirectory*)g_kernel_directory_virt)->entries[511]; - - // From now on, we're only going to use the physical address, since accessing the PageDirectory will be dealt - // with using recursive mapping. So let's make sure we don't leak any VM. - MemoryManager::unmap_weak_and_free_vm(directory_virt, 1); - return (PageDirectory*)directory_phys; } @@ -321,16 +299,11 @@ namespace MMU { check(directory); - // Needed in order to access page tables using the recursive mapping system. - switch_page_directory(directory); + switch_page_directory(g_kernel_directory); - auto guard = make_scope_guard([&] { - check(g_kernel_directory); - switch_page_directory(g_kernel_directory); - MemoryManager::free_frame((u64)directory); - }); + auto guard = make_scope_guard([directory] { MemoryManager::free_frame((u64)directory); }); - PageDirectory* const table = l4_table(); + PageDirectory* const table = translate_physical(directory); // Let's iterate over every top-level entry, skipping the last two entries (recursive mapping and kernel pages) for (u64 i = 0; i < 510; i++) @@ -338,7 +311,7 @@ namespace MMU PageTableEntry& l4 = table->entries[i]; if (!l4.present) continue; - PageDirectory* const pdp = raw_l3_table(i); + PageDirectory* const pdp = &page_table(l4); for (u64 j = 0; j < 512; j++) { @@ -350,7 +323,7 @@ namespace MMU TRY(MemoryManager::free_frame(l3.get_address())); } - PageDirectory* const pd = raw_l2_table(i, j); + PageDirectory* const pd = &page_table(l3); for (u64 k = 0; k < 512; k++) { @@ -362,7 +335,7 @@ namespace MMU TRY(MemoryManager::free_frame(l2.get_address())); } - PageDirectory* const pt = raw_l1_table(i, j, k); + PageDirectory* const pt = &page_table(l2); for (u64 l = 0; l < 512; l++) { -- 2.34.1 From 9da52040798d8180a0c218e3ceddf2c745f0f3cf Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 12:30:52 +0100 Subject: [PATCH 31/44] x86_64/MMU: Copy from the mapped kernel directory instead of the physical version --- kernel/src/arch/x86_64/MMU.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index 2f85f238..0e04332b 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -288,7 +288,8 @@ namespace MMU constexpr auto HALF_PAGE = ARCH_PAGE_SIZE / 2; // Copy the upper part of the page directory (higher half) - memcpy(offset_ptr(directory, HALF_PAGE), offset_ptr(g_kernel_directory, HALF_PAGE), HALF_PAGE); + memcpy(offset_ptr(directory, HALF_PAGE), offset_ptr((PageDirectory*)g_kernel_directory_virt, HALF_PAGE), + HALF_PAGE); kdbgln("MMU init page directory (ring3): virt %p, phys %#.16lx", directory, directory_phys); -- 2.34.1 From efdd64736f22f922f99a2e8c0201088a82ccdc28 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 12:41:28 +0100 Subject: [PATCH 32/44] x86_64: Allow mapping huge pages, but don't do it yet --- kernel/src/arch/MMU.h | 10 +++++++++- kernel/src/arch/x86_64/MMU.cpp | 31 +++++++++++++++++++---------- kernel/src/arch/x86_64/MMU.h | 1 + kernel/src/memory/MemoryManager.cpp | 8 ++++---- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/kernel/src/arch/MMU.h b/kernel/src/arch/MMU.h index 031c038e..addd5863 100644 --- a/kernel/src/arch/MMU.h +++ b/kernel/src/arch/MMU.h @@ -7,6 +7,8 @@ #error "Unknown architecture." #endif +constexpr u64 PAGES_PER_HUGE_PAGE = ARCH_HUGE_PAGE_SIZE / ARCH_PAGE_SIZE; + namespace MMU { enum Flags @@ -19,7 +21,13 @@ namespace MMU CacheDisable = 16, }; - Result map(u64 virt, u64 phys, int flags); + enum class UseHugePages + { + No = 0, + Yes = 1 + }; + + Result map(u64 virt, u64 phys, int flags, UseHugePages use_huge_pages); Result unmap(u64 virt); Result get_physical(u64 virt); Result get_flags(u64 virt); diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index 0e04332b..de239a22 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -167,7 +167,18 @@ namespace MMU return &l1; } - Result map(u64 virt, u64 phys, int flags) + void set_page_table_entry_properties(PageTableEntry& entry, u64 phys, int flags) + { + entry.present = true; + entry.read_write = has_flag(flags, Flags::ReadWrite); + entry.user = has_flag(flags, Flags::User); + entry.write_through = has_flag(flags, Flags::WriteThrough); + entry.cache_disabled = has_flag(flags, Flags::CacheDisable); + entry.no_execute = has_flag(flags, Flags::NoExecute); + entry.set_address(phys); + } + + Result map(u64 virt, u64 phys, int flags, UseHugePages use_huge_pages) { auto& l4 = l4_entry(virt); if (!l4.present) @@ -191,7 +202,7 @@ namespace MMU if (flags & Flags::ReadWrite) l3.read_write = true; if (flags & Flags::User) l3.user = true; - if (l3.larger_pages) return err(EFIXME); // FIXME: Replacing larger pages is not supported ATM + if (l3.larger_pages) return err(EEXIST); auto& l2 = l2_entry(l3, virt); if (!l2.present) @@ -204,17 +215,17 @@ namespace MMU if (flags & Flags::ReadWrite) l2.read_write = true; if (flags & Flags::User) l2.user = true; - if (l2.larger_pages) return err(EFIXME); // FIXME: Replacing larger pages is not supported ATM + if (l2.larger_pages) return err(EEXIST); + else if (use_huge_pages == UseHugePages::Yes) + { + l2.larger_pages = true; + set_page_table_entry_properties(l2, phys, flags); + return {}; + } auto& l1 = l1_entry(l2, virt); if (l1.present) return err(EEXIST); // Please explicitly unmap the page before mapping it again. - l1.present = true; - l1.read_write = has_flag(flags, Flags::ReadWrite); - l1.user = has_flag(flags, Flags::User); - l1.write_through = has_flag(flags, Flags::WriteThrough); - l1.cache_disabled = has_flag(flags, Flags::CacheDisable); - l1.no_execute = has_flag(flags, Flags::NoExecute); - l1.set_address(phys); + set_page_table_entry_properties(l1, phys, flags); return {}; } diff --git a/kernel/src/arch/x86_64/MMU.h b/kernel/src/arch/x86_64/MMU.h index 198485f0..d1f8c362 100644 --- a/kernel/src/arch/x86_64/MMU.h +++ b/kernel/src/arch/x86_64/MMU.h @@ -2,6 +2,7 @@ #include const usize ARCH_PAGE_SIZE = 4096; +const usize ARCH_HUGE_PAGE_SIZE = 2 * 1024 * 1024; // 2 MiB const u64 rindex = 0776; // recursive index const u64 sign = 0177777UL << 48; // sign extension diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 96818eb7..35e6b80a 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -202,7 +202,7 @@ namespace MemoryManager while (pages_mapped < count) { - TRY(MMU::map(virt, phys, flags)); + TRY(MMU::map(virt, phys, flags, MMU::UseHugePages::No)); virt += ARCH_PAGE_SIZE; phys += ARCH_PAGE_SIZE; pages_mapped++; @@ -225,7 +225,7 @@ namespace MemoryManager while (pages_mapped < count) { const u64 frame = TRY(alloc_frame()); - TRY(MMU::map(virt, frame, flags)); + TRY(MMU::map(virt, frame, flags, MMU::UseHugePages::No)); virt += ARCH_PAGE_SIZE; pages_mapped++; } @@ -250,7 +250,7 @@ namespace MemoryManager while (pages_mapped < count) { const u64 frame = TRY(alloc_frame()); - TRY(MMU::map(virt, frame, flags)); + TRY(MMU::map(virt, frame, flags, MMU::UseHugePages::No)); virt += ARCH_PAGE_SIZE; pages_mapped++; } @@ -275,7 +275,7 @@ namespace MemoryManager while (pages_mapped < count) { - TRY(MMU::map(virt, phys, flags)); + TRY(MMU::map(virt, phys, flags, MMU::UseHugePages::No)); virt += ARCH_PAGE_SIZE; phys += ARCH_PAGE_SIZE; pages_mapped++; -- 2.34.1 From ff01f49b419cb4a23f7bb5aef2e7f8dc28286c89 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 12:47:17 +0100 Subject: [PATCH 33/44] x86_64/MMU: Map the physical address space using huge pages --- kernel/src/arch/x86_64/MMU.cpp | 6 ++--- kernel/src/memory/MemoryManager.cpp | 36 +++++++++++++++++++++++++++++ kernel/src/memory/MemoryManager.h | 3 +++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index de239a22..7d037bef 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -278,9 +278,9 @@ namespace MMU const u64 physical_memory_size = highest_entry.address() + highest_entry.size(); - // FIXME: Do this using 2MiB huge pages. - MemoryManager::map_frames_at(physical_memory_base, 0, physical_memory_size / ARCH_PAGE_SIZE, - MMU::ReadWrite | MMU::NoExecute); + check(physical_memory_size % ARCH_HUGE_PAGE_SIZE == 0); + MemoryManager::map_huge_frames_at(physical_memory_base, 0, physical_memory_size / ARCH_HUGE_PAGE_SIZE, + MMU::ReadWrite | MMU::NoExecute); g_physical_mapping_base = physical_memory_base; diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 35e6b80a..bfa4e497 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -213,6 +213,29 @@ namespace MemoryManager return {}; } + Result map_huge_frames_at(u64 virt, u64 phys, usize count, int flags) + { + CHECK_PAGE_ALIGNED(virt); + CHECK_PAGE_ALIGNED(phys); + + usize pages_mapped = 0; + + // Let's clean up after ourselves if we fail. + auto guard = make_scope_guard([=, &pages_mapped] { unmap_weak_huge(virt, pages_mapped); }); + + while (pages_mapped < count) + { + TRY(MMU::map(virt, phys, flags, MMU::UseHugePages::Yes)); + virt += ARCH_HUGE_PAGE_SIZE; + phys += ARCH_HUGE_PAGE_SIZE; + pages_mapped++; + } + + guard.deactivate(); + + return {}; + } + Result alloc_at(u64 virt, usize count, int flags) { CHECK_PAGE_ALIGNED(virt); @@ -322,6 +345,19 @@ namespace MemoryManager return {}; } + Result unmap_weak_huge(u64 virt, usize count) + { + CHECK_PAGE_ALIGNED(virt); + + while (count--) + { + TRY(MMU::unmap(virt)); + virt += ARCH_HUGE_PAGE_SIZE; + } + + return {}; + } + Result unmap_weak_and_free_vm(u64 virt, usize count) { CHECK_PAGE_ALIGNED(virt); diff --git a/kernel/src/memory/MemoryManager.h b/kernel/src/memory/MemoryManager.h index 8f2b9bbc..3ceecffb 100644 --- a/kernel/src/memory/MemoryManager.h +++ b/kernel/src/memory/MemoryManager.h @@ -53,6 +53,7 @@ namespace MemoryManager } Result map_frames_at(u64 virt, u64 phys, usize count, int flags); + Result map_huge_frames_at(u64 virt, u64 phys, usize count, int flags); Result alloc_at(u64 virt, usize count, int flags); Result alloc_for_kernel(usize count, int flags); @@ -64,6 +65,8 @@ namespace MemoryManager Result unmap_weak(u64 virt, usize count); Result unmap_weak_and_free_vm(u64 virt, usize count); + Result unmap_weak_huge(u64 virt, usize count); + usize free(); usize used(); usize reserved(); -- 2.34.1 From 9af6a3f30fab0dc2fb8569d4720a6855f126181f Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 12:51:29 +0100 Subject: [PATCH 34/44] MemoryManager: Reuse the existing mapping of physical memory that MMU has --- kernel/src/arch/MMU.h | 2 ++ kernel/src/arch/x86_64/MMU.cpp | 5 +++++ kernel/src/memory/MemoryManager.cpp | 14 ++------------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/kernel/src/arch/MMU.h b/kernel/src/arch/MMU.h index addd5863..8a46e6fa 100644 --- a/kernel/src/arch/MMU.h +++ b/kernel/src/arch/MMU.h @@ -27,6 +27,8 @@ namespace MMU Yes = 1 }; + u64 translate_physical_address(u64 phys); + Result map(u64 virt, u64 phys, int flags, UseHugePages use_huge_pages); Result unmap(u64 virt); Result get_physical(u64 virt); diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index 7d037bef..760508c4 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -47,6 +47,11 @@ namespace MMU return (T)(g_physical_mapping_base + (u64)phys); } + u64 translate_physical_address(u64 phys) + { + return g_physical_mapping_base + phys; + } + void switch_page_directory(PageDirectory* dir) { asm volatile("mov %0, %%cr3" : : "r"(dir)); diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index bfa4e497..3160f808 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -103,20 +103,10 @@ namespace MemoryManager KernelVM::init(); MMU::setup_initial_page_directory(); - // NOTE: We force these operations to succeed, because if we can't map the frame bitmap to virtual memory - // there's no point in continuing. - auto bitmap_pages = g_frame_bitmap.lock()->size_in_bytes() / ARCH_PAGE_SIZE; - - auto virtual_bitmap_base = - KernelVM::alloc_several_pages(bitmap_pages) - .expect_value("Unable to allocate virtual memory for the physical frame bitmap, cannot continue"); - - u64 phys = (u64)g_frame_bitmap.lock()->location(); - map_frames_at(virtual_bitmap_base, phys, bitmap_pages, MMU::ReadWrite | MMU::NoExecute) - .expect_value("Unable to map the physical frame bitmap to virtual memory, cannot continue"); - auto frame_bitmap = g_frame_bitmap.lock(); + u64 phys = (u64)frame_bitmap->location(); + auto virtual_bitmap_base = MMU::translate_physical_address(phys); frame_bitmap->initialize((void*)virtual_bitmap_base, frame_bitmap->size_in_bytes()); } -- 2.34.1 From 2038ee1929e0c659b404d0d5867c0bd22507f502 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 12:55:15 +0100 Subject: [PATCH 35/44] x86_64/MMU: Do not allocate level 1 page tables for huge page entries This would leak memory, since we would never end up using them. --- kernel/src/arch/x86_64/MMU.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index 760508c4..cc91b6c3 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -212,11 +212,16 @@ namespace MMU auto& l2 = l2_entry(l3, virt); if (!l2.present) { - const u64 addr = TRY(MemoryManager::alloc_frame()); l2.present = true; - l2.set_address(addr); - memset(&page_table(l2), 0, ARCH_PAGE_SIZE); + + if (use_huge_pages == UseHugePages::No) + { + const u64 addr = TRY(MemoryManager::alloc_frame()); + l2.set_address(addr); + memset(&page_table(l2), 0, ARCH_PAGE_SIZE); + } } + if (flags & Flags::ReadWrite) l2.read_write = true; if (flags & Flags::User) l2.user = true; -- 2.34.1 From a0252e42a433330cd7dee9667fc3fdf3762790b7 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 13:07:52 +0100 Subject: [PATCH 36/44] x86_64: Remove recursive mapping related things from MMU.h --- kernel/src/arch/x86_64/MMU.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/src/arch/x86_64/MMU.h b/kernel/src/arch/x86_64/MMU.h index d1f8c362..294956b6 100644 --- a/kernel/src/arch/x86_64/MMU.h +++ b/kernel/src/arch/x86_64/MMU.h @@ -4,9 +4,6 @@ const usize ARCH_PAGE_SIZE = 4096; const usize ARCH_HUGE_PAGE_SIZE = 2 * 1024 * 1024; // 2 MiB -const u64 rindex = 0776; // recursive index -const u64 sign = 0177777UL << 48; // sign extension - struct [[gnu::packed]] PageTableEntry { union { -- 2.34.1 From 3654cc5bee06a1b0a28928b709475cad6a5ab314 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 13:24:58 +0100 Subject: [PATCH 37/44] MemoryManager: Initialize KernelVM at the end of init() KernelVM is not needed for MMU's init process anymore. --- kernel/src/memory/MemoryManager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 3160f808..fb7f57ee 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -100,7 +100,7 @@ namespace MemoryManager void init() { init_physical_frame_allocator(); - KernelVM::init(); + MMU::setup_initial_page_directory(); auto frame_bitmap = g_frame_bitmap.lock(); @@ -108,6 +108,8 @@ namespace MemoryManager auto virtual_bitmap_base = MMU::translate_physical_address(phys); frame_bitmap->initialize((void*)virtual_bitmap_base, frame_bitmap->size_in_bytes()); + + KernelVM::init(); } void do_lock_frame(u64 index, Bitmap& bitmap) -- 2.34.1 From 7f1884213accb072f78205d2d1614c7e586c4497 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 13:27:21 +0100 Subject: [PATCH 38/44] InitRD: Use MMU::translate_physical_address instead of allocating VM This one is a perfect candidate, since we're just mapping a fixed continuous range of physical memory to virtual memory. --- kernel/src/InitRD.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/kernel/src/InitRD.cpp b/kernel/src/InitRD.cpp index 1fc592df..a661b817 100644 --- a/kernel/src/InitRD.cpp +++ b/kernel/src/InitRD.cpp @@ -1,18 +1,13 @@ #include "InitRD.h" #include "arch/MMU.h" #include "boot/bootboot.h" -#include "memory/MemoryManager.h" -#include TarStream g_initrd; extern const BOOTBOOT bootboot; void InitRD::initialize() { - u64 virtual_initrd_address = - MemoryManager::get_kernel_mapping_for_frames( - bootboot.initrd_ptr, get_blocks_from_size(bootboot.initrd_size, ARCH_PAGE_SIZE), MMU::NoExecute) - .expect_value("Unable to map the initial ramdisk into virtual memory"); + u64 virtual_initrd_address = MMU::translate_physical_address(bootboot.initrd_ptr); g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size); } -- 2.34.1 From ec146caeead26e33169afd5368e88b2b898c9a9f Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 15:02:55 +0100 Subject: [PATCH 39/44] Vector: Fix try_append (hopefully) Still doesn't work with OwnedStringViews inside of structs. --- luna/include/luna/Vector.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/luna/include/luna/Vector.h b/luna/include/luna/Vector.h index 46393feb..c74f632e 100644 --- a/luna/include/luna/Vector.h +++ b/luna/include/luna/Vector.h @@ -78,7 +78,7 @@ template class Vector resize(capacity).release_value(); } - Result try_append(T item) + Result try_append(T&& item) { if (m_capacity == m_size) TRY(resize(m_capacity + 8)); @@ -89,6 +89,11 @@ template class Vector return {}; } + Result try_append(const T& item) + { + return try_append(T(item)); + } + Option try_pop() { if (m_size == 0) return {}; -- 2.34.1 From 19b72fe779ede80f3fe32bbdbd86bb09cb225477 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 15:03:22 +0100 Subject: [PATCH 40/44] luna: Add strlcpy() --- luna/include/luna/CString.h | 2 ++ luna/src/CString.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/luna/include/luna/CString.h b/luna/include/luna/CString.h index db7991d9..3765c45a 100644 --- a/luna/include/luna/CString.h +++ b/luna/include/luna/CString.h @@ -22,6 +22,8 @@ extern "C" // FIXME: Replace this invented function with strlcpy(). void nullcpy(char* dest, const char* src, usize len); + usize strlcpy(char* dest, const char* src, usize len); + [[deprecated]] char* strcpy(char* dst, const char* src); [[deprecated]] char* strcat(char* dst, const char* src); diff --git a/luna/src/CString.cpp b/luna/src/CString.cpp index e1ba020e..e9a9fefc 100644 --- a/luna/src/CString.cpp +++ b/luna/src/CString.cpp @@ -125,4 +125,15 @@ extern "C" if (*str) return const_cast(str); return NULL; } + + usize strlcpy(char* dest, const char* src, usize len) + { + usize src_len = strlen(src); + usize copy_len = src_len; + if (len == 0) return src_len; + if (src_len >= (len - 1)) copy_len = len - 1; + memcpy(dest, src, copy_len); + dest[copy_len] = 0; + return src_len; + } } -- 2.34.1 From 55b430a4fd116058204b54153b8d5f5b560a574b Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 15:04:29 +0100 Subject: [PATCH 41/44] TmpFS: Use a fixed char array in DirInode's Entry instead of OwnedStringView --- kernel/src/fs/VFS.h | 2 +- kernel/src/fs/tmpfs/FileSystem.cpp | 12 ++++++++---- kernel/src/fs/tmpfs/FileSystem.h | 4 ++-- kernel/src/main.cpp | 4 ++++ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 9c89f273..70e2fb12 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -57,7 +57,7 @@ namespace VFS virtual Result> create_file_inode() = 0; - virtual Result> create_dir_inode() = 0; + virtual Result> create_dir_inode(SharedPtr parent) = 0; virtual ~FileSystem() = default; }; diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index 4606743e..76e095bd 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -1,5 +1,6 @@ #include "fs/tmpfs/FileSystem.h" #include +#include #include namespace TmpFS @@ -7,7 +8,7 @@ namespace TmpFS Result> FileSystem::create() { SharedPtr fs = TRY(adopt_shared(new (std::nothrow) FileSystem())); - SharedPtr root = TRY(fs->create_dir_inode()); + SharedPtr root = TRY(fs->create_dir_inode({})); fs->set_root(root); return (SharedPtr)fs; } @@ -22,10 +23,11 @@ namespace TmpFS return (SharedPtr)inode; } - Result> FileSystem::create_dir_inode() + Result> FileSystem::create_dir_inode(SharedPtr parent) { SharedPtr inode = TRY(make_shared()); TRY(inode->add_entry(inode, ".")); + TRY(inode->add_entry(parent ? parent : (SharedPtr)inode, "..")); inode->set_fs(*this, {}); inode->set_inode_number(m_next_inode_number, {}); @@ -43,7 +45,7 @@ namespace TmpFS { for (const auto& entry : m_entries) { - if (!strcmp(name, entry.name.chars())) return entry.inode; + if (!strcmp(name, entry.name)) return entry.inode; } return err(ENOENT); @@ -51,7 +53,9 @@ namespace TmpFS Result DirInode::add_entry(SharedPtr inode, const char* name) { - Entry entry = { inode, TRY(OwnedStringView::from_string_literal(name)) }; + Entry entry; + entry.inode = inode; + strlcpy(entry.name, name, sizeof(entry.name)); TRY(m_entries.try_append(move(entry))); diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 044a26a5..63cf7abe 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -16,7 +16,7 @@ namespace TmpFS } Result> create_file_inode() override; - Result> create_dir_inode() override; + Result> create_dir_inode(SharedPtr parent) override; static Result> create(); @@ -110,7 +110,7 @@ namespace TmpFS struct Entry { SharedPtr inode; - OwnedStringView name; + char name[128]; }; Vector m_entries; diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 3427cf6e..09964795 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -61,7 +61,11 @@ Result init() VFS::Inode& root_inode = VFS::root_inode(); kinfoln("root inode number: %zu", root_inode.inode_number()); + kinfoln("root inode's '.' entry inode number: %zu", TRY(root_inode.find("."))->inode_number()); + kinfoln("root inode's '..' entry inode number: %zu", TRY(root_inode.find(".."))->inode_number()); + TRY(root_inode.create_file("usr")); + kinfoln("root inode's 'usr' entry inode number: %zu", TRY(root_inode.find("usr"))->inode_number()); TarStream::Entry entry; -- 2.34.1 From 76f9bd8112563a7f35d843fc5041b4b459015a3e Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 15:13:23 +0100 Subject: [PATCH 42/44] luna: Add StaticString, an OOP char[] --- luna/include/luna/StaticString.h | 52 ++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 luna/include/luna/StaticString.h diff --git a/luna/include/luna/StaticString.h b/luna/include/luna/StaticString.h new file mode 100644 index 00000000..7bdf77be --- /dev/null +++ b/luna/include/luna/StaticString.h @@ -0,0 +1,52 @@ +#pragma once +#include +#include + +template class StaticString +{ + public: + StaticString() = default; + StaticString(const char* string) + { + adopt(string); + } + + void adopt(const char* string) + { + usize length = strlcpy(m_buffer, string, sizeof(m_buffer)); + if (length > Size) { m_length = Size; } + else + m_length = length; + } + + StaticString& operator=(const char* string) + { + adopt(string); + return *this; + } + + template StaticString& operator=(const StaticString& string) + { + if constexpr (OSize == Size) + { + if (this == &string) return *this; + } + + adopt(string.chars()); + return *this; + } + + const char* chars() const + { + return m_buffer; + } + + usize length() const + { + return m_length; + } + + private: + char m_buffer[Size + 1]; + usize m_length { 0 }; +}; -- 2.34.1 From 32dc5473a577dcfd5d0cbdf86f5e7664d5d60274 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 15:14:07 +0100 Subject: [PATCH 43/44] TmpFS: Use StaticString<128> instead of char[128] --- kernel/src/fs/tmpfs/FileSystem.cpp | 6 ++---- kernel/src/fs/tmpfs/FileSystem.h | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index 76e095bd..772433cc 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -45,7 +45,7 @@ namespace TmpFS { for (const auto& entry : m_entries) { - if (!strcmp(name, entry.name)) return entry.inode; + if (!strcmp(name, entry.name.chars())) return entry.inode; } return err(ENOENT); @@ -53,9 +53,7 @@ namespace TmpFS Result DirInode::add_entry(SharedPtr inode, const char* name) { - Entry entry; - entry.inode = inode; - strlcpy(entry.name, name, sizeof(entry.name)); + Entry entry { inode, name }; TRY(m_entries.try_append(move(entry))); diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index 63cf7abe..6e1e5f39 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -2,7 +2,7 @@ #include "fs/VFS.h" #include #include -#include +#include #include namespace TmpFS @@ -110,7 +110,7 @@ namespace TmpFS struct Entry { SharedPtr inode; - char name[128]; + StaticString<128> name; }; Vector m_entries; -- 2.34.1 From eebbbf0b164ebeaf6e4cf18605dbd92f55036a1d Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 27 Feb 2023 15:19:18 +0100 Subject: [PATCH 44/44] luna -> libluna --- CMakeLists.txt | 2 +- {luna => libluna}/CMakeLists.txt | 0 {luna => libluna}/include/luna/Alignment.h | 0 {luna => libluna}/include/luna/Alloc.h | 0 {luna => libluna}/include/luna/Atomic.h | 0 {luna => libluna}/include/luna/Attributes.h | 0 {luna => libluna}/include/luna/Badge.h | 0 {luna => libluna}/include/luna/Bitmap.h | 0 {luna => libluna}/include/luna/CString.h | 0 {luna => libluna}/include/luna/CType.h | 0 {luna => libluna}/include/luna/Check.h | 0 {luna => libluna}/include/luna/CircularQueue.h | 0 {luna => libluna}/include/luna/DebugLog.h | 0 {luna => libluna}/include/luna/Format.h | 0 {luna => libluna}/include/luna/Heap.h | 0 {luna => libluna}/include/luna/Ignore.h | 0 {luna => libluna}/include/luna/LinkedList.h | 0 {luna => libluna}/include/luna/Move.h | 0 {luna => libluna}/include/luna/NumberParsing.h | 0 {luna => libluna}/include/luna/Option.h | 0 {luna => libluna}/include/luna/OwnedPtr.h | 0 {luna => libluna}/include/luna/OwnedStringView.h | 0 {luna => libluna}/include/luna/PlacementNew.h | 0 {luna => libluna}/include/luna/Result.h | 0 {luna => libluna}/include/luna/SafeArithmetic.h | 0 {luna => libluna}/include/luna/ScopeGuard.h | 0 {luna => libluna}/include/luna/SharedPtr.h | 0 {luna => libluna}/include/luna/SourceLocation.h | 0 {luna => libluna}/include/luna/Spinlock.h | 0 {luna => libluna}/include/luna/Stack.h | 0 {luna => libluna}/include/luna/StaticString.h | 0 {luna => libluna}/include/luna/Syscall.h | 0 {luna => libluna}/include/luna/SystemError.h | 0 {luna => libluna}/include/luna/TarStream.h | 0 {luna => libluna}/include/luna/TypeTraits.h | 0 {luna => libluna}/include/luna/Types.h | 0 {luna => libluna}/include/luna/UBSAN.h | 0 {luna => libluna}/include/luna/Units.h | 0 {luna => libluna}/include/luna/Utf8.h | 0 {luna => libluna}/include/luna/Vector.h | 0 {luna => libluna}/src/Bitmap.cpp | 0 {luna => libluna}/src/CString.cpp | 0 {luna => libluna}/src/Check.cpp | 0 {luna => libluna}/src/DebugLog.cpp | 0 {luna => libluna}/src/Format.cpp | 0 {luna => libluna}/src/Heap.cpp | 0 {luna => libluna}/src/NumberParsing.cpp | 0 {luna => libluna}/src/OwnedStringView.cpp | 0 {luna => libluna}/src/Spinlock.cpp | 0 {luna => libluna}/src/Stack.cpp | 0 {luna => libluna}/src/SystemError.cpp | 0 {luna => libluna}/src/TarStream.cpp | 0 {luna => libluna}/src/UBSAN.cpp | 0 {luna => libluna}/src/Units.cpp | 0 {luna => libluna}/src/Utf8.cpp | 0 tools/install-headers.sh | 2 +- 56 files changed, 2 insertions(+), 2 deletions(-) rename {luna => libluna}/CMakeLists.txt (100%) rename {luna => libluna}/include/luna/Alignment.h (100%) rename {luna => libluna}/include/luna/Alloc.h (100%) rename {luna => libluna}/include/luna/Atomic.h (100%) rename {luna => libluna}/include/luna/Attributes.h (100%) rename {luna => libluna}/include/luna/Badge.h (100%) rename {luna => libluna}/include/luna/Bitmap.h (100%) rename {luna => libluna}/include/luna/CString.h (100%) rename {luna => libluna}/include/luna/CType.h (100%) rename {luna => libluna}/include/luna/Check.h (100%) rename {luna => libluna}/include/luna/CircularQueue.h (100%) rename {luna => libluna}/include/luna/DebugLog.h (100%) rename {luna => libluna}/include/luna/Format.h (100%) rename {luna => libluna}/include/luna/Heap.h (100%) rename {luna => libluna}/include/luna/Ignore.h (100%) rename {luna => libluna}/include/luna/LinkedList.h (100%) rename {luna => libluna}/include/luna/Move.h (100%) rename {luna => libluna}/include/luna/NumberParsing.h (100%) rename {luna => libluna}/include/luna/Option.h (100%) rename {luna => libluna}/include/luna/OwnedPtr.h (100%) rename {luna => libluna}/include/luna/OwnedStringView.h (100%) rename {luna => libluna}/include/luna/PlacementNew.h (100%) rename {luna => libluna}/include/luna/Result.h (100%) rename {luna => libluna}/include/luna/SafeArithmetic.h (100%) rename {luna => libluna}/include/luna/ScopeGuard.h (100%) rename {luna => libluna}/include/luna/SharedPtr.h (100%) rename {luna => libluna}/include/luna/SourceLocation.h (100%) rename {luna => libluna}/include/luna/Spinlock.h (100%) rename {luna => libluna}/include/luna/Stack.h (100%) rename {luna => libluna}/include/luna/StaticString.h (100%) rename {luna => libluna}/include/luna/Syscall.h (100%) rename {luna => libluna}/include/luna/SystemError.h (100%) rename {luna => libluna}/include/luna/TarStream.h (100%) rename {luna => libluna}/include/luna/TypeTraits.h (100%) rename {luna => libluna}/include/luna/Types.h (100%) rename {luna => libluna}/include/luna/UBSAN.h (100%) rename {luna => libluna}/include/luna/Units.h (100%) rename {luna => libluna}/include/luna/Utf8.h (100%) rename {luna => libluna}/include/luna/Vector.h (100%) rename {luna => libluna}/src/Bitmap.cpp (100%) rename {luna => libluna}/src/CString.cpp (100%) rename {luna => libluna}/src/Check.cpp (100%) rename {luna => libluna}/src/DebugLog.cpp (100%) rename {luna => libluna}/src/Format.cpp (100%) rename {luna => libluna}/src/Heap.cpp (100%) rename {luna => libluna}/src/NumberParsing.cpp (100%) rename {luna => libluna}/src/OwnedStringView.cpp (100%) rename {luna => libluna}/src/Spinlock.cpp (100%) rename {luna => libluna}/src/Stack.cpp (100%) rename {luna => libluna}/src/SystemError.cpp (100%) rename {luna => libluna}/src/TarStream.cpp (100%) rename {luna => libluna}/src/UBSAN.cpp (100%) rename {luna => libluna}/src/Units.cpp (100%) rename {luna => libluna}/src/Utf8.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c0c1f2f..04dd5fef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ set(CMAKE_FIND_ROOT_PATH ${LUNA_ROOT}/toolchain/${LUNA_ARCH}-luna) message(STATUS "Configuring Luna for ${LUNA_ARCH}") -add_subdirectory(luna) +add_subdirectory(libluna) add_subdirectory(libc) add_subdirectory(kernel) add_subdirectory(apps) diff --git a/luna/CMakeLists.txt b/libluna/CMakeLists.txt similarity index 100% rename from luna/CMakeLists.txt rename to libluna/CMakeLists.txt diff --git a/luna/include/luna/Alignment.h b/libluna/include/luna/Alignment.h similarity index 100% rename from luna/include/luna/Alignment.h rename to libluna/include/luna/Alignment.h diff --git a/luna/include/luna/Alloc.h b/libluna/include/luna/Alloc.h similarity index 100% rename from luna/include/luna/Alloc.h rename to libluna/include/luna/Alloc.h diff --git a/luna/include/luna/Atomic.h b/libluna/include/luna/Atomic.h similarity index 100% rename from luna/include/luna/Atomic.h rename to libluna/include/luna/Atomic.h diff --git a/luna/include/luna/Attributes.h b/libluna/include/luna/Attributes.h similarity index 100% rename from luna/include/luna/Attributes.h rename to libluna/include/luna/Attributes.h diff --git a/luna/include/luna/Badge.h b/libluna/include/luna/Badge.h similarity index 100% rename from luna/include/luna/Badge.h rename to libluna/include/luna/Badge.h diff --git a/luna/include/luna/Bitmap.h b/libluna/include/luna/Bitmap.h similarity index 100% rename from luna/include/luna/Bitmap.h rename to libluna/include/luna/Bitmap.h diff --git a/luna/include/luna/CString.h b/libluna/include/luna/CString.h similarity index 100% rename from luna/include/luna/CString.h rename to libluna/include/luna/CString.h diff --git a/luna/include/luna/CType.h b/libluna/include/luna/CType.h similarity index 100% rename from luna/include/luna/CType.h rename to libluna/include/luna/CType.h diff --git a/luna/include/luna/Check.h b/libluna/include/luna/Check.h similarity index 100% rename from luna/include/luna/Check.h rename to libluna/include/luna/Check.h diff --git a/luna/include/luna/CircularQueue.h b/libluna/include/luna/CircularQueue.h similarity index 100% rename from luna/include/luna/CircularQueue.h rename to libluna/include/luna/CircularQueue.h diff --git a/luna/include/luna/DebugLog.h b/libluna/include/luna/DebugLog.h similarity index 100% rename from luna/include/luna/DebugLog.h rename to libluna/include/luna/DebugLog.h diff --git a/luna/include/luna/Format.h b/libluna/include/luna/Format.h similarity index 100% rename from luna/include/luna/Format.h rename to libluna/include/luna/Format.h diff --git a/luna/include/luna/Heap.h b/libluna/include/luna/Heap.h similarity index 100% rename from luna/include/luna/Heap.h rename to libluna/include/luna/Heap.h diff --git a/luna/include/luna/Ignore.h b/libluna/include/luna/Ignore.h similarity index 100% rename from luna/include/luna/Ignore.h rename to libluna/include/luna/Ignore.h diff --git a/luna/include/luna/LinkedList.h b/libluna/include/luna/LinkedList.h similarity index 100% rename from luna/include/luna/LinkedList.h rename to libluna/include/luna/LinkedList.h diff --git a/luna/include/luna/Move.h b/libluna/include/luna/Move.h similarity index 100% rename from luna/include/luna/Move.h rename to libluna/include/luna/Move.h diff --git a/luna/include/luna/NumberParsing.h b/libluna/include/luna/NumberParsing.h similarity index 100% rename from luna/include/luna/NumberParsing.h rename to libluna/include/luna/NumberParsing.h diff --git a/luna/include/luna/Option.h b/libluna/include/luna/Option.h similarity index 100% rename from luna/include/luna/Option.h rename to libluna/include/luna/Option.h diff --git a/luna/include/luna/OwnedPtr.h b/libluna/include/luna/OwnedPtr.h similarity index 100% rename from luna/include/luna/OwnedPtr.h rename to libluna/include/luna/OwnedPtr.h diff --git a/luna/include/luna/OwnedStringView.h b/libluna/include/luna/OwnedStringView.h similarity index 100% rename from luna/include/luna/OwnedStringView.h rename to libluna/include/luna/OwnedStringView.h diff --git a/luna/include/luna/PlacementNew.h b/libluna/include/luna/PlacementNew.h similarity index 100% rename from luna/include/luna/PlacementNew.h rename to libluna/include/luna/PlacementNew.h diff --git a/luna/include/luna/Result.h b/libluna/include/luna/Result.h similarity index 100% rename from luna/include/luna/Result.h rename to libluna/include/luna/Result.h diff --git a/luna/include/luna/SafeArithmetic.h b/libluna/include/luna/SafeArithmetic.h similarity index 100% rename from luna/include/luna/SafeArithmetic.h rename to libluna/include/luna/SafeArithmetic.h diff --git a/luna/include/luna/ScopeGuard.h b/libluna/include/luna/ScopeGuard.h similarity index 100% rename from luna/include/luna/ScopeGuard.h rename to libluna/include/luna/ScopeGuard.h diff --git a/luna/include/luna/SharedPtr.h b/libluna/include/luna/SharedPtr.h similarity index 100% rename from luna/include/luna/SharedPtr.h rename to libluna/include/luna/SharedPtr.h diff --git a/luna/include/luna/SourceLocation.h b/libluna/include/luna/SourceLocation.h similarity index 100% rename from luna/include/luna/SourceLocation.h rename to libluna/include/luna/SourceLocation.h diff --git a/luna/include/luna/Spinlock.h b/libluna/include/luna/Spinlock.h similarity index 100% rename from luna/include/luna/Spinlock.h rename to libluna/include/luna/Spinlock.h diff --git a/luna/include/luna/Stack.h b/libluna/include/luna/Stack.h similarity index 100% rename from luna/include/luna/Stack.h rename to libluna/include/luna/Stack.h diff --git a/luna/include/luna/StaticString.h b/libluna/include/luna/StaticString.h similarity index 100% rename from luna/include/luna/StaticString.h rename to libluna/include/luna/StaticString.h diff --git a/luna/include/luna/Syscall.h b/libluna/include/luna/Syscall.h similarity index 100% rename from luna/include/luna/Syscall.h rename to libluna/include/luna/Syscall.h diff --git a/luna/include/luna/SystemError.h b/libluna/include/luna/SystemError.h similarity index 100% rename from luna/include/luna/SystemError.h rename to libluna/include/luna/SystemError.h diff --git a/luna/include/luna/TarStream.h b/libluna/include/luna/TarStream.h similarity index 100% rename from luna/include/luna/TarStream.h rename to libluna/include/luna/TarStream.h diff --git a/luna/include/luna/TypeTraits.h b/libluna/include/luna/TypeTraits.h similarity index 100% rename from luna/include/luna/TypeTraits.h rename to libluna/include/luna/TypeTraits.h diff --git a/luna/include/luna/Types.h b/libluna/include/luna/Types.h similarity index 100% rename from luna/include/luna/Types.h rename to libluna/include/luna/Types.h diff --git a/luna/include/luna/UBSAN.h b/libluna/include/luna/UBSAN.h similarity index 100% rename from luna/include/luna/UBSAN.h rename to libluna/include/luna/UBSAN.h diff --git a/luna/include/luna/Units.h b/libluna/include/luna/Units.h similarity index 100% rename from luna/include/luna/Units.h rename to libluna/include/luna/Units.h diff --git a/luna/include/luna/Utf8.h b/libluna/include/luna/Utf8.h similarity index 100% rename from luna/include/luna/Utf8.h rename to libluna/include/luna/Utf8.h diff --git a/luna/include/luna/Vector.h b/libluna/include/luna/Vector.h similarity index 100% rename from luna/include/luna/Vector.h rename to libluna/include/luna/Vector.h diff --git a/luna/src/Bitmap.cpp b/libluna/src/Bitmap.cpp similarity index 100% rename from luna/src/Bitmap.cpp rename to libluna/src/Bitmap.cpp diff --git a/luna/src/CString.cpp b/libluna/src/CString.cpp similarity index 100% rename from luna/src/CString.cpp rename to libluna/src/CString.cpp diff --git a/luna/src/Check.cpp b/libluna/src/Check.cpp similarity index 100% rename from luna/src/Check.cpp rename to libluna/src/Check.cpp diff --git a/luna/src/DebugLog.cpp b/libluna/src/DebugLog.cpp similarity index 100% rename from luna/src/DebugLog.cpp rename to libluna/src/DebugLog.cpp diff --git a/luna/src/Format.cpp b/libluna/src/Format.cpp similarity index 100% rename from luna/src/Format.cpp rename to libluna/src/Format.cpp diff --git a/luna/src/Heap.cpp b/libluna/src/Heap.cpp similarity index 100% rename from luna/src/Heap.cpp rename to libluna/src/Heap.cpp diff --git a/luna/src/NumberParsing.cpp b/libluna/src/NumberParsing.cpp similarity index 100% rename from luna/src/NumberParsing.cpp rename to libluna/src/NumberParsing.cpp diff --git a/luna/src/OwnedStringView.cpp b/libluna/src/OwnedStringView.cpp similarity index 100% rename from luna/src/OwnedStringView.cpp rename to libluna/src/OwnedStringView.cpp diff --git a/luna/src/Spinlock.cpp b/libluna/src/Spinlock.cpp similarity index 100% rename from luna/src/Spinlock.cpp rename to libluna/src/Spinlock.cpp diff --git a/luna/src/Stack.cpp b/libluna/src/Stack.cpp similarity index 100% rename from luna/src/Stack.cpp rename to libluna/src/Stack.cpp diff --git a/luna/src/SystemError.cpp b/libluna/src/SystemError.cpp similarity index 100% rename from luna/src/SystemError.cpp rename to libluna/src/SystemError.cpp diff --git a/luna/src/TarStream.cpp b/libluna/src/TarStream.cpp similarity index 100% rename from luna/src/TarStream.cpp rename to libluna/src/TarStream.cpp diff --git a/luna/src/UBSAN.cpp b/libluna/src/UBSAN.cpp similarity index 100% rename from luna/src/UBSAN.cpp rename to libluna/src/UBSAN.cpp diff --git a/luna/src/Units.cpp b/libluna/src/Units.cpp similarity index 100% rename from luna/src/Units.cpp rename to libluna/src/Units.cpp diff --git a/luna/src/Utf8.cpp b/libluna/src/Utf8.cpp similarity index 100% rename from luna/src/Utf8.cpp rename to libluna/src/Utf8.cpp diff --git a/tools/install-headers.sh b/tools/install-headers.sh index 324ce7ab..71b3b07f 100755 --- a/tools/install-headers.sh +++ b/tools/install-headers.sh @@ -10,4 +10,4 @@ mkdir -p $LUNA_BASE/usr/include mkdir -p $LUNA_BASE/usr/include/luna cp --preserve=timestamps -RT libc/include/ $LUNA_BASE/usr/include -cp --preserve=timestamps -RT luna/include/luna/ $LUNA_BASE/usr/include/luna +cp --preserve=timestamps -RT libluna/include/luna/ $LUNA_BASE/usr/include/luna -- 2.34.1