mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[kernel] Spit out vm_area types
The vm_space allow() functionality was a bit janky; using VMAs for all regions would be a lot cleaner. To that end, this change: - Adds a "static array" ctor to kutil::vector for setting the kernel address space's VMA list. This way a kernel heap VMA can be created without the heap already existing. - Splits vm_area into different subclasses depending on desired behavior - Splits out the concept of vm_mapper which maps vm_areas to vm_spaces, so that some kinds of VMA can be inherently single-space - Implements VMA resizing so that userspace can grow allocations. - Obsolete page_table_indices is removed Also, the following bugs were fixed: - kutil::map iterators on empty maps no longer break - memory::page_count was doing page-align, not page-count See: Github bug #242 See: [frobozz blog post](https://jsix.dev/posts/frobozz/) Tags:
This commit is contained in:
98
src/kernel/vm_mapper.cpp
Normal file
98
src/kernel/vm_mapper.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "objects/vm_area.h"
|
||||
#include "vm_mapper.h"
|
||||
#include "vm_space.h"
|
||||
|
||||
|
||||
vm_mapper_single::vm_mapper_single(vm_area &area, vm_space &space) :
|
||||
m_area(area), m_space(space)
|
||||
{}
|
||||
|
||||
vm_mapper_single::~vm_mapper_single()
|
||||
{
|
||||
m_space.clear(m_area, 0, memory::page_count(m_area.size()), true);
|
||||
}
|
||||
|
||||
bool
|
||||
vm_mapper_single::can_resize(size_t size) const
|
||||
{
|
||||
return m_space.can_resize(m_area, size);
|
||||
}
|
||||
|
||||
void
|
||||
vm_mapper_single::map(uintptr_t offset, size_t count, uintptr_t phys)
|
||||
{
|
||||
m_space.page_in(m_area, offset, phys, count);
|
||||
}
|
||||
|
||||
void
|
||||
vm_mapper_single::unmap(uintptr_t offset, size_t count)
|
||||
{
|
||||
m_space.clear(m_area, offset, count, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
vm_mapper_multi::vm_mapper_multi(vm_area &area) :
|
||||
m_area(area)
|
||||
{
|
||||
}
|
||||
|
||||
vm_mapper_multi::~vm_mapper_multi()
|
||||
{
|
||||
if (!m_spaces.count())
|
||||
return;
|
||||
|
||||
size_t count = memory::page_count(m_area.size());
|
||||
|
||||
for (int i = 1; i < m_spaces.count(); ++i)
|
||||
m_spaces[i]->clear(m_area, 0, count);
|
||||
|
||||
m_spaces[0]->clear(m_area, 0, count, true);
|
||||
}
|
||||
|
||||
bool
|
||||
vm_mapper_multi::can_resize(size_t size) const
|
||||
{
|
||||
for (auto &it : m_spaces)
|
||||
if (!it->can_resize(m_area, size))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
vm_mapper_multi::map(uintptr_t offset, size_t count, uintptr_t phys)
|
||||
{
|
||||
for (auto &it : m_spaces)
|
||||
it->page_in(m_area, offset, phys, count);
|
||||
}
|
||||
|
||||
void
|
||||
vm_mapper_multi::unmap(uintptr_t offset, size_t count)
|
||||
{
|
||||
for (auto &it : m_spaces)
|
||||
it->clear(m_area, offset, count);
|
||||
}
|
||||
|
||||
void
|
||||
vm_mapper_multi::add(vm_space *space)
|
||||
{
|
||||
if (m_spaces.count()) {
|
||||
vm_space *source = m_spaces[0];
|
||||
space->copy_from(*source, m_area);
|
||||
}
|
||||
|
||||
m_spaces.append(space);
|
||||
}
|
||||
|
||||
void
|
||||
vm_mapper_multi::remove(vm_space *space)
|
||||
{
|
||||
size_t count = memory::page_count(m_area.size());
|
||||
|
||||
for (int i = 0; i < m_spaces.count(); ++i) {
|
||||
if (m_spaces[i] == space) {
|
||||
m_spaces.remove_swap_at(i);
|
||||
space->clear(m_area, 0, count, m_spaces.count() == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user