1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:48:12 +00:00
serenity/Kernel/VM/PageDirectory.cpp
Jesse Buhagiar bd33c66273 Kernel: Move Kernel mapping to 0xc0000000
The kernel is now no longer identity mapped to the bottom 8MiB of
memory, and is now mapped at the higher address of `0xc0000000`.

The lower ~1MiB of memory (from GRUB's mmap), however is still
identity mapped to provide an easy way for the kernel to get
physical pages for things such as DMA etc. These could later be
mapped to the higher address too, as I'm not too sure how to
go about doing this elegantly without a lot of address subtractions.
2019-11-22 16:23:23 +01:00

59 lines
1.8 KiB
C++

#include <Kernel/Process.h>
#include <Kernel/Thread.h>
#include <Kernel/VM/MemoryManager.h>
#include <Kernel/VM/PageDirectory.h>
static const u32 userspace_range_base = 0x01000000;
static const u32 kernelspace_range_base = 0xc0000000;
static HashMap<u32, PageDirectory*>& pdb_map()
{
ASSERT_INTERRUPTS_DISABLED();
static HashMap<u32, PageDirectory*>* map;
if (!map)
map = new HashMap<u32, PageDirectory*>;
return *map;
}
RefPtr<PageDirectory> PageDirectory::find_by_pdb(u32 pdb)
{
InterruptDisabler disabler;
return pdb_map().get(pdb).value_or({});
}
PageDirectory::PageDirectory(PhysicalAddress paddr)
: m_range_allocator(VirtualAddress(kernelspace_range_base + 0x800000), 0x3f000000)
{
m_directory_page = PhysicalPage::create(paddr, true, false);
InterruptDisabler disabler;
pdb_map().set(m_directory_page->paddr().get(), this);
}
PageDirectory::PageDirectory(Process& process, const RangeAllocator* parent_range_allocator)
: m_process(&process)
, m_range_allocator(parent_range_allocator ? RangeAllocator(*parent_range_allocator) : RangeAllocator(VirtualAddress(userspace_range_base), kernelspace_range_base - userspace_range_base))
{
MM.populate_page_directory(*this);
InterruptDisabler disabler;
pdb_map().set(m_directory_page->paddr().get(), this);
}
PageDirectory::~PageDirectory()
{
#ifdef MM_DEBUG
dbgprintf("MM: ~PageDirectory K%x\n", this);
#endif
InterruptDisabler disabler;
pdb_map().remove(m_directory_page->paddr().get());
}
void PageDirectory::flush(VirtualAddress vaddr)
{
#ifdef MM_DEBUG
dbgprintf("MM: Flush page V%p\n", vaddr.get());
#endif
if (!current)
return;
if (this == &MM.kernel_page_directory() || &current->process().page_directory() == this)
MM.flush_tlb(vaddr);
}