summaryrefslogtreecommitdiff
path: root/src/kernel/proc.c
blob: b165878f5ac2ce6620086ea00629c5f4a06b0aec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <kernel/arch/generic.h>
#include <kernel/mem.h>
#include <kernel/proc.h>
#include <kernel/util.h>
#include <stdint.h>

struct process *process_current;

struct process *process_new() {
	struct process *proc = page_alloc(1); // TODO kmalloc
	proc->pages = pagedir_new();

	// map the stack to the last page in memory
	pagedir_map(proc->pages, (void*)~PAGE_MASK, page_alloc(1), true, true);
	proc->stack_top = proc->regs.esp = ~0xF;

	// map the kernel
	//   yup, .text is writeable too. the plan is to not map the kernel
	//   into user memory at all, but i'll implement that later. TODO
	for (size_t p = 0x100000; p < (size_t)&_bss_end; p += PAGE_SIZE)
		pagedir_map(proc->pages, (void*)p, (void*)p, false, true);

	// the kernel still has to load the executable code and set EIP
	return proc;
}

struct process *process_clone(const struct process *orig) {
	struct process *clone = page_alloc(1);
	memcpy(clone, orig, sizeof(struct process));
	clone->pages = pagedir_copy(orig->pages);

	return clone;
}

void process_switch(struct process *proc) {
	process_current = proc;
	pagedir_switch(proc->pages);
	sysexit(proc->regs);
}