[kernel] Change VMA syscall addr param to inout
This change allows the `vma_map` and `vma_create_map` syscalls to map to addresses other than the one specified, and therefore makes the address parameter to those syscalls `inout` in order to return the mapped address. Also add the `exact` flag for specifying that mapping needs to be done at the exact address given. If the mapping collides with another, the new `j6_err_collision` error is returned.
This commit is contained in:
@@ -17,13 +17,14 @@ object vma : object {
|
|||||||
|
|
||||||
method create_map [constructor cap:map] {
|
method create_map [constructor cap:map] {
|
||||||
param size size
|
param size size
|
||||||
param address address
|
param address address [inout]
|
||||||
param flags uint32
|
param flags uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
method map [cap:map] {
|
method map [cap:map] {
|
||||||
param process ref process [optional]
|
param process ref process [optional]
|
||||||
param address address
|
param address address [inout]
|
||||||
|
param flags uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
method unmap [cap:unmap] {
|
method unmap [cap:unmap] {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ load_init_server(bootproto::program &program, uintptr_t modules_address)
|
|||||||
((sect.type && section_flags::write) ? vm_flags::write : vm_flags::none);
|
((sect.type && section_flags::write) ? vm_flags::write : vm_flags::none);
|
||||||
|
|
||||||
obj::vm_area *vma = new obj::vm_area_fixed(sect.phys_addr, sect.size, flags);
|
obj::vm_area *vma = new obj::vm_area_fixed(sect.phys_addr, sect.size, flags);
|
||||||
space.add(sect.virt_addr, vma);
|
space.add(sect.virt_addr, vma, obj::vm_flags::exact);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t iopl = (3ull << 12);
|
uint64_t iopl = (3ull << 12);
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
|||||||
obj::vm_area *heap_map = new (&g_kernel_heapmap_area)
|
obj::vm_area *heap_map = new (&g_kernel_heapmap_area)
|
||||||
obj::vm_area_untracked(mem::heapmap_size, vm_flags::write);
|
obj::vm_area_untracked(mem::heapmap_size, vm_flags::write);
|
||||||
|
|
||||||
vm.add(mem::heap_offset, heap);
|
vm.add(mem::heap_offset, heap, vm_flags::exact);
|
||||||
vm.add(mem::heapmap_offset, heap_map);
|
vm.add(mem::heapmap_offset, heap_map, vm_flags::exact);
|
||||||
|
|
||||||
new (&g_kernel_heap) heap_allocator {mem::heap_offset, mem::heap_size, mem::heapmap_offset};
|
new (&g_kernel_heap) heap_allocator {mem::heap_offset, mem::heap_size, mem::heapmap_offset};
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
|||||||
size_t log_buffer_size = log::log_pages * arch::frame_size;
|
size_t log_buffer_size = log::log_pages * arch::frame_size;
|
||||||
obj::vm_area *logs = new (&g_kernel_log_area)
|
obj::vm_area *logs = new (&g_kernel_log_area)
|
||||||
obj::vm_area_ring(log_buffer_size, vm_flags::write);
|
obj::vm_area_ring(log_buffer_size, vm_flags::write);
|
||||||
vm.add(mem::logs_offset, logs);
|
vm.add(mem::logs_offset, logs, vm_flags::exact);
|
||||||
|
|
||||||
new (&g_logger) log::logger(
|
new (&g_logger) log::logger(
|
||||||
util::buffer::from(mem::logs_offset, log_buffer_size));
|
util::buffer::from(mem::logs_offset, log_buffer_size));
|
||||||
@@ -120,7 +120,7 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
|||||||
obj::vm_area *caps = new (&g_cap_table_area)
|
obj::vm_area *caps = new (&g_cap_table_area)
|
||||||
obj::vm_area_untracked(mem::caps_size, vm_flags::write);
|
obj::vm_area_untracked(mem::caps_size, vm_flags::write);
|
||||||
|
|
||||||
vm.add(mem::caps_offset, caps);
|
vm.add(mem::caps_offset, caps, vm_flags::exact);
|
||||||
|
|
||||||
new (&g_cap_table) cap_table {mem::caps_offset};
|
new (&g_cap_table) cap_table {mem::caps_offset};
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
|||||||
mem::kernel_stack_pages,
|
mem::kernel_stack_pages,
|
||||||
mem::stacks_size,
|
mem::stacks_size,
|
||||||
vm_flags::write};
|
vm_flags::write};
|
||||||
vm.add(mem::stacks_offset, &g_kernel_stacks);
|
vm.add(mem::stacks_offset, &g_kernel_stacks, vm_flags::exact);
|
||||||
|
|
||||||
// Clean out any remaning bootloader page table entries
|
// Clean out any remaning bootloader page table entries
|
||||||
for (unsigned i = 0; i < arch::kernel_root_index; ++i)
|
for (unsigned i = 0; i < arch::kernel_root_index; ++i)
|
||||||
@@ -140,7 +140,7 @@ void
|
|||||||
memory_initialize_post_ctors(bootproto::args &kargs)
|
memory_initialize_post_ctors(bootproto::args &kargs)
|
||||||
{
|
{
|
||||||
vm_space &vm = vm_space::kernel_space();
|
vm_space &vm = vm_space::kernel_space();
|
||||||
vm.add(mem::buffers_offset, &g_kernel_buffers);
|
vm.add(mem::buffers_offset, &g_kernel_buffers, vm_flags::exact);
|
||||||
|
|
||||||
g_frame_allocator.free(
|
g_frame_allocator.free(
|
||||||
get_physical_page(kargs.page_tables.pointer),
|
get_physical_page(kargs.page_tables.pointer),
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ start(cpu_data &bsp, void *kpml4)
|
|||||||
uintptr_t addr = 0x8000; // TODO: find a valid address, rewrite addresses
|
uintptr_t addr = 0x8000; // TODO: find a valid address, rewrite addresses
|
||||||
isr vector = static_cast<isr>(addr >> 12);
|
isr vector = static_cast<isr>(addr >> 12);
|
||||||
obj::vm_area *vma = new obj::vm_area_fixed(addr, 0x1000, vm_flags::write);
|
obj::vm_area *vma = new obj::vm_area_fixed(addr, 0x1000, vm_flags::write);
|
||||||
vm_space::kernel_space().add(addr, vma);
|
vm_space::kernel_space().add(addr, vma, obj::vm_flags::exact);
|
||||||
memcpy(
|
memcpy(
|
||||||
reinterpret_cast<void*>(addr),
|
reinterpret_cast<void*>(addr),
|
||||||
reinterpret_cast<void*>(&ap_startup),
|
reinterpret_cast<void*>(&ap_startup),
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ vma_create(j6_handle_t *self, size_t size, uint32_t flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
vma_create_map(j6_handle_t *self, size_t size, uintptr_t base, uint32_t flags)
|
vma_create_map(j6_handle_t *self, size_t size, uintptr_t *base, uint32_t flags)
|
||||||
{
|
{
|
||||||
vm_area *a = nullptr;
|
vm_area *a = nullptr;
|
||||||
vm_flags f = vm_flags::user_mask & flags;
|
vm_flags f = vm_flags::user_mask & flags;
|
||||||
@@ -32,16 +32,17 @@ vma_create_map(j6_handle_t *self, size_t size, uintptr_t base, uint32_t flags)
|
|||||||
else
|
else
|
||||||
a = construct_handle<vm_area_open>(self, size, f);
|
a = construct_handle<vm_area_open>(self, size, f);
|
||||||
|
|
||||||
process::current().space().add(base, a);
|
*base = process::current().space().add(*base, a, f);
|
||||||
return j6_status_ok;
|
return *base ? j6_status_ok : j6_err_collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
vma_map(vm_area *self, process *proc, uintptr_t base)
|
vma_map(vm_area *self, process *proc, uintptr_t *base, uint32_t flags)
|
||||||
{
|
{
|
||||||
vm_space &space = proc ? proc->space() : process::current().space();
|
vm_space &space = proc ? proc->space() : process::current().space();
|
||||||
space.add(base, self);
|
vm_flags f = vm_flags::user_mask & flags;
|
||||||
return j6_status_ok;
|
*base = space.add(*base, self, f);
|
||||||
|
return *base ? j6_status_ok : j6_err_collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ vm_space::vm_space() :
|
|||||||
sizeof(system_config),
|
sizeof(system_config),
|
||||||
vm_flags::none);
|
vm_flags::none);
|
||||||
|
|
||||||
add(sysconf_user_address, sysc);
|
add(sysconf_user_address, sysc, vm_flags::exact);
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_space::~vm_space()
|
vm_space::~vm_space()
|
||||||
@@ -80,14 +80,34 @@ vm_space::kernel_space()
|
|||||||
return obj::process::kernel_process().space();
|
return obj::process::kernel_process().space();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
uintptr_t
|
||||||
vm_space::add(uintptr_t base, obj::vm_area *area)
|
vm_space::add(uintptr_t base, obj::vm_area *area, obj::vm_flags flags)
|
||||||
{
|
{
|
||||||
//TODO: check for collisions
|
if (!base)
|
||||||
|
base = min_auto_address;
|
||||||
|
|
||||||
|
uintptr_t end = base + area->size();
|
||||||
|
|
||||||
|
//TODO: optimize find/insert
|
||||||
|
bool exact = util::bits::has(flags, j6_vm_flag_exact);
|
||||||
|
for (size_t i = 0; i < m_areas.count(); ++i) {
|
||||||
|
const vm_space::area &a = m_areas[i];
|
||||||
|
uintptr_t aend = a.base + a.area->size();
|
||||||
|
if (base >= aend)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (end <= a.base)
|
||||||
|
break;
|
||||||
|
else if (exact)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
base = aend;
|
||||||
|
}
|
||||||
|
|
||||||
m_areas.sorted_insert({base, area});
|
m_areas.sorted_insert({base, area});
|
||||||
area->add_to(this);
|
area->add_to(this);
|
||||||
area->handle_retain();
|
area->handle_retain();
|
||||||
return true;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -4,23 +4,27 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <j6/flags.h>
|
||||||
#include <util/enum_bitfields.h>
|
#include <util/enum_bitfields.h>
|
||||||
#include <util/spinlock.h>
|
#include <util/spinlock.h>
|
||||||
#include <util/vector.h>
|
#include <util/vector.h>
|
||||||
|
|
||||||
|
#include "objects/vm_area.h"
|
||||||
#include "page_table.h"
|
#include "page_table.h"
|
||||||
|
|
||||||
struct TCB;
|
struct TCB;
|
||||||
|
|
||||||
namespace obj {
|
namespace obj {
|
||||||
class process;
|
class process;
|
||||||
class vm_area;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tracks a region of virtual memory address space
|
/// Tracks a region of virtual memory address space
|
||||||
class vm_space
|
class vm_space
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// Never map below this address unless explicitly asked.
|
||||||
|
static constexpr uintptr_t min_auto_address = 16 * 1024 * 1024; // 16 MiB
|
||||||
|
|
||||||
/// Constructor for the kernel address space
|
/// Constructor for the kernel address space
|
||||||
/// \arg pml4 The existing kernel PML4
|
/// \arg pml4 The existing kernel PML4
|
||||||
vm_space(page_table *pml4);
|
vm_space(page_table *pml4);
|
||||||
@@ -33,8 +37,9 @@ public:
|
|||||||
/// Add a virtual memorty area to this address space
|
/// Add a virtual memorty area to this address space
|
||||||
/// \arg base The starting address of the area
|
/// \arg base The starting address of the area
|
||||||
/// \arg area The area to add
|
/// \arg area The area to add
|
||||||
/// \returns True if the add succeeded
|
/// \arg flags Flags for the operation (exact, clobber, etc)
|
||||||
bool add(uintptr_t base, obj::vm_area *area);
|
/// \returns The base address the area was added at
|
||||||
|
uintptr_t add(uintptr_t base, obj::vm_area *area, obj::vm_flags flags);
|
||||||
|
|
||||||
/// Remove a virtual memory area from this address space
|
/// Remove a virtual memory area from this address space
|
||||||
/// \arg area The area to remove
|
/// \arg area The area to remove
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ channel::create(size_t size)
|
|||||||
channel_addr += size * 2; // account for ring buffer virtual space doubling
|
channel_addr += size * 2; // account for ring buffer virtual space doubling
|
||||||
lock.release();
|
lock.release();
|
||||||
|
|
||||||
result = j6_vma_create_map(&vma, size, addr, j6_vm_flag_write|j6_vm_flag_ring);
|
result = j6_vma_create_map(&vma, size, &addr, j6_vm_flag_write|j6_vm_flag_ring);
|
||||||
if (result != j6_status_ok) {
|
if (result != j6_status_ok) {
|
||||||
syslog("Failed to create channel VMA. Error: %lx", result);
|
syslog("Failed to create channel VMA. Error: %lx", result);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -77,7 +77,7 @@ channel::open(j6_handle_t vma)
|
|||||||
util::scoped_lock lock {addr_spinlock};
|
util::scoped_lock lock {addr_spinlock};
|
||||||
uintptr_t addr = channel_addr;
|
uintptr_t addr = channel_addr;
|
||||||
|
|
||||||
result = j6_vma_map(vma, 0, addr);
|
result = j6_vma_map(vma, 0, &addr, 0);
|
||||||
if (result != j6_status_ok) {
|
if (result != j6_status_ok) {
|
||||||
syslog("Failed to map channel VMA. Error: %lx", result);
|
syslog("Failed to map channel VMA. Error: %lx", result);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -24,4 +24,5 @@
|
|||||||
#define j6_err_insufficient j6_err(0x0005)
|
#define j6_err_insufficient j6_err(0x0005)
|
||||||
#define j6_err_timed_out j6_err(0x0006)
|
#define j6_err_timed_out j6_err(0x0006)
|
||||||
#define j6_err_denied j6_err(0x0007)
|
#define j6_err_denied j6_err(0x0007)
|
||||||
|
#define j6_err_collision j6_err(0x0008)
|
||||||
|
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ enum j6_vm_flags {
|
|||||||
enum j6_flags {
|
enum j6_flags {
|
||||||
j6_flag_block = 0x01,
|
j6_flag_block = 0x01,
|
||||||
|
|
||||||
j6_flags_COUNT // custom per-type flags should start here
|
j6_flags_MAX // custom per-type flags should start here
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
VM_FLAG( none, 0x00000000 )
|
VM_FLAG( none, 0x00000000 )
|
||||||
|
|
||||||
VM_FLAG( write, 0x00000001 )
|
VM_FLAG( write, 0x00000001 )
|
||||||
VM_FLAG( exec, 0x00000002 )
|
VM_FLAG( exec, 0x00000002 )
|
||||||
VM_FLAG( contiguous, 0x00000020 )
|
|
||||||
VM_FLAG( large_pages, 0x00000100 )
|
|
||||||
VM_FLAG( huge_pages, 0x00000200 )
|
|
||||||
VM_FLAG( write_combine, 0x00001000 )
|
|
||||||
VM_FLAG( ring, 0x00002000 )
|
|
||||||
|
|
||||||
VM_FLAG( mmio, 0x00010000 )
|
VM_FLAG( contiguous, 0x00000010 )
|
||||||
|
VM_FLAG( large_pages, 0x00000020 )
|
||||||
|
VM_FLAG( huge_pages, 0x00000040 )
|
||||||
|
|
||||||
|
VM_FLAG( write_combine, 0x00000100 )
|
||||||
|
|
||||||
|
VM_FLAG( mmio, 0x00001000 )
|
||||||
|
|
||||||
|
VM_FLAG( exact, 0x00010000 )
|
||||||
|
VM_FLAG( ring, 0x00020000 )
|
||||||
@@ -19,22 +19,25 @@ template <typename Proc>
|
|||||||
class thread
|
class thread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr uintptr_t stack_base_start = 0x7f0'0000'0000;
|
||||||
|
|
||||||
/// Constructor. Create a thread and its stack space, but
|
/// Constructor. Create a thread and its stack space, but
|
||||||
/// do not start executing the thread.
|
/// do not start executing the thread.
|
||||||
/// \arg p The function where the thread will begin execution
|
/// \arg p The function where the thread will begin execution
|
||||||
/// \arg stack_top The address where the top of this thread's stack should be mapped
|
/// \arg stack_top The address where the top of this thread's stack should be mapped
|
||||||
/// \arg stack_size Size of the stack, in bytes (default 64KiB)
|
/// \arg stack_size Size of the stack, in bytes (default 16MiB)
|
||||||
thread(Proc p, uintptr_t stack_top, size_t stack_size = 0x10000) :
|
thread(Proc p, size_t stack_size = 0x100'0000) :
|
||||||
m_stack {j6_handle_invalid},
|
m_stack {j6_handle_invalid},
|
||||||
m_thread {j6_handle_invalid},
|
m_thread {j6_handle_invalid},
|
||||||
m_stack_top {stack_top},
|
|
||||||
m_proc {p}
|
m_proc {p}
|
||||||
{
|
{
|
||||||
uintptr_t stack_base = stack_top - stack_size;
|
uintptr_t stack_base = stack_base_start;
|
||||||
m_status = j6_vma_create_map(&m_stack, stack_size, stack_base, j6_vm_flag_write);
|
m_status = j6_vma_create_map(&m_stack, stack_size, &stack_base, j6_vm_flag_write);
|
||||||
if (m_status != j6_status_ok)
|
if (m_status != j6_status_ok)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_stack_top = stack_base + stack_size;
|
||||||
|
|
||||||
static constexpr size_t zeros_size = 0x10;
|
static constexpr size_t zeros_size = 0x10;
|
||||||
m_stack_top -= zeros_size; // Sentinel
|
m_stack_top -= zeros_size; // Sentinel
|
||||||
memset(reinterpret_cast<void*>(m_stack_top), 0, zeros_size);
|
memset(reinterpret_cast<void*>(m_stack_top), 0, zeros_size);
|
||||||
|
|||||||
@@ -1,26 +1,17 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <j6/errors.h>
|
||||||
|
#include <j6/syscalls.h>
|
||||||
|
|
||||||
namespace __j6libc {
|
namespace __j6libc {
|
||||||
|
|
||||||
using j6_status_t = uint64_t;
|
|
||||||
using j6_handle_t = uint64_t;
|
|
||||||
|
|
||||||
constexpr j6_handle_t j6_handle_invalid = -1ull;
|
|
||||||
constexpr j6_status_t j6_status_ok = 0;
|
|
||||||
|
|
||||||
static j6_handle_t core_handle = j6_handle_invalid;
|
static j6_handle_t core_handle = j6_handle_invalid;
|
||||||
static intptr_t core_size = 0;
|
static intptr_t core_size = 0;
|
||||||
|
|
||||||
static const uintptr_t core_base = 0x1c0000000;
|
static uintptr_t core_base = 0x1c0000000;
|
||||||
|
|
||||||
static const void *error_val = (void*)-1;
|
static const void *error_val = (void*)-1;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
j6_status_t j6_vma_create_map(j6_handle_t *, size_t, uintptr_t, unsigned);
|
|
||||||
j6_status_t j6_vma_resize(j6_handle_t, size_t *);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * increase_core(intptr_t i)
|
void * increase_core(intptr_t i)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
@@ -30,7 +21,7 @@ void * increase_core(intptr_t i)
|
|||||||
if (i < 0)
|
if (i < 0)
|
||||||
return (void*)-1;
|
return (void*)-1;
|
||||||
|
|
||||||
j6_status_t result = j6_vma_create_map(&core_handle, i, core_base, 1);
|
j6_status_t result = j6_vma_create_map(&core_handle, i, &core_base, 1);
|
||||||
if (result != j6_status_ok)
|
if (result != j6_status_ok)
|
||||||
return (void*)-1;
|
return (void*)-1;
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ main(int argc, const char **argv, const char **env)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = j6_vma_map(fb_handle, 0, lfb_addr);
|
s = j6_vma_map(fb_handle, 0, &lfb_addr, j6_vm_flag_exact);
|
||||||
if (s != j6_status_ok) {
|
if (s != j6_status_ok) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
static uint64_t initfs_running = 1;
|
static uint64_t initfs_running = 1;
|
||||||
static constexpr size_t buffer_size = 2048;
|
static constexpr size_t buffer_size = 2048;
|
||||||
static constexpr uintptr_t load_addr = 0xf00000000;
|
|
||||||
|
|
||||||
j6_status_t
|
j6_status_t
|
||||||
handle_load_request(j6romfs::fs &fs, const char *path, j6_handle_t &vma)
|
handle_load_request(j6romfs::fs &fs, const char *path, j6_handle_t &vma)
|
||||||
@@ -21,7 +20,8 @@ handle_load_request(j6romfs::fs &fs, const char *path, j6_handle_t &vma)
|
|||||||
return j6_status_ok;
|
return j6_status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
j6_vma_create_map(&vma, in->size, load_addr, j6_vm_flag_write);
|
uintptr_t load_addr = 0;
|
||||||
|
j6_vma_create_map(&vma, in->size, &load_addr, j6_vm_flag_write);
|
||||||
util::buffer dest = util::buffer::from(load_addr, in->size);
|
util::buffer dest = util::buffer::from(load_addr, in->size);
|
||||||
fs.load_inode_data(in, dest);
|
fs.load_inode_data(in, dest);
|
||||||
j6_vma_unmap(vma, 0);
|
j6_vma_unmap(vma, 0);
|
||||||
|
|||||||
@@ -16,10 +16,9 @@
|
|||||||
|
|
||||||
using bootproto::module;
|
using bootproto::module;
|
||||||
|
|
||||||
static uintptr_t load_addr = 0xf'000'0000;
|
|
||||||
static constexpr size_t stack_size = 0x10000;
|
|
||||||
static constexpr uintptr_t stack_top = 0x80000000000;
|
|
||||||
static constexpr size_t MiB = 0x10'0000ull;
|
static constexpr size_t MiB = 0x10'0000ull;
|
||||||
|
static constexpr size_t stack_size = 16 * MiB;
|
||||||
|
static constexpr uintptr_t stack_top = 0x7f0'0000'0000;
|
||||||
|
|
||||||
inline uintptr_t align_up(uintptr_t a) { return ((a-1) & ~(MiB-1)) + MiB; }
|
inline uintptr_t align_up(uintptr_t a) { return ((a-1) & ~(MiB-1)) + MiB; }
|
||||||
|
|
||||||
@@ -31,7 +30,7 @@ map_phys(j6_handle_t sys, uintptr_t phys, size_t len, j6_vm_flags flags)
|
|||||||
if (res != j6_status_ok)
|
if (res != j6_status_ok)
|
||||||
return j6_handle_invalid;
|
return j6_handle_invalid;
|
||||||
|
|
||||||
res = j6_vma_map(vma, 0, phys);
|
res = j6_vma_map(vma, 0, &phys, j6_vm_flag_exact);
|
||||||
if (res != j6_status_ok)
|
if (res != j6_status_ok)
|
||||||
return j6_handle_invalid;
|
return j6_handle_invalid;
|
||||||
|
|
||||||
@@ -72,8 +71,7 @@ load_program_into(j6_handle_t proc, elf::file &file, uintptr_t image_base, const
|
|||||||
if (seg.type != elf::segment_type::load)
|
if (seg.type != elf::segment_type::load)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uintptr_t addr = load_addr;
|
uintptr_t addr = 0;
|
||||||
load_addr = align_up(load_addr + seg.mem_size);
|
|
||||||
|
|
||||||
// TODO: way to remap VMA as read-only if there's no write flag on
|
// TODO: way to remap VMA as read-only if there's no write flag on
|
||||||
// the segment
|
// the segment
|
||||||
@@ -86,7 +84,7 @@ load_program_into(j6_handle_t proc, elf::file &file, uintptr_t image_base, const
|
|||||||
size_t epilogue = seg.mem_size - seg.file_size;
|
size_t epilogue = seg.mem_size - seg.file_size;
|
||||||
|
|
||||||
j6_handle_t sub_vma = j6_handle_invalid;
|
j6_handle_t sub_vma = j6_handle_invalid;
|
||||||
j6_status_t res = j6_vma_create_map(&sub_vma, seg.mem_size+prologue, addr, flags);
|
j6_status_t res = j6_vma_create_map(&sub_vma, seg.mem_size+prologue, &addr, flags);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
j6::syslog(" ** error loading ELF '%s': creating sub vma: %lx", path, res);
|
j6::syslog(" ** error loading ELF '%s': creating sub vma: %lx", path, res);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -102,9 +100,9 @@ load_program_into(j6_handle_t proc, elf::file &file, uintptr_t image_base, const
|
|||||||
if (eos > eop)
|
if (eos > eop)
|
||||||
eop = eos;
|
eop = eos;
|
||||||
|
|
||||||
uintptr_t start_addr = (image_base + seg.vaddr);
|
uintptr_t start_addr = (image_base + seg.vaddr) & ~0xfffull;
|
||||||
j6::syslog("Mapping segment from %s at %012lx - %012lx", path, start_addr, start_addr+seg.mem_size);
|
j6::syslog("Mapping segment from %s at %012lx - %012lx", path, start_addr, start_addr+seg.mem_size);
|
||||||
res = j6_vma_map(sub_vma, proc, start_addr & ~0xfffull);
|
res = j6_vma_map(sub_vma, proc, &start_addr, j6_vm_flag_exact);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
j6::syslog(" ** error loading ELF '%s': mapping sub vma to child: %lx", path, res);
|
j6::syslog(" ** error loading ELF '%s': mapping sub vma to child: %lx", path, res);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -193,10 +191,9 @@ load_program(
|
|||||||
if (!eop)
|
if (!eop)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uintptr_t stack_addr = load_addr;
|
uintptr_t stack_addr = 0;
|
||||||
load_addr = align_up(load_addr + stack_size);
|
|
||||||
j6_handle_t stack_vma = j6_handle_invalid;
|
j6_handle_t stack_vma = j6_handle_invalid;
|
||||||
j6_status_t res = j6_vma_create_map(&stack_vma, stack_size, stack_addr, j6_vm_flag_write);
|
j6_status_t res = j6_vma_create_map(&stack_vma, stack_size, &stack_addr, j6_vm_flag_write);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
j6::syslog(" ** error loading program '%s': creating stack vma: %lx", path, res);
|
j6::syslog(" ** error loading program '%s': creating stack vma: %lx", path, res);
|
||||||
return false;
|
return false;
|
||||||
@@ -223,9 +220,8 @@ load_program(
|
|||||||
const elf::file_header *h = program_elf.header();
|
const elf::file_header *h = program_elf.header();
|
||||||
loader_arg->image_base = program_image_base;
|
loader_arg->image_base = program_image_base;
|
||||||
loader_arg->phdr = h->ph_offset;
|
loader_arg->phdr = h->ph_offset;
|
||||||
loader_arg->phdr_size = h->ph_entsize;
|
|
||||||
loader_arg->phdr_count = h->ph_num;
|
loader_arg->phdr_count = h->ph_num;
|
||||||
loader_arg->entrypoint = program_elf.entrypoint();
|
loader_arg->entrypoint = entrypoint;
|
||||||
|
|
||||||
j6_arg_handles *handles_arg = stack_push<j6_arg_handles>(stack, 2 * sizeof(j6_arg_handle_entry));
|
j6_arg_handles *handles_arg = stack_push<j6_arg_handles>(stack, 2 * sizeof(j6_arg_handle_entry));
|
||||||
handles_arg->nhandles = 1;
|
handles_arg->nhandles = 1;
|
||||||
@@ -258,7 +254,8 @@ load_program(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = j6_vma_map(stack_vma, proc, stack_top-stack_size);
|
uintptr_t stack_base = stack_top-stack_size;
|
||||||
|
res = j6_vma_map(stack_vma, proc, &stack_base, j6_vm_flag_exact);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
j6::syslog(" ** error loading program '%s': mapping stack vma: %lx", path, res);
|
j6::syslog(" ** error loading program '%s': mapping stack vma: %lx", path, res);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user