Переглянути джерело

Kernel: Use a RangeAllocator for kernel-only virtual space allocation too.

Andreas Kling 6 роки тому
батько
коміт
4a6fcfbacf

+ 5 - 7
Kernel/VM/MemoryManager.cpp

@@ -20,6 +20,7 @@ MemoryManager& MM
 }
 
 MemoryManager::MemoryManager()
+    : m_range_allocator(LinearAddress(0xc0000000), 0x3f000000)
 {
     // FIXME: This is not the best way to do memory map detection.
     //        Rewrite to use BIOS int 15,e820 once we have VM86 support.
@@ -400,14 +401,11 @@ RetainPtr<Region> MemoryManager::allocate_kernel_region(size_t size, String&& na
 {
     InterruptDisabler disabler;
 
-    // FIXME: We need a linear address space allocator.
-    static dword next_laddr = 0xd0000000;
     ASSERT(!(size % PAGE_SIZE));
-    LinearAddress laddr(next_laddr);
-    next_laddr += size + 16384;
-
-    auto region = adopt(*new Region(laddr, size, move(name), true, true, false));
-    MM.map_region_at_address(*m_kernel_page_directory, *region, laddr, false);
+    auto range = m_range_allocator.allocate_anywhere(size);
+    ASSERT(range.is_valid());
+    auto region = adopt(*new Region(range.base(), range.size(), move(name), true, true, false));
+    MM.map_region_at_address(*m_kernel_page_directory, *region, range.base(), false);
     // FIXME: It would be cool if these could zero-fill on demand instead.
     region->commit();
     return region;

+ 3 - 0
Kernel/VM/MemoryManager.h

@@ -13,6 +13,7 @@
 #include <AK/Weakable.h>
 #include <Kernel/LinearAddress.h>
 #include <Kernel/VM/PhysicalPage.h>
+#include <Kernel/VM/RangeAllocator.h>
 #include <Kernel/VM/Region.h>
 #include <Kernel/VM/VMObject.h>
 #include <Kernel/FileSystem/InodeIdentifier.h>
@@ -216,6 +217,8 @@ private:
     HashTable<Region*> m_user_regions;
     HashTable<Region*> m_kernel_regions;
 
+    RangeAllocator m_range_allocator;
+
     size_t m_ram_size { 0 };
     bool m_quickmap_in_use { false };
 };

+ 6 - 1
Kernel/VM/RangeAllocator.cpp

@@ -2,9 +2,12 @@
 #include <Kernel/kstdio.h>
 #include <AK/QuickSort.h>
 
+//#define VRA_DEBUG
+
 RangeAllocator::RangeAllocator(LinearAddress base, size_t size)
 {
     m_available_ranges.append({ base, size });
+    dump();
 }
 
 RangeAllocator::~RangeAllocator()
@@ -29,7 +32,9 @@ Vector<Range, 2> Range::carve(const Range& taken)
     if (taken.end() < end())
         parts.append({ taken.end(), end().get() - taken.end().get() });
 #ifdef VRA_DEBUG
-    dbgprintf("VRA: carve: remaining parts:\n");
+    dbgprintf("VRA: carve: take %x-%x from %x-%x\n",
+        taken.base().get(), taken.end().get() - 1,
+        base().get(), end().get() - 1);
     for (int i = 0; i < parts.size(); ++i)
         dbgprintf("        %x-%x\n", parts[i].base().get(), parts[i].end().get() - 1);
 #endif

+ 1 - 1
Kernel/VM/RangeAllocator.h

@@ -15,7 +15,7 @@ public:
 
     LinearAddress base() const { return m_base; }
     size_t size() const { return m_size; }
-    bool is_valid() const { return m_base.is_null(); }
+    bool is_valid() const { return !m_base.is_null(); }
 
     LinearAddress end() const { return m_base.offset(m_size); }