kern
view src/proc.c @ 53:23abbeea4d5f
llalallalala
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 08 Aug 2011 09:53:10 +0300 |
parents | fa65b4f45366 |
children | 4eaecb14fe31 |
line source
1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4 #include "proc.h"
5 #include "tss.h"
6 #include "vm.h"
7 #include "segm.h"
8 #include "intr.h"
9 #include "panic.h"
10 #include "syscall.h"
11 #include "sched.h"
13 #define FLAGS_INTR_BIT 9
15 /* defined in test_proc.S */
16 void test_proc(void);
17 void test_proc_end(void);
19 static struct process proc[MAX_PROC];
20 static int cur_pid;
22 void init_proc(void)
23 {
24 int proc_size_pg, img_start_pg, stack_pg;
25 void *img_start;
26 cur_pid = 0;
28 init_syscall();
30 /* prepare the first process */
31 proc[1].id = 1;
32 proc[1].parent = 0;
34 /* allocate a chunk of memory for the process image
35 * and copy the code of test_proc there.
36 * (should be mapped at a fixed address)
37 */
38 proc_size_pg = (test_proc_end - test_proc) / PGSIZE + 1;
39 if((img_start_pg = pgalloc(proc_size_pg, MEM_USER)) == -1) {
40 panic("failed to allocate space for the init process image\n");
41 }
42 img_start = (void*)PAGE_TO_ADDR(img_start_pg);
43 memcpy(img_start, test_proc, proc_size_pg * PGSIZE);
45 printf("copied init process at: %x\n", (unsigned int)img_start);
47 /* instruction pointer at the beginning of the process image */
48 proc[1].ctx.instr_ptr = (uint32_t)img_start;
50 /* allocate the first page of the process stack */
51 stack_pg = ADDR_TO_PAGE(KMEM_START) - 1;
52 if(pgalloc_vrange(stack_pg, 1) == -1) {
53 panic("failed to allocate user stack page\n");
54 }
55 proc[1].ctx.stack_ptr = PAGE_TO_ADDR(stack_pg) + PGSIZE;
56 proc[1].stack_start_pg = stack_pg;
58 /* create the virtual address space for this process */
59 /*proc[1].ctx.pgtbl_paddr = clone_vm();*/
61 /* we don't need the image and the stack in this address space */
62 /*unmap_page_range(img_start_pg, proc_size_pg);
63 pgfree(img_start_pg, proc_size_pg);
65 unmap_page(stack_pg);
66 pgfree(stack_pg, 1);*/
68 /* add it to the scheduler queues */
69 add_proc(1, STATE_RUNNABLE);
71 /* switch to the initial process, this never returns */
72 context_switch(1);
73 }
76 void context_switch(int pid)
77 {
78 struct context *ctx;
79 struct intr_frame ifrm;
80 struct intr_frame *cur_frame = get_intr_frame();
82 assert(0);
84 if(cur_pid == pid) {
85 assert(cur_frame);
86 intr_ret(*cur_frame);
87 }
89 ctx = &proc[pid].ctx;
90 cur_pid = pid;
92 ifrm.inum = ifrm.err = 0;
94 ifrm.regs = ctx->regs;
95 ifrm.eflags = ctx->flags | (1 << FLAGS_INTR_BIT);
97 ifrm.eip = ctx->instr_ptr;
98 ifrm.cs = selector(SEGM_KCODE, 0); /* XXX change this when we setup the TSS */
99 /*ifrm.regs.esp = ctx->stack_ptr;*/ /* ... until then... */
100 ifrm.esp = ctx->stack_ptr; /* this will only be used when we switch to userspace */
101 ifrm.ss = selector(SEGM_KDATA, 0);
103 /* switch to the vm of the process */
104 set_pgdir_addr(ctx->pgtbl_paddr);
105 intr_ret(ifrm);
106 }
108 int get_current_pid(void)
109 {
110 return cur_pid;
111 }
113 struct process *get_current_proc(void)
114 {
115 return cur_pid ? &proc[cur_pid] : 0;
116 }
118 struct process *get_process(int pid)
119 {
120 return &proc[pid];
121 }