Compare commits

..

No commits in common. "d2df55b1ac799e4830f3450b161f2ed70384af73" and "6ac36816043c7abd659cff5a6b02bc0b8b521ecb" have entirely different histories.

14 changed files with 95 additions and 217 deletions

View File

@ -117,7 +117,16 @@ namespace Kernel
ASSERT(s_global_pdpte == 0); ASSERT(s_global_pdpte == 0);
s_global_pdpte = V2P(allocate_zeroed_page_aligned_page()); s_global_pdpte = V2P(allocate_zeroed_page_aligned_page());
map_kernel_memory(); ASSERT(m_highest_paging_struct == 0);
m_highest_paging_struct = V2P(kmalloc(32, 32, true));
ASSERT(m_highest_paging_struct);
uint64_t* pdpt = reinterpret_cast<uint64_t*>(P2V(m_highest_paging_struct));
pdpt[0] = 0;
pdpt[1] = 0;
pdpt[2] = 0;
pdpt[3] = s_global_pdpte;
static_assert(KERNEL_OFFSET == 0xC0000000);
prepare_fast_page(); prepare_fast_page();
@ -162,7 +171,8 @@ namespace Kernel
constexpr uint64_t pte = (fast_page() >> 12) & 0x1FF; constexpr uint64_t pte = (fast_page() >> 12) & 0x1FF;
uint64_t* pdpt = reinterpret_cast<uint64_t*>(P2V(m_highest_paging_struct)); uint64_t* pdpt = reinterpret_cast<uint64_t*>(P2V(m_highest_paging_struct));
ASSERT(pdpt[pdpte] & Flags::Present); ASSERT(!(pdpt[pdpte] & Flags::Present));
pdpt[pdpte] = V2P(allocate_zeroed_page_aligned_page()) | Flags::Present;
uint64_t* pd = reinterpret_cast<uint64_t*>(P2V(pdpt[pdpte]) & PAGE_ADDR_MASK); uint64_t* pd = reinterpret_cast<uint64_t*>(P2V(pdpt[pdpte]) & PAGE_ADDR_MASK);
ASSERT(!(pd[pde] & Flags::Present)); ASSERT(!(pd[pde] & Flags::Present));
@ -237,7 +247,7 @@ namespace Kernel
pdpt[0] = 0; pdpt[0] = 0;
pdpt[1] = 0; pdpt[1] = 0;
pdpt[2] = 0; pdpt[2] = 0;
pdpt[3] = s_global_pdpte | Flags::Present; pdpt[3] = s_global_pdpte;
static_assert(KERNEL_OFFSET == 0xC0000000); static_assert(KERNEL_OFFSET == 0xC0000000);
} }

View File

@ -1,31 +1,19 @@
.global sys_fork_trampoline .global sys_fork_trampoline
sys_fork_trampoline: sys_fork_trampoline:
pushl %ebp ud2
subl $4, %esp
pushl %ebx pushl %ebx
pushl %esi pushl %ebp
pushl %edi
call read_ip call read_ip
testl %eax, %eax testl %eax, %eax
jz .reload_stack je .done
movl %esp, %ebx
subl $8, %esp subl $8, %esp
pushl %eax pushl %eax
pushl %ebx pushl %esp
call sys_fork call sys_fork
addl $16, %esp addl $16, %esp
.done:
.done:
popl %edi
popl %esi
popl %ebx
popl %ebp popl %ebp
popl %ebx
addl $4, %esp
ret ret
.reload_stack:
call get_thread_start_sp
movl %eax, %esp
xorl %eax, %eax
jmp .done

View File

@ -7,7 +7,7 @@ read_ip:
# void start_kernel_thread() # void start_kernel_thread()
.global start_kernel_thread .global start_kernel_thread
start_kernel_thread: start_kernel_thread:
call get_thread_start_sp call get_start_kernel_thread_sp
movl %eax, %esp movl %eax, %esp
# STACK LAYOUT # STACK LAYOUT
@ -32,37 +32,3 @@ start_kernel_thread:
pushl %edi pushl %edi
call *%esi call *%esi
addl $16, %esp addl $16, %esp
.global start_userspace_thread
start_userspace_thread:
call get_thread_start_sp
movl %eax, %esp
# STACK LAYOUT
# entry
# argc
# argv
# envp
# userspace stack
call get_userspace_thread_stack_top
movw $(0x20 | 3), %bx
movw %bx, %ds
movw %bx, %es
movw %bx, %fs
movw %bx, %gs
xorw %bx, %bx
popl %edx
popl %esi
popl %edi
popl %ecx
pushl $(0x20 | 3)
pushl %eax
pushl $0x202
pushl $(0x18 | 3)
pushl %ecx
iret

View File

@ -231,6 +231,7 @@ system_halt:
.code16 .code16
.global ap_trampoline .global ap_trampoline
ap_trampoline: ap_trampoline:
ud2
jmp 1f jmp 1f
.align 8 .align 8
ap_stack_ptr: ap_stack_ptr:
@ -238,7 +239,10 @@ ap_stack_ptr:
1: 1:
cli; cld cli; cld
ljmpl $0x00, $ap_cs_clear ljmpl $0x00, $ap_cs_clear
ap_cs_clear: ap_cs_clear:
xorw %ax, %ax
movw %ax, %ds
# load ap gdt and enter protected mode # load ap gdt and enter protected mode
lgdt ap_gdtr lgdt ap_gdtr

View File

@ -1,48 +1,5 @@
.macro push_userspace
pushw %gs
pushw %fs
pushw %es
pushw %ds
pushal
.endm
.macro load_kernel_segments
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw $0x28, %ax
movw %ax, %gs
.endm
.macro pop_userspace
popal
popw %ds
popw %es
popw %fs
popw %gs
.endm
.macro pop_userspace_skip_eax
popl %edi
popl %esi
popl %ebp
addl $4, %esp
popl %ebx
popl %edx
popl %ecx
addl $4, %esp
popw %ds
popw %es
popw %fs
popw %gs
.endm
isr_stub: isr_stub:
push_userspace pusha
load_kernel_segments
movl %cr0, %eax; pushl %eax movl %cr0, %eax; pushl %eax
movl %cr2, %eax; pushl %eax movl %cr2, %eax; pushl %eax
@ -50,9 +7,9 @@ isr_stub:
movl %cr4, %eax; pushl %eax movl %cr4, %eax; pushl %eax
movl %esp, %eax // register ptr movl %esp, %eax // register ptr
leal 64(%esp), %ebx // interrupt stack ptr leal 56(%esp), %ebx // interrupt stack ptr
movl 60(%esp), %ecx // error code movl 52(%esp), %ecx // error code
movl 56(%esp), %edx // isr number movl 48(%esp), %edx // isr number
subl $12, %esp subl $12, %esp
pushl %eax pushl %eax
@ -62,32 +19,30 @@ isr_stub:
call cpp_isr_handler call cpp_isr_handler
addl $44, %esp addl $44, %esp
pop_userspace popa
addl $8, %esp addl $8, %esp
iret iret
irq_stub: irq_stub:
push_userspace pusha
load_kernel_segments
movl 40(%esp), %eax # interrupt number movl 32(%esp), %eax # interrupt number
subl $12, %esp subl $8, %esp
pushl %eax pushl %eax
call cpp_irq_handler call cpp_irq_handler
addl $16, %esp addl $12, %esp
pop_userspace popa
addl $8, %esp addl $8, %esp
iret iret
.global asm_reschedule_handler .global asm_reschedule_handler
asm_reschedule_handler: asm_reschedule_handler:
push_userspace pusha
load_kernel_segments
movl %esp, %eax # interrupt registers ptr movl %esp, %eax # interrupt registers ptr
leal 40(%esp), %ebx # interrupt stack ptr leal 32(%esp), %ebx # interrupt stack ptr
subl $12, %esp subl $12, %esp
pushl %eax pushl %eax
@ -95,18 +50,17 @@ asm_reschedule_handler:
call cpp_reschedule_handler call cpp_reschedule_handler
addl $20, %esp addl $20, %esp
pop_userspace popa
iret iret
// arguments in EAX, EBX, ECX, EDX, ESI, EDI // arguments in EAX, EBX, ECX, EDX, ESI, EDI
.global syscall_asm .global syscall_asm
syscall_asm: syscall_asm:
push_userspace ud2
pusha
subl $8, %esp
pushl %esp pushl %esp
addl $48, (%esp) addl $36, (%esp)
pushl %edi pushl %edi
pushl %esi pushl %esi
@ -115,12 +69,19 @@ syscall_asm:
pushl %ebx pushl %ebx
pushl %eax pushl %eax
load_kernel_segments
call cpp_syscall_handler call cpp_syscall_handler
addl $36, %esp
pop_userspace_skip_eax addl $60, %esp
popl %edi
popl %esi
popl %ebp
addl $4, %esp
popl %ebx
popl %edx
popl %ecx
addl $4, %esp
iret iret
.macro isr n .macro isr n

View File

@ -6,16 +6,13 @@ sys_fork_trampoline:
pushq %r13 pushq %r13
pushq %r14 pushq %r14
pushq %r15 pushq %r15
call read_ip call read_ip
testq %rax, %rax testq %rax, %rax
je .reload_stack je .done
movq %rax, %rsi movq %rax, %rsi
movq %rsp, %rdi movq %rsp, %rdi
call sys_fork call sys_fork
.done:
.done:
popq %r15 popq %r15
popq %r14 popq %r14
popq %r13 popq %r13
@ -23,9 +20,3 @@ sys_fork_trampoline:
popq %rbp popq %rbp
popq %rbx popq %rbx
ret ret
.reload_stack:
call get_thread_start_sp
movq %rax, %rsp
xorq %rax, %rax
jmp .done

View File

@ -7,7 +7,7 @@ read_ip:
# void start_kernel_thread() # void start_kernel_thread()
.global start_kernel_thread .global start_kernel_thread
start_kernel_thread: start_kernel_thread:
call get_thread_start_sp call get_start_kernel_thread_sp
movq %rax, %rsp movq %rax, %rsp
# STACK LAYOUT # STACK LAYOUT
@ -24,29 +24,3 @@ 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_thread_start_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

View File

@ -249,7 +249,10 @@ ap_stack_ptr:
1: 1:
cli; cld cli; cld
ljmpl $0x00, $ap_cs_clear ljmpl $0x00, $ap_cs_clear
ap_cs_clear: ap_cs_clear:
xorw %ax, %ax
movw %ax, %ds
# load ap gdt and enter protected mode # load ap gdt and enter protected mode
lgdt ap_gdtr lgdt ap_gdtr

View File

@ -124,7 +124,6 @@ namespace Kernel
m_tss.rsp0 = sp; m_tss.rsp0 = sp;
#elif ARCH(i686) #elif ARCH(i686)
m_tss.esp0 = sp; m_tss.esp0 = sp;
m_tss.ss0 = 0x10;
#endif #endif
} }

View File

@ -29,6 +29,11 @@ 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);
@ -115,7 +120,11 @@ namespace Kernel
if (thread->state() == Thread::State::NotStarted) if (thread->state() == Thread::State::NotStarted)
thread->m_state = Thread::State::Executing; thread->m_state = Thread::State::Executing;
ASSERT(thread->interrupt_stack().ip);
ASSERT(thread->interrupt_stack().sp);
Processor::gdt().set_tss_stack(thread->kernel_stack_top()); Processor::gdt().set_tss_stack(thread->kernel_stack_top());
Processor::get_interrupt_stack() = thread->interrupt_stack(); Processor::get_interrupt_stack() = thread->interrupt_stack();
Processor::get_interrupt_registers() = thread->interrupt_registers(); Processor::get_interrupt_registers() = thread->interrupt_registers();
} }
@ -145,9 +154,7 @@ namespace Kernel
"movq %[load_sp], %%rsp;" "movq %[load_sp], %%rsp;"
"int %[ipi];" "int %[ipi];"
"movq %%rcx, %%rsp;" "movq %%rcx, %%rsp;"
// NOTE: This is offset by 2 pointers since interrupt without PL change :: [load_sp]"r"(Processor::current_stack_top()),
// does not push SP and SS. This allows accessing "whole" interrupt stack.
:: [load_sp]"r"(Processor::current_stack_top() - 2 * sizeof(uintptr_t)),
[ipi]"i"(IRQ_VECTOR_BASE + IRQ_IPI) [ipi]"i"(IRQ_VECTOR_BASE + IRQ_IPI)
: "memory", "rcx" : "memory", "rcx"
); );
@ -157,9 +164,7 @@ namespace Kernel
"movl %[load_sp], %%esp;" "movl %[load_sp], %%esp;"
"int %[ipi];" "int %[ipi];"
"movl %%ecx, %%esp;" "movl %%ecx, %%esp;"
// NOTE: This is offset by 2 pointers since interrupt without PL change :: [load_sp]"r"(Processor::current_stack_top()),
// does not push SP and SS. This allows accessing "whole" interrupt stack.
:: [load_sp]"r"(Processor::current_stack_top() - 2 * sizeof(uintptr_t)),
[ipi]"i"(IRQ_VECTOR_BASE + IRQ_IPI) [ipi]"i"(IRQ_VECTOR_BASE + IRQ_IPI)
: "memory", "ecx" : "memory", "ecx"
); );

View File

@ -28,9 +28,9 @@ namespace Kernel
#undef O #undef O
}; };
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack* interrupt_stack) extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack& interrupt_stack)
{ {
ASSERT(GDT::is_user_segment(interrupt_stack->cs)); ASSERT((interrupt_stack.cs & 0b11) == 0b11);
asm volatile("sti"); asm volatile("sti");

View File

@ -13,7 +13,6 @@ 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();
@ -24,16 +23,6 @@ namespace Kernel
*(uintptr_t*)rsp = (uintptr_t)value; *(uintptr_t*)rsp = (uintptr_t)value;
} }
extern "C" uintptr_t get_thread_start_sp()
{
return Thread::current().interrupt_stack().sp;
}
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)
@ -192,12 +181,6 @@ namespace Kernel
thread->m_interrupt_stack.sp = sp; thread->m_interrupt_stack.sp = sp;
thread->m_interrupt_stack.ss = 0x10; thread->m_interrupt_stack.ss = 0x10;
#if ARCH(x86_64)
thread->m_interrupt_registers.rax = 0;
#elif ARCH(i686)
thread->m_interrupt_registers.eax = 0;
#endif
thread_deleter.disable(); thread_deleter.disable();
return thread; return thread;
@ -214,19 +197,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(kernel_stack_top() - PAGE_SIZE), [&] { PageTable::with_fast_page(process().page_table().physical_address_of(userspace_stack_top() - PAGE_SIZE), [&] {
uintptr_t sp = PageTable::fast_page() + PAGE_SIZE; uintptr_t sp = PageTable::fast_page() + PAGE_SIZE;
write_to_stack(sp, userspace_info.entry); write_to_stack(sp, nullptr);
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 = reinterpret_cast<vaddr_t>(start_userspace_thread);; m_interrupt_stack.ip = userspace_info.entry;
m_interrupt_stack.cs = 0x08; m_interrupt_stack.cs = 0x18 | 3;
m_interrupt_stack.flags = 0x002; m_interrupt_stack.flags = 0x202;
m_interrupt_stack.sp = kernel_stack_top() - 4 * sizeof(uintptr_t); m_interrupt_stack.sp = userspace_stack_top() - 4 * sizeof(uintptr_t);
m_interrupt_stack.ss = 0x10; m_interrupt_stack.ss = 0x20 | 3;
memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters)); memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters));
} }

View File

@ -2,32 +2,31 @@
.global _start .global _start
_start: _start:
# zero out stack frame
pushl $0 pushl $0
pushl %edi pushl $0
pushl %esi movl %esp, %ebp
# FIXME: handle stack alignment
ud2
# push argc, argv, environ for call to main
pushl %edx pushl %edx
pushl %esi
pushl %edi
# STACK LAYOUT # initialize libc
# null pushl %edx
# argc
# argv
# envp
xorl %ebp, %ebp
# init libc (envp already as argument)
call _init_libc call _init_libc
addl $4, %esp
# call global constructors # call global constructos
call _init call _init
# call main # call main, arguments are already on stack
movl 0(%esp), %eax
xchgl %eax, 8(%esp)
movl %eax, (%esp)
call main call main
subl $12, %esp # cleanly exit the process
pushl %eax pushl %eax
call exit call exit

View File

@ -2,11 +2,6 @@
.global _start .global _start
_start: _start:
pushq $0
pushq %rdi
pushq %rsi
pushq %rdx
# STACK LAYOUT # STACK LAYOUT
# null # null
# argc # argc