diff options
author | Jean-Baptiste Boric <jblbeurope@gmail.com> | 2021-01-19 19:13:03 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-22 22:17:39 +0100 |
commit | ec056f3bd1a20a52b4d47815a24704c09abb92c5 (patch) | |
tree | 64a8c4421500a2ffe86060a1e56cdb10effb9dd3 /Kernel/VM | |
parent | 3cbe8054864a3496dc5d097a1902b3406614113f (diff) | |
download | serenity-ec056f3bd1a20a52b4d47815a24704c09abb92c5.zip |
Kernel: Parse boot modules from Multiboot specification
Diffstat (limited to 'Kernel/VM')
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 45 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.h | 24 |
2 files changed, 55 insertions, 14 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index a08c255fb6..6f69959a07 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -64,6 +64,11 @@ namespace Kernel { static MemoryManager* s_the; RecursiveSpinLock s_mm_lock; +const LogStream& operator<<(const LogStream& stream, const UsedMemoryRange& value) +{ + return stream << UserMemoryRangeTypeNames[static_cast<int>(value.type)] << " range @ " << value.start << " - " << value.end; +} + MemoryManager& MM { return *s_the; @@ -122,25 +127,37 @@ void MemoryManager::parse_memory_map() { RefPtr<PhysicalRegion> region; - // We need to make sure we exclude the kmalloc range as well as the kernel image. - // The kmalloc range directly follows the kernel image - const PhysicalAddress used_range_start(virtual_to_low_physical(FlatPtr(&start_of_kernel_image))); - const PhysicalAddress used_range_end(virtual_to_low_physical(FlatPtr(&end_of_kernel_image))); - klog() << "MM: kernel range: " << used_range_start << " - " << used_range_end; + // Register used memory regions that we know of. + m_used_memory_ranges.ensure_capacity(4); + m_used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::LowMemory, PhysicalAddress(0x00000000), PhysicalAddress(1 * MiB) }); + m_used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::Kernel, PhysicalAddress(virtual_to_low_physical(FlatPtr(&start_of_kernel_image))), PhysicalAddress(PAGE_ROUND_UP(virtual_to_low_physical(FlatPtr(&end_of_kernel_image)))) }); - auto* mmap = (multiboot_memory_map_t*)(low_physical_to_virtual(multiboot_info_ptr->mmap_addr)); - for (; (unsigned long)mmap < (low_physical_to_virtual(multiboot_info_ptr->mmap_addr)) + (multiboot_info_ptr->mmap_length); mmap = (multiboot_memory_map_t*)((unsigned long)mmap + mmap->size + sizeof(mmap->size))) { - klog() << "MM: Multiboot mmap: base_addr = " << String::format("0x%08llx", mmap->addr) << ", length = " << String::format("0x%08llx", mmap->len) << ", type = 0x" << String::format("%x", mmap->type); - if (mmap->type != MULTIBOOT_MEMORY_AVAILABLE) - continue; + if (multiboot_info_ptr->flags & 0x4) { + auto* bootmods_start = multiboot_copy_boot_modules_array; + auto* bootmods_end = bootmods_start + multiboot_copy_boot_modules_count; - // FIXME: Maybe make use of stuff below the 1MiB mark? - if (mmap->addr < (1 * MiB)) + for (auto* bootmod = bootmods_start; bootmod < bootmods_end; bootmod++) { + m_used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::BootModule, PhysicalAddress(bootmod->start), PhysicalAddress(bootmod->end) }); + } + } + + auto* mmap_begin = reinterpret_cast<multiboot_memory_map_t*>(low_physical_to_virtual(multiboot_info_ptr->mmap_addr)); + auto* mmap_end = reinterpret_cast<multiboot_memory_map_t*>(low_physical_to_virtual(multiboot_info_ptr->mmap_addr) + multiboot_info_ptr->mmap_length); + + for (auto used_range : m_used_memory_ranges) { + klog() << "MM: " << used_range; + } + + for (auto* mmap = mmap_begin; mmap < mmap_end; mmap++) { + klog() << "MM: Multiboot mmap: address = " << String::format("0x%016llx", mmap->addr) << ", length = " << String::format("0x%016llx", mmap->len) << ", type = 0x" << String::format("%x", mmap->type); + + if (mmap->type != MULTIBOOT_MEMORY_AVAILABLE) continue; if ((mmap->addr + mmap->len) > 0xffffffff) continue; + // Fix up unaligned memory regions. auto diff = (FlatPtr)mmap->addr % PAGE_SIZE; if (diff != 0) { klog() << "MM: got an unaligned region base from the bootloader; correcting " << String::format("%p", (void*)mmap->addr) << " by " << diff << " bytes"; @@ -188,12 +205,12 @@ void MemoryManager::parse_memory_map() for (auto& region : m_super_physical_regions) { m_super_physical_pages += region.finalize_capacity(); - klog() << "Super physical region: " << region.lower() << " - " << region.upper(); + klog() << "MM: Super physical region: " << region.lower() << " - " << region.upper(); } for (auto& region : m_user_physical_regions) { m_user_physical_pages += region.finalize_capacity(); - klog() << "User physical region: " << region.lower() << " - " << region.upper(); + klog() << "MM: User physical region: " << region.lower() << " - " << region.upper(); } ASSERT(m_super_physical_pages > 0); diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index db8537dea0..1afd405a37 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -67,6 +67,26 @@ inline u32 virtual_to_low_physical(u32 physical) class KBuffer; class SynthFSInode; +enum class UsedMemoryRangeType { + LowMemory = 0, + Kernel, + BootModule, +}; + +constexpr static const char* UserMemoryRangeTypeNames[] { + "Low memory", + "Kernel", + "Boot module", +}; + +struct UsedMemoryRange { + UsedMemoryRangeType type; + PhysicalAddress start; + PhysicalAddress end; +}; + +const LogStream& operator<<(const LogStream& stream, const UsedMemoryRange& value); + #define MM Kernel::MemoryManager::the() struct MemoryManagerData { @@ -93,6 +113,7 @@ public: static MemoryManager& the(); static bool is_initialized(); + static void early_initialize(); static void initialize(u32 cpu); static inline MemoryManagerData& get_data() @@ -165,6 +186,8 @@ public: PageDirectory& kernel_page_directory() { return *m_kernel_page_directory; } + const Vector<UsedMemoryRange>& used_memory_ranges() { return m_used_memory_ranges; } + private: MemoryManager(); ~MemoryManager(); @@ -221,6 +244,7 @@ private: InlineLinkedList<Region> m_user_regions; InlineLinkedList<Region> m_kernel_regions; + Vector<UsedMemoryRange> m_used_memory_ranges; InlineLinkedList<VMObject> m_vmobjects; |