Kernel: Implement syscalls for i686 and cleanup x86_64

This actually allows i686 to boot properly!
This commit is contained in:
Bananymous 2024-04-03 02:23:23 +03:00
parent 9e073e9fa0
commit 0dd74e3c9d
8 changed files with 120 additions and 48 deletions

View File

@ -1,19 +1,31 @@
.global sys_fork_trampoline .global sys_fork_trampoline
sys_fork_trampoline: sys_fork_trampoline:
ud2
subl $4, %esp
pushl %ebx
pushl %ebp pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
call read_ip call read_ip
testl %eax, %eax testl %eax, %eax
je .done jz .reload_stack
movl %esp, %ebx
subl $8, %esp subl $8, %esp
pushl %eax pushl %eax
pushl %esp pushl %ebx
call sys_fork call sys_fork
addl $16, %esp addl $16, %esp
.done:
popl %ebp .done:
popl %edi
popl %esi
popl %ebx popl %ebx
addl $4, %esp popl %ebp
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_start_kernel_thread_sp call get_thread_start_sp
movl %eax, %esp movl %eax, %esp
# STACK LAYOUT # STACK LAYOUT
@ -32,3 +32,37 @@ 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

@ -24,6 +24,22 @@
popw %gs popw %gs
.endm .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 push_userspace
load_kernel_segments load_kernel_segments
@ -85,11 +101,12 @@ asm_reschedule_handler:
// 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:
ud2 push_userspace
pusha
subl $8, %esp
pushl %esp pushl %esp
addl $36, (%esp) addl $48, (%esp)
pushl %edi pushl %edi
pushl %esi pushl %esi
@ -98,19 +115,12 @@ syscall_asm:
pushl %ebx pushl %ebx
pushl %eax pushl %eax
load_kernel_segments
call cpp_syscall_handler call cpp_syscall_handler
addl $36, %esp
addl $60, %esp pop_userspace_skip_eax
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,13 +6,16 @@ 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 .done je .reload_stack
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
@ -20,3 +23,9 @@ 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_start_kernel_thread_sp call get_thread_start_sp
movq %rax, %rsp movq %rax, %rsp
# STACK LAYOUT # STACK LAYOUT
@ -27,7 +27,7 @@ start_kernel_thread:
.global start_userspace_thread .global start_userspace_thread
start_userspace_thread: start_userspace_thread:
call get_start_kernel_thread_sp call get_thread_start_sp
movq %rax, %rsp movq %rax, %rsp
# STACK LAYOUT # STACK LAYOUT

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((interrupt_stack.cs & 0b11) == 0b11); ASSERT(GDT::is_user_segment(interrupt_stack->cs));
asm volatile("sti"); asm volatile("sti");

View File

@ -24,9 +24,9 @@ namespace Kernel
*(uintptr_t*)rsp = (uintptr_t)value; *(uintptr_t*)rsp = (uintptr_t)value;
} }
extern "C" uintptr_t get_start_kernel_thread_sp() extern "C" uintptr_t get_thread_start_sp()
{ {
return Thread::current().kernel_stack_top() - 4 * sizeof(uintptr_t); return Thread::current().interrupt_stack().sp;
} }
extern "C" uintptr_t get_userspace_thread_stack_top() extern "C" uintptr_t get_userspace_thread_stack_top()
@ -192,6 +192,12 @@ 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;

View File

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