mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-30 22:18:21 +00:00
system calls
This commit is contained in:
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c)) israsm.o context.o
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c)) israsm.o context.o syscall.o
|
||||
subdirs=boot
|
||||
OBJPATH=$(OBJDIR)/arch/${TARGET}/
|
||||
export
|
||||
@@ -19,3 +19,7 @@ context.o: context.asm
|
||||
nasm -f elf64 -o $@ $<
|
||||
mkdir -p $(OBJPATH)
|
||||
cp $@ $(OBJPATH)/$@
|
||||
syscall.o: syscall.asm
|
||||
nasm -f elf64 -o $@ $<
|
||||
mkdir -p $(OBJPATH)
|
||||
cp $@ $(OBJPATH)/$@
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
global arch_switchcontext
|
||||
arch_switchcontext:
|
||||
mov rsp,rdi
|
||||
add rsp, 8 ; cr2
|
||||
pop rax
|
||||
mov gs,rax
|
||||
pop rax
|
||||
mov fs,rax
|
||||
pop rax
|
||||
add rsp, 24 ; cr2 gs fs
|
||||
|
||||
mov rbx,es
|
||||
pop rax
|
||||
cmp rax,rbx
|
||||
jne .segswap
|
||||
add rsp,8 ; ds
|
||||
jmp .genreg
|
||||
.segswap:
|
||||
swapgs
|
||||
mov es,rax
|
||||
pop rax
|
||||
pop rax
|
||||
mov ds,rax
|
||||
|
||||
.genreg:
|
||||
pop rax
|
||||
pop rbx
|
||||
pop rcx
|
||||
@@ -27,6 +33,4 @@ arch_switchcontext:
|
||||
pop rbp
|
||||
add rsp,8 ; remove error code
|
||||
|
||||
swapgs
|
||||
|
||||
iretq
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
// syscall, sse, etc
|
||||
// for the current cpu
|
||||
|
||||
extern void asm_syscall_entry();
|
||||
|
||||
void cpu_state_init(){
|
||||
|
||||
// syscall
|
||||
@@ -28,7 +30,7 @@ void cpu_state_init(){
|
||||
star |= (uint64_t)0x28 << 32;
|
||||
|
||||
wrmsr(MSR_STAR, star);
|
||||
wrmsr(MSR_LSTAR, 0xDEADBEEF); // FIXME add 64 bit handler here
|
||||
wrmsr(MSR_LSTAR, asm_syscall_entry);
|
||||
wrmsr(MSR_CSTAR, 0); // no compat mode syscall handler
|
||||
wrmsr(MSR_FMASK, 0x200); // disable interrupts on syscall
|
||||
}
|
||||
|
||||
@@ -34,8 +34,10 @@ static void reloadgdtr(){
|
||||
|
||||
gdtr.offset = &arch_getcls()->gdt;
|
||||
gdtr.size = sizeof(gdt_t) - 1;
|
||||
asm("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
|
||||
asm("ltr %%ax" : : "a"(0x48));
|
||||
asm volatile("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
|
||||
asm volatile("ltr %%ax" : : "a"(0x48));
|
||||
asm volatile("swapgs;mov $0, %%ax;mov %%ax, %%gs;mov %%ax, %%fs;swapgs;" : : : "ax");
|
||||
|
||||
}
|
||||
|
||||
void gdt_init(){
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// this will be pointed to by GS and will contain per cpu info
|
||||
|
||||
typedef struct{
|
||||
void* kstack;
|
||||
gdt_t gdt;
|
||||
ist_t ist;
|
||||
int lapicid;
|
||||
|
||||
@@ -4,10 +4,15 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct{
|
||||
uint64_t gsbase, fsbase;
|
||||
} arch_extraregs;
|
||||
|
||||
typedef struct{
|
||||
uint64_t cr2,gs,fs,es,ds,rax,rbx,rcx,rdx,r8,r9,r10,r11,r12,r13,r14,r15,rdi,rsi,rbp,error,rip,cs,rflags,rsp,ss;
|
||||
} arch_regs;
|
||||
|
||||
void arch_regs_saveextra(arch_extraregs* regs);
|
||||
void arch_regs_setupextra(arch_extraregs* regs);
|
||||
void arch_regs_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts);
|
||||
void arch_regs_setupuser(arch_regs* regs, void* ip, void* stack, bool interrupts);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ section .text
|
||||
mov rax, gs
|
||||
push rax
|
||||
|
||||
cmp rax,0x30
|
||||
cmp rax,0x43
|
||||
jmp .noswapgs
|
||||
swapgs
|
||||
.noswapgs:
|
||||
@@ -42,22 +42,18 @@ section .text
|
||||
|
||||
%macro popregs 0
|
||||
|
||||
add rsp, 8 ; cr2
|
||||
|
||||
add rsp, 24 ; cr2 gs fs
|
||||
|
||||
pop rax
|
||||
cmp rax,0x30
|
||||
cmp rax,0x43
|
||||
je .dontpopsegs
|
||||
mov gs,rax
|
||||
pop rax
|
||||
mov fs,rax
|
||||
pop rax
|
||||
mov es,rax
|
||||
pop rax
|
||||
mov ds,rax
|
||||
swapgs
|
||||
jmp .poprest
|
||||
.dontpopsegs:
|
||||
add rsp,24
|
||||
add rsp,8 ; ds
|
||||
|
||||
.poprest:
|
||||
pop rax
|
||||
|
||||
@@ -5,4 +5,5 @@
|
||||
void arch_setkernelstack(void* stack){
|
||||
|
||||
arch_getcls()->ist.rsp0 = (uint64_t)stack;
|
||||
arch_getcls()->kstack = stack;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
#include <arch/regs.h>
|
||||
#include <arch/msr.h>
|
||||
|
||||
void arch_regs_saveextra(arch_extraregs* regs){
|
||||
// user gs was swapped
|
||||
regs->gsbase = rdmsr(MSR_KERNELGSBASE);
|
||||
regs->fsbase = rdmsr(MSR_FSBASE);
|
||||
}
|
||||
|
||||
void arch_regs_setupextra(arch_extraregs* regs){
|
||||
// gs will be swapped later
|
||||
wrmsr(MSR_KERNELGSBASE, regs->gsbase);
|
||||
wrmsr(MSR_FSBASE, regs->fsbase);
|
||||
}
|
||||
|
||||
void arch_regs_setupkernel(arch_regs* regs, void* ip, void* stack, bool interrupts){
|
||||
regs->rip = ip;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
section .rodata
|
||||
|
||||
|
||||
extern syscall_libc_log
|
||||
func_count equ 1
|
||||
|
||||
|
||||
func_table:
|
||||
dq syscall_libc_log
|
||||
|
||||
section .text
|
||||
global asm_syscall_entry
|
||||
|
||||
; the registers for the system call are:
|
||||
; RETURN:
|
||||
; rax -> ret value
|
||||
; rdx -> errno
|
||||
; PARAM:
|
||||
; rax -> func
|
||||
; rdi, rsi, rdx, r10, r8, r9 -> parameters
|
||||
; clobbers: rax, rdx, rcx, r11
|
||||
|
||||
asm_syscall_entry:
|
||||
swapgs
|
||||
|
||||
xchg rsp, [gs:0] ; get new stack
|
||||
push qword [gs:0] ; save old stack
|
||||
mov [gs:0], rsp ; return back the kernel stack
|
||||
add qword [gs:0], 8 ; fix it
|
||||
|
||||
push rcx ; old rip
|
||||
push r11 ; old rflags
|
||||
|
||||
mov r11, 0x30 ; kernel data
|
||||
mov ds, r11
|
||||
mov es, r11
|
||||
|
||||
; save C scratch registers
|
||||
; rax is not saved because it will be the return value
|
||||
; rdx is not saved because it will be the errno value
|
||||
|
||||
push rdi
|
||||
push rsi
|
||||
push rcx
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
|
||||
; system V C abi expects the third param to be in rcx
|
||||
; but the param is in rdx because of the syscall instruction
|
||||
|
||||
mov rcx, rdx
|
||||
|
||||
call [func_table + rax * 8]
|
||||
|
||||
; now restore the scratch registers
|
||||
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rcx
|
||||
pop rsi
|
||||
pop rdi
|
||||
|
||||
; restore entry state
|
||||
|
||||
mov r11, 0x40 ; user data
|
||||
mov es,r11
|
||||
mov ds,r11
|
||||
|
||||
pop r11
|
||||
pop rcx
|
||||
pop rsp
|
||||
swapgs
|
||||
|
||||
o64 sysret
|
||||
@@ -23,6 +23,7 @@ typedef struct _thread_t{
|
||||
struct _thread_t* prev;
|
||||
struct _proc_t* proc;
|
||||
arch_regs* regs;
|
||||
arch_extraregs extraregs;
|
||||
state_t state;
|
||||
void* kernelstack;
|
||||
void* kernelstackbase;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef _SYSCALLS_H_INCLUDE
|
||||
#define _SYSCALLS_H_INCLUDE
|
||||
|
||||
typedef struct {
|
||||
long ret;
|
||||
long errno;
|
||||
} syscallret;
|
||||
|
||||
syscallret syscall_libc_log(char* str);
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
subdirs := mm sched
|
||||
subdirs := mm sched syscalls
|
||||
OBJPATH=$(OBJDIR)
|
||||
export
|
||||
|
||||
|
||||
@@ -162,9 +162,9 @@ void sched_timerhook(arch_regs* regs){
|
||||
|
||||
spinlock_release(&running.lock);
|
||||
|
||||
|
||||
|
||||
memcpy(current->regs, regs, sizeof(arch_regs));
|
||||
|
||||
arch_regs_saveextra(¤t->extraregs);
|
||||
|
||||
spinlock_acquire(¤tqueue->lock);
|
||||
|
||||
@@ -198,6 +198,8 @@ static void switch_thread(thread_t* thread){
|
||||
|
||||
arch_setkernelstack(thread->kernelstack);
|
||||
|
||||
arch_regs_setupextra(&thread->extraregs);
|
||||
|
||||
arch_switchcontext(thread->regs);
|
||||
|
||||
__builtin_unreachable();
|
||||
@@ -291,6 +293,8 @@ void sched_runinit(){
|
||||
printf("ELF load error: %s\n", strerror(ret));
|
||||
_panic("Could not load init", 0);
|
||||
}
|
||||
|
||||
thread->extraregs.gsbase = 0xFFFFFFFFDEADBEEF;
|
||||
|
||||
switch_thread(thread);
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
subdirs :=
|
||||
OBJPATH=$(OBJDIR)
|
||||
export
|
||||
|
||||
all: $(subdirs) $(objects)
|
||||
for subdir in $(subdirs) ; do $(MAKE) -C $${subdir} ; done
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
mkdir -p $(OBJPATH)
|
||||
cp $@ $(OBJPATH)/$@
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
syscallret syscall_libc_log(char* str){
|
||||
|
||||
syscallret ret;
|
||||
|
||||
char* buf = alloc(strlen(str) + 1);
|
||||
if(!buf){
|
||||
ret.errno = ENOMEM;
|
||||
ret.ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
strcpy(buf, str);
|
||||
|
||||
printf("%s", str);
|
||||
|
||||
ret.errno = 0;
|
||||
ret.ret = 0;
|
||||
|
||||
free(buf);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user