forked from hse-cs-ami/yabloko-public
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproc.c
75 lines (64 loc) · 1.68 KB
/
proc.c
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "elf.h"
#include "proc.h"
#include "fs/fs.h"
#include "cpu/gdt.h"
#include "cpu/isr.h"
#include "lib/mem.h"
#include "lib/string.h"
#include "console.h"
struct context {
// matches the behavior of swtch()
uint32_t edi, esi, ebp, ebx;
uint32_t eip; // return address for swtch()
};
struct kstack {
uint32_t space[400];
struct context context;
registers_t trapframe;
char bottom[];
};
struct task {
struct taskstate tss;
struct kstack stack;
};
struct vm {
void *kernel_thread;
void *user_thread;
struct task *user_task;
} *vm;
void trapret();
void swtch(void** oldstack, void* newstack);
void run_elf(const char* name) {
if (!vm) {
vm = kmalloc(sizeof(struct vm));
vm->user_task = kmalloc(sizeof(struct task));
switchuvm(&vm->user_task->tss, vm->user_task->stack.bottom);
}
if (read_file(name, (void*)USER_BASE, 100 << 20) <= 0) {
printk(name);
printk(": file not found\n");
return;
}
Elf32_Ehdr *hdr = (void*)USER_BASE;
struct kstack *u = &vm->user_task->stack;
memset(u, 0, sizeof(*u));
u->context.eip = (uint32_t)trapret;
registers_t *tf = &u->trapframe;
tf->eip = hdr->e_entry;
tf->cs = (SEG_UCODE << 3) | DPL_USER;
tf->ds = (SEG_UDATA << 3) | DPL_USER;
tf->es = tf->ds;
tf->fs = tf->ds;
tf->gs = tf->ds;
tf->ss = tf->ds;
tf->eflags = FL_IF;
tf->useresp = USER_STACK_BASE;
// initialization done, now switch to the process
swtch(&vm->kernel_thread, &u->context);
// process has finished
}
_Noreturn void killproc() {
void* task_stack;
swtch(&task_stack, vm->kernel_thread);
__builtin_unreachable();
}