diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c new file mode 100644 index 0000000..eadbedb --- /dev/null +++ b/kernel/amd64/proc.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include + +struct proc* proc_from_elf (uint8_t* elf_contents) { + struct proc* proc = malloc (sizeof (*proc)); + if (proc == NULL) + return NULL; + + memset (proc, 0, sizeof (*proc)); + + proc->pd.lock = SPIN_LOCK_INIT; + proc->pd.cr3_paddr = mm_alloc_user_pd_phys (); + if (proc->pd.cr3_paddr == 0) { + free (proc); + return NULL; + } + + proc->pdata.syscall_stack = pmm_alloc (KSTACK_SIZE / PAGE_SIZE); + if (proc->pdata.syscall_stack == PMM_ALLOC_ERR) { + free (proc); + return NULL; + } + + proc->pdata.user_stack = pmm_alloc (USTACK_SIZE / PAGE_SIZE); + if (proc->pdata.user_stack == PMM_ALLOC_ERR) { + free (proc); + pmm_free (proc->pdata.syscall_stack, USTACK_SIZE / PAGE_SIZE); + return NULL; + } + + uintptr_t user_stack = proc->pdata.user_stack; + + proc->pdata.syscall_stack += KSTACK_SIZE; + proc->pdata.user_stack += USTACK_SIZE; + + proc_map (proc, user_stack, PROC_USTACK_TOP - USTACK_SIZE, USTACK_SIZE / PAGE_SIZE, + MM_PG_USER | MM_PG_PRESENT | MM_PG_RW); + + struct elf_aux aux = proc_load_segments (proc, elf_contents); + + proc->pdata.regs.ss = 0x20 | 0x03; + proc->pdata.regs.rsp = (uint64_t)PROC_USTACK_TOP; + proc->pdata.regs.rflags = 0x202; + proc->pdata.regs.cs = 0x18 | 0x03; + proc->pdata.regs.rip = aux.entry; + proc->lock = SPIN_LOCK_INIT; + atomic_store (&proc->state, PROC_READY); + + return proc; +} diff --git a/kernel/amd64/src.mk b/kernel/amd64/src.mk index dcd2074..17a6e03 100644 --- a/kernel/amd64/src.mk +++ b/kernel/amd64/src.mk @@ -10,7 +10,8 @@ c += amd64/bootmain.c \ amd64/mm.c \ amd64/time.c \ amd64/smp.c \ - amd64/sched1.c + amd64/sched1.c \ + amd64/proc.c S += amd64/intr_stub.S \ amd64/spin.S \ @@ -31,4 +32,5 @@ o += amd64/bootmain.o \ amd64/time.o \ amd64/smp.o \ amd64/sched.o \ - amd64/sched1.o + amd64/sched1.o \ + amd64/proc.o diff --git a/kernel/aux/elf.h b/kernel/aux/elf.h index 00957ea..75c3b25 100644 --- a/kernel/aux/elf.h +++ b/kernel/aux/elf.h @@ -4545,4 +4545,11 @@ enum { #define R_OR1K_TLS_DTPOFF 33 #define R_OR1K_TLS_DTPMOD 34 +struct elf_aux { + uint64_t entry; + uint64_t phdr; + uint64_t phent; + uint64_t phnum; +}; + #endif // _KERNELAUX_ELF_H diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 8b6e84c..a7706b9 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -15,20 +15,13 @@ #include #include #include +#include +#include #if defined(__x86_64__) #include - #include - #include #endif -struct elf_aux { - uint64_t entry; - uint64_t phdr; - uint64_t phent; - uint64_t phnum; -}; - static struct procw* procs; static spin_lock_t procs_lock = SPIN_LOCK_INIT; @@ -59,7 +52,7 @@ void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, spin_unlock (&proc->pd.lock); } -static struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) { +struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) { struct elf_aux aux; Elf64_Ehdr* ehdr = (Elf64_Ehdr*)elf; @@ -112,53 +105,7 @@ static struct proc* proc_spawn_rd (char* name) { if (!ok) return NULL; - struct proc* proc = malloc (sizeof (*proc)); - if (proc == NULL) - return NULL; - - memset (proc, 0, sizeof (*proc)); - -#if defined(__x86_64__) - proc->pd.lock = SPIN_LOCK_INIT; - proc->pd.cr3_paddr = mm_alloc_user_pd_phys (); - if (proc->pd.cr3_paddr == 0) { - free (proc); - return NULL; - } - - proc->pdata.syscall_stack = pmm_alloc (KSTACK_SIZE / PAGE_SIZE); - if (proc->pdata.syscall_stack == PMM_ALLOC_ERR) { - free (proc); - return NULL; - } - - proc->pdata.user_stack = pmm_alloc (USTACK_SIZE / PAGE_SIZE); - if (proc->pdata.user_stack == PMM_ALLOC_ERR) { - free (proc); - pmm_free (proc->pdata.syscall_stack, USTACK_SIZE / PAGE_SIZE); - return NULL; - } - - uintptr_t user_stack = proc->pdata.user_stack; - - proc->pdata.syscall_stack += KSTACK_SIZE; - proc->pdata.user_stack += USTACK_SIZE; - - proc_map (proc, user_stack, PROC_USTACK_TOP - USTACK_SIZE, USTACK_SIZE / PAGE_SIZE, - MM_PG_USER | MM_PG_PRESENT | MM_PG_RW); - - struct elf_aux aux = proc_load_segments (proc, rd_file->content); - - proc->pdata.regs.ss = 0x20 | 0x03; - proc->pdata.regs.rsp = (uint64_t)PROC_USTACK_TOP; - proc->pdata.regs.rflags = 0x202; - proc->pdata.regs.cs = 0x18 | 0x03; - proc->pdata.regs.rip = aux.entry; - proc->lock = SPIN_LOCK_INIT; - atomic_store (&proc->state, PROC_READY); -#endif - - return proc; + return proc_from_elf (rd_file->content); } static void proc_register (struct proc* proc) { @@ -228,11 +175,7 @@ void proc_sched (void) { } idle: -#if defined(__x86_64__) - extern void amd64_spin (void); - - amd64_spin (); -#endif + spin (); } void proc_kill (struct proc* proc) { diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index 2a8f370..f136d68 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -2,6 +2,7 @@ #define _KERNEL_PROC_PROC_H #include +#include #include #include #include @@ -51,6 +52,9 @@ struct procw { void proc_sched (void); void proc_kill (struct proc* proc); +void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages, + uint32_t flags); +struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf); void proc_init (void); #endif // _KERNEL_PROC_PROC_H diff --git a/kernel/sys/proc.h b/kernel/sys/proc.h new file mode 100644 index 0000000..60398bf --- /dev/null +++ b/kernel/sys/proc.h @@ -0,0 +1,8 @@ +#ifndef _KERNEL_SYS_PROC_H +#define _KERNEL_SYS_PROC_H + +struct proc; + +struct proc* proc_from_elf (uint8_t* elf_contents); + +#endif // _KERNEL_SYS_PROC_H diff --git a/kernel/sys/spin.h b/kernel/sys/spin.h new file mode 100644 index 0000000..8447091 --- /dev/null +++ b/kernel/sys/spin.h @@ -0,0 +1,9 @@ +#ifndef _KERNEL_SYS_SPIN_H +#define _KERNEL_SYS_SPIN_H + +#if defined(__x86_64__) + extern void amd64_spin (void); + #define spin amd64_spin +#endif + +#endif // _KERNEL_SYS_SPIN_H