From 7b91cb3f96d7b8ba0874a1b24b19f624e43c99d5 Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Mon, 24 Oct 2016 20:35:17 -0500 Subject: [PATCH] syscalls and a user mode process --- syscall.h | 3 ++ syscalls.s | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 syscall.h create mode 100644 syscalls.s diff --git a/syscall.h b/syscall.h new file mode 100644 index 0000000..04aebb6 --- /dev/null +++ b/syscall.h @@ -0,0 +1,3 @@ +void ksyscall(int call); +void syscall_entry(); +void init_syscalls(void); diff --git a/syscalls.s b/syscalls.s new file mode 100644 index 0000000..2dd2f6a --- /dev/null +++ b/syscalls.s @@ -0,0 +1,125 @@ +global syscall_entry:function +global ksyscall:function + +extern printk +extern allstop +extern need_schedule + +; syscall to kernel +; syscall number in rax +; fourth argument (rcx) on stack? +ksyscall: + ; syscall over-writes rcx, save it + push rcx + syscall + pop rcx + ret + +%define STAR 0xC0000081 +%define LSTAR 0xC0000082 +%define FMASK 0xC0000084 + +extern enable_syscall + +global init_syscalls:function +init_syscalls: + ; STAR register + mov ecx, STAR + rdmsr + mov edx, 0x23 ; user code segment / user data segment / 64 bit user code segment + shr edx, 16 + or edx, 0x10 ; kernel code segment + wrmsr + + ; syscall rip + mov rax, qword syscall_entry + mov rdx, qword syscall_entry + shr rdx, 32 + mov ecx, LSTAR + wrmsr + + ; rflags mask + mov ecx, FMASK + rdmsr + mov eax, ~0x202 + wrmsr + + ; turn on the enable bit (bit 1 of EFER, iirc) + call enable_syscall + ret + +; still using user stack and memory map +; can't use user's stack because user may lie about where it is +; causing us to overwrite memory. + +extern sleep +extern timer_ticks + +syscall_entry: + mov dr0, rcx + mov dr1, rax + mov dr2, rdi + + ; TODO switch to kernel stack + + ; save values for sysret + push r11 + push rcx + mov r10, rcx ; fourth arg in r10, since syscall clobbers rcx + + push rax + push rdi + push rsi + mov r8, rdi + mov r9, rsi + + mov rdi, qword sleepstr + mov rdx, qword timer_ticks + mov rsi, [rdx] + mov edx, 0 + mov ecx, eax + + call printk + pop rsi + pop rdi + pop rax + + call sleep + + ; syscall number in rax + ; rcx would be the fourth argument, but over-written by syscall + ; so we pass it in r10, another scratch register + + ; may not need to check for schedule, the syscall itself + ; should do a yield if it wants to + + ; need to check for schedule, could possible just do + ; an interrupt if it needed scheduling + call need_schedule + mov dr1, rax + ;call allstop + test eax,eax + jz .nosched + mov eax, 0x1123f982 + mov dr0, rax + call allstop + int 0x81 ; force a schedule call, any int would do actually +.nosched: + + mov eax, __LINE__ + mov dr3, rax + mov dr2, r11 + mov dr1, rcx + ;call allstop + + pop rcx + pop r11 + db 0x48 ; no sysretq in yasm + sysret + +ign: +db 'ignoring syscall %u', 0xa, 0 + +sleepstr: + db '%u pid %u syscall %u : %u %u', 0xa, 0 + -- 2.40.0