[kernel] Split loading from scheduler

In preparation for moving things to the init process, move process
loading out of the scheduler. memory_bootstrap now has a
load_simple_process function for mapping an args::program into memory,
and the stack setup has been simplified (though all the initv values are
still being added by the kernel - this needs rework) and normalized to
use the thread::add_thunk_user code path.
This commit is contained in:
Justin C. Miller
2021-01-28 01:30:17 -08:00
parent 35d8d2ab2d
commit 3aa909b917
12 changed files with 163 additions and 179 deletions

View File

@@ -106,7 +106,9 @@ process::create_thread(uint8_t priority, bool user)
vm_flags::zero|vm_flags::write);
m_space.add(stack_top - stack_size, vma);
th->tcb()->rsp3 = stack_top;
// Space for null frame - because the page gets zeroed on
// allocation, just pointing rsp here does the trick
th->tcb()->rsp3 = stack_top - 2 * sizeof(uint64_t);
}
m_threads.append(th);

View File

@@ -16,7 +16,7 @@ public:
constexpr static uintptr_t stacks_top = 0x0000800000000000;
/// Size of userspace thread stacks
constexpr static size_t stack_size = 0x4000;
constexpr static size_t stack_size = 0x4000000; // 64MiB
/// Value that represents default priority
constexpr static uint8_t default_priority = 0xff;

View File

@@ -149,6 +149,10 @@ thread::exit(int32_t code)
void
thread::add_thunk_kernel(uintptr_t rip)
{
// This adds just enough values to the top of the
// kernel stack to come out of task_switch correctly
// and start executing at rip (still in kernel mode)
m_tcb.rsp -= sizeof(uintptr_t) * 7;
uintptr_t *stack = reinterpret_cast<uintptr_t*>(m_tcb.rsp);
@@ -162,15 +166,24 @@ thread::add_thunk_kernel(uintptr_t rip)
}
void
thread::add_thunk_user(uintptr_t rip)
thread::add_thunk_user(uintptr_t rip3, uintptr_t rip0, uint64_t flags)
{
// This sets up the stack to:
// a) come out of task_switch and return to rip0 (default is the
// kernel/user trampoline) (via add_thunk_kernel) - if this is
// changed, it needs to end up at the trampoline with the stack
// as it was
// b) come out of the kernel/user trampoline and start executing
// in user mode at rip
m_tcb.rsp -= sizeof(uintptr_t) * 8;
uintptr_t *stack = reinterpret_cast<uintptr_t*>(m_tcb.rsp);
flags |= 0x200;
stack[7] = rip; // return rip in rcx
stack[7] = rip3; // return rip in rcx
stack[6] = m_tcb.rsp3; // rbp
stack[5] = 0xbbbbbbbb; // rbx
stack[4] = 0x00000200; // r11 sets RFLAGS
stack[4] = flags; // r11 sets RFLAGS
stack[3] = 0x12121212; // r12
stack[2] = 0x13131313; // r13
stack[1] = 0x14141414; // r14
@@ -178,7 +191,7 @@ thread::add_thunk_user(uintptr_t rip)
static const uintptr_t trampoline =
reinterpret_cast<uintptr_t>(kernel_to_user_trampoline);
add_thunk_kernel(trampoline);
add_thunk_kernel(rip0 ? rip0 : trampoline);
}
void

View File

@@ -137,9 +137,12 @@ public:
/// \arg rip The address to return to, must be kernel space
void add_thunk_kernel(uintptr_t rip);
/// Add a stack header that returns to the given address in user space.
/// \arg rip The address to return to, must be user space
void add_thunk_user(uintptr_t rip);
/// Add a stack header that returns to the given address in user space
/// via a function in kernel space.
/// \arg rip3 The user space address to return to
/// \arg rip0 The kernel function to pass through, optional
/// \arg flags Extra RFLAGS values to set, optional
void add_thunk_user(uintptr_t rip3, uintptr_t rip0 = 0, uint64_t flags = 0);
/// Get the handle representing this thread to its process
j6_handle_t self_handle() const { return m_self_handle; }