Kernel: Implement thread start trampoline for userspace
This is needed on i686 to set segment registers.
This commit is contained in:
parent
4d70322eab
commit
fe386fa819
|
@ -24,3 +24,29 @@ start_kernel_thread:
|
||||||
movq 24(%rsp), %rdi
|
movq 24(%rsp), %rdi
|
||||||
movq 16(%rsp), %rsi
|
movq 16(%rsp), %rsi
|
||||||
call *%rsi
|
call *%rsi
|
||||||
|
|
||||||
|
.global start_userspace_thread
|
||||||
|
start_userspace_thread:
|
||||||
|
call get_start_kernel_thread_sp
|
||||||
|
movq %rax, %rsp
|
||||||
|
|
||||||
|
# STACK LAYOUT
|
||||||
|
# entry
|
||||||
|
# argc
|
||||||
|
# argv
|
||||||
|
# envp
|
||||||
|
# userspace stack
|
||||||
|
|
||||||
|
call get_userspace_thread_stack_top
|
||||||
|
|
||||||
|
popq %rdx
|
||||||
|
popq %rsi
|
||||||
|
popq %rdi
|
||||||
|
popq %rcx
|
||||||
|
|
||||||
|
pushq $(0x20 | 3)
|
||||||
|
pushq %rax
|
||||||
|
pushq $0x202
|
||||||
|
pushq $(0x18 | 3)
|
||||||
|
pushq %rcx
|
||||||
|
iretq
|
||||||
|
|
|
@ -29,11 +29,6 @@ namespace Kernel
|
||||||
return *s_instance;
|
return *s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" uintptr_t get_start_kernel_thread_sp()
|
|
||||||
{
|
|
||||||
return Scheduler::get().current_thread().kernel_stack_top() - 4 * sizeof(uintptr_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scheduler::start()
|
void Scheduler::start()
|
||||||
{
|
{
|
||||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
extern "C" [[noreturn]] void start_kernel_thread();
|
extern "C" [[noreturn]] void start_kernel_thread();
|
||||||
|
extern "C" [[noreturn]] void start_userspace_thread();
|
||||||
|
|
||||||
extern "C" void signal_trampoline();
|
extern "C" void signal_trampoline();
|
||||||
|
|
||||||
|
@ -23,6 +24,16 @@ namespace Kernel
|
||||||
*(uintptr_t*)rsp = (uintptr_t)value;
|
*(uintptr_t*)rsp = (uintptr_t)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" uintptr_t get_start_kernel_thread_sp()
|
||||||
|
{
|
||||||
|
return Thread::current().kernel_stack_top() - 4 * sizeof(uintptr_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" uintptr_t get_userspace_thread_stack_top()
|
||||||
|
{
|
||||||
|
return Thread::current().userspace_stack_top() - 4 * sizeof(uintptr_t);
|
||||||
|
}
|
||||||
|
|
||||||
static pid_t s_next_tid = 1;
|
static pid_t s_next_tid = 1;
|
||||||
|
|
||||||
BAN::ErrorOr<Thread*> Thread::create_kernel(entry_t entry, void* data, Process* process)
|
BAN::ErrorOr<Thread*> Thread::create_kernel(entry_t entry, void* data, Process* process)
|
||||||
|
@ -197,19 +208,19 @@ namespace Kernel
|
||||||
ASSERT(userspace_info.entry);
|
ASSERT(userspace_info.entry);
|
||||||
|
|
||||||
// Initialize stack for returning
|
// Initialize stack for returning
|
||||||
PageTable::with_fast_page(process().page_table().physical_address_of(userspace_stack_top() - PAGE_SIZE), [&] {
|
PageTable::with_fast_page(process().page_table().physical_address_of(kernel_stack_top() - PAGE_SIZE), [&] {
|
||||||
uintptr_t sp = PageTable::fast_page() + PAGE_SIZE;
|
uintptr_t sp = PageTable::fast_page() + PAGE_SIZE;
|
||||||
write_to_stack(sp, nullptr);
|
write_to_stack(sp, userspace_info.entry);
|
||||||
write_to_stack(sp, userspace_info.argc);
|
write_to_stack(sp, userspace_info.argc);
|
||||||
write_to_stack(sp, userspace_info.argv);
|
write_to_stack(sp, userspace_info.argv);
|
||||||
write_to_stack(sp, userspace_info.envp);
|
write_to_stack(sp, userspace_info.envp);
|
||||||
});
|
});
|
||||||
|
|
||||||
m_interrupt_stack.ip = userspace_info.entry;
|
m_interrupt_stack.ip = reinterpret_cast<vaddr_t>(start_userspace_thread);;
|
||||||
m_interrupt_stack.cs = 0x18 | 3;
|
m_interrupt_stack.cs = 0x08;
|
||||||
m_interrupt_stack.flags = 0x202;
|
m_interrupt_stack.flags = 0x002;
|
||||||
m_interrupt_stack.sp = userspace_stack_top() - 4 * sizeof(uintptr_t);
|
m_interrupt_stack.sp = kernel_stack_top() - 4 * sizeof(uintptr_t);
|
||||||
m_interrupt_stack.ss = 0x20 | 3;
|
m_interrupt_stack.ss = 0x10;
|
||||||
|
|
||||||
memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters));
|
memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
.global _start
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
|
pushq $0
|
||||||
|
pushq %rdi
|
||||||
|
pushq %rsi
|
||||||
|
pushq %rdx
|
||||||
|
|
||||||
# STACK LAYOUT
|
# STACK LAYOUT
|
||||||
# null
|
# null
|
||||||
# argc
|
# argc
|
||||||
|
|
Loading…
Reference in New Issue