kern

annotate src/proc.c @ 51:b1e8c8251884

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