From 44118c4a81f03a3a88b17955ee4da3f260525d79 Mon Sep 17 00:00:00 2001 From: lirong <lirongleiyan@163.com> Date: Tue, 9 May 2023 16:43:02 +0000 Subject: [PATCH] alloc_PCB --- kernel.c | 3 +- memlayout.h | 14 ++++++--- memory.c | 28 ++++++++++++++++-- memory.h | 2 +- process.c | 83 +++++++++++++++++++++++++++++++++++++++++------------ process.h | 9 +++--- riscv.h | 3 +- trap.c | 1 + vm.c | 3 +- vm.h | 4 +++ 10 files changed, 116 insertions(+), 34 deletions(-) diff --git a/kernel.c b/kernel.c index 446fd06..8ae7c15 100644 --- a/kernel.c +++ b/kernel.c @@ -35,7 +35,8 @@ void Kernel_Init(uint64_t hartid) boot_flag = true; wake_other_hart(hartid); printf("hartid:%d, pid:%d, this is idle\n", hartid, myPCB()->pid); - //printf("clock init\n"); + struct PCB *p = alloc_PCB(); + printf("pid of alloc_PCB:%d\n", p->pid); clock_init(); // è¿™å—以åŽé›†æˆä¸€ä¸ªtrap_init() //Test panic("Test"); diff --git a/memlayout.h b/memlayout.h index f6e3498..dab8de7 100644 --- a/memlayout.h +++ b/memlayout.h @@ -7,12 +7,18 @@ #define MEM_MAX_SIZE 128 // 128M ram #define PA_MAX (SBI_ENRTY+ 128*1024*1024) #define KERNEL_ENTRY 0X80200000L // å†…æ ¸å…¥å£ -#define KERNEL_STACK_SIZE (1<<13) // æ¯ä¸ªhart分é…8kbçš„å†…æ ¸æ ˆ -#define KERNEL_STACK_SIZE_SHIFT 13 // 1<<13 åŒä¸Š +#define KERNEL_STACK_SIZE (1<<12) // æ¯ä¸ªhart分é…4kbçš„å†…æ ¸æ ˆ +#define KERNEL_STACK_SIZE_SHIFT 12 // 1<<12 åŒä¸Š #define PYHSTOP (SBI_ENRTY+MEM_MAX_SIZE*1024*1024) // dramä¸Šé™ -#define PAGE_SIZE (1<<12) //ä¸€é¡µçš„å¤§å° 4K -#define PAGE_SIZE_SHIFT 12 +#define PGSIZE (1<<12) //ä¸€é¡µçš„å¤§å° 4K +#define PGSIZE_SHIFT 12 + +#define TRAMPOLINE (MAXVA - PGSIZE) // 蹦床 用于用户æ€è¿›ç¨‹é™·å…¥å†…æ ¸æ€ + +// map kernel stacks beneath the trampoline, +// each surrounded by invalid guard pages. +#define KSTACK(p) (TRAMPOLINE - ((p)+1)* 2*PGSIZE) // 使用了 xv6 kernel/memlayout.h // qemu -machine virt diff --git a/memory.c b/memory.c index be74a78..46374fc 100644 --- a/memory.c +++ b/memory.c @@ -19,7 +19,8 @@ struct{ }kmem; /* - * @brief + * @brief 将物ç†é¡µé‡Šæ”¾ + * @param pa 物ç†åœ°å€ï¼Œå¿…é¡»é¡µå¯¹é½ */ void memfree(uint64_t pa){ struct run *r; @@ -54,7 +55,7 @@ void init_mem(){ } /* - * @brief 分é…页,è¿”å›žçš„å®žé™…åœ°å€ + * @brief 分é…实页,返回其物ç†åœ°å€ * @retval return pyshical address of page or 0 if failed */ void* alloc_page(){ @@ -66,7 +67,28 @@ void* alloc_page(){ // panic() mark return 0; } - kmem.freelist = r ->next; + kmem.freelist = r->next; release_lock(&kmem.mem_lock); return (void*)r; } + +/* + * @brief 分é…连ç»çš„né¡µå†…å˜ +*/ +void* alloc_npages(int32_t n){ + if(n < 1) return NULL; + struct run *last, *start; + int i; + acquire_lock(&kmem.mem_lock); + start = last = kmem.freelist; + for(i = 0; i < n; i++){ + if(last == NULL){ + printf("error: no free memory!\n"); + return 0; + } + last = last->next; + } + kmem.freelist = last; + release_lock(&kmem.mem_lock); + return (void*)start; +} diff --git a/memory.h b/memory.h index 910a2b0..20c6041 100644 --- a/memory.h +++ b/memory.h @@ -5,5 +5,5 @@ void init_mem(); void* alloc_page(); void memfree(uint64_t pa); - +void* alloc_npages(int32_t n); #endif \ No newline at end of file diff --git a/process.c b/process.c index b7cd246..52131e8 100644 --- a/process.c +++ b/process.c @@ -5,9 +5,16 @@ #include "register.h" #include "stdio.h" #include "hart.h" +#include "memory.h" +#include "memlayout.h" +#include "string.h" extern uint64_t KernelStack_start; //定义在 struct PCB PCBs[MAX_PROC_NUM]; +struct spinlock pid_lock; +int32_t next_pid = 1; + +pgtable_t alloc_pgtable(); /* * @brief 将所有pcbåˆå§‹åŒ– @@ -19,6 +26,7 @@ void init_proc(){ init_lock(&(p->lock), "pcb_lock"); PCBs[i].state = UNUSED; } + init_lock(&pid_lock, "pid_lock"); } /* @@ -34,13 +42,15 @@ void init_hart_idle(uint64_t hartid){ p->parent = NULL; p->pagetable = (pte_t*)r_satp(); // 这个感觉好åƒä¸éœ€è¦ p->state = RUNNABLE; - p->kstack = (void*)(KernelStack_start + hartid*KERNEL_STACK_SIZE); //guard page以åŽå†åŠ å§ mark + p->kstack = (KernelStack_start + hartid*KERNEL_STACK_SIZE); //guard page以åŽå†åŠ å§ mark // å°†pcbä¿¡æ¯å†™å…¥åˆ°å½“å‰hart上 push_interrupt(); myhart()->proc = p; pop_interrupt(); + // 修改sp寄å˜å™¨ç‰ mark process_running(); + printf("hartid %d :init_hart_idle\n", hartid); } @@ -49,24 +59,47 @@ void init_hart_idle(uint64_t hartid){ * @retval 如果失败,返回0,å¦åˆ™è¿”回PCB指针 * @note å‰KERNEL_MAX_NUM个PCB始终被idleå 用 */ +struct PCB* alloc_PCB(void){ + struct PCB *p; + for(int i = KERNEL_MAX_NUM; i < MAX_PROC_NUM; i++){ + p = &PCBs[i]; + if(p->state == UNUSED){ + if(init_PCB(p) == false) return NULL; + return p; + } + } + return NULL; +} + +bool init_PCB(struct PCB* p ){ + acquire_lock(&p->lock); + p->state = SLEEPING; + if((p->pid = alloc_pid()) < 1){ + return false; + } + p->parent = NULL; + p->runtime = 0; + p->size_of_memory = 0; + p->pagetable = alloc_pgtable(); + p->kstack = KSTACK((int) (p - PCBs)); + p->name = NULL; -// static struct PCB* alloc_PCB(void){ -// struct PCB *p; -// for(int i = KERNEL_MAX_NUM; i < MAX_PROC_NUM; i++){ -// p = &PCBs[i]; -// if(p->state == UNUSED){ -// acquire_lock(&p->lock); -// p->state = SLEEPING; -// p->pid = -1; -// p->parent = NULL; -// p->runtime = 0; -// p->size_of_memory = 0; -// p->pagetable = NULL; -// p->kstack = NULL; -// p->name = NULL; -// } -// } -// } + // p->trapframe.ra mark + p->trapframe.sp = p->kstack + PGSIZE; + return true; +} + +/* + * @brief 分é…一个pid +*/ +int32_t alloc_pid(){ + int32_t pid; + acquire_lock(&pid_lock); + pid = next_pid; + next_pid++; + release_lock(&pid_lock); + return pid; +} struct PCB* myPCB(){ push_interrupt(); @@ -74,4 +107,18 @@ struct PCB* myPCB(){ pop_interrupt(); return p; } +/* + * @brief 为进程分é…ä¸€å¼ é¡µè¡¨ +*/ +pgtable_t alloc_pgtable(){ + pgtable_t pg; + pg = (pgtable_t)alloc_page(); + if(pg == 0) return 0; + memset(pg, 0, PGSIZE); + + // if(map_pages(pg, TRAMPOLINE, PGSIZE, trampoline, PTE_R | PTE_X) == false){ + // return 0; + // } mark å°†è¹¦åºŠæ˜ å°„ + return pg; +} diff --git a/process.h b/process.h index 25f8460..468cd68 100644 --- a/process.h +++ b/process.h @@ -78,7 +78,7 @@ enum process_state{ struct PCB{ uint32_t pid; uint32_t priority; //进程优先级 - struct trapframe *trapframe; //trap帧 ç”¨äºŽé™·å…¥å†…æ ¸æ€ + struct trapframe trapframe; //trap帧 ç”¨äºŽé™·å…¥å†…æ ¸æ€ struct context context; //上下文 struct spinlock lock; enum process_state state; //è¿›ç¨‹çŠ¶æ€ @@ -86,14 +86,15 @@ struct PCB{ uint64_t runtime; //è¿è¡Œæ—¶é—´ uint64_t size_of_memory; //内å˜ç©ºé—´å¤§å° pgtable_t pagetable; //用户æ€ä¸‹çš„è¿›ç¨‹é¡µè¡¨ï¼Œè¿›ç¨‹é™·å…¥å†…æ ¸æ€åŽå¼‚常处ç†ç‰å¯èƒ½éœ€è¦ä½¿ç”¨ - void* kstack; //å†…æ ¸æ ˆ + uint64_t kstack; //å†…æ ¸æ ˆ char* name; //debug用 }; void init_proc(); void init_hart_idle(uint64_t hartid); -struct PCB* alloc_proc(); +struct PCB* alloc_PCB(void); void free_proc(struct PCB *pro); struct PCB* myPCB(); - +bool init_PCB(struct PCB* p ); +int32_t alloc_pid(); #endif \ No newline at end of file diff --git a/riscv.h b/riscv.h index 7893dbc..083a01f 100644 --- a/riscv.h +++ b/riscv.h @@ -12,8 +12,7 @@ #define SSTATUS_UIE (1L << 0) // User Interrupt Enable #define SIE_STIE (1L << 5) // SIE 寄å˜å™¨ timer -#define PGSIZE 4096 // 页表长度 -#define PGSHIFT 12 +#define MAXVA (1L << 38) // æœ€å¤§è™šæ‹Ÿåœ°å€ #define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) diff --git a/trap.c b/trap.c index 687ea7f..9d12b6e 100644 --- a/trap.c +++ b/trap.c @@ -114,6 +114,7 @@ void exception_handler(){ case Load_page_fault: // mark åŠ è½½é¡µé”™è¯¯ printf("Load page fault\n"); + panic("1"); break; case Store_or_AMO_page_fault: printf("Store/AMO page fault\n"); diff --git a/vm.c b/vm.c index 4753c11..7b2561c 100644 --- a/vm.c +++ b/vm.c @@ -16,7 +16,7 @@ void init_kernelvm(){ if(kernel_pagetable == 0){ panic("init_kernelvm failed"); } - memset(kernel_pagetable, 0, PAGE_SIZE); + memset(kernel_pagetable, 0, PGSIZE); /* // uart registers @@ -55,6 +55,7 @@ void init_hart_vm(){ * @param size å¤§å° * @param pa 物ç†åœ°å€ * @param perm pteçš„æ ‡å¿—ä½ + * @retval flase or true */ bool map_pages(pgtable_t pagetable, uint64_t va, uint64_t size, uint64_t pa, int perm){ if(size == 0) diff --git a/vm.h b/vm.h index 08a3fe4..8cc16b1 100644 --- a/vm.h +++ b/vm.h @@ -15,4 +15,8 @@ static inline void sfence_vma(){ asm volatile("sfence.vma zero, zero"); } void init_hart_vm(); + +pgtable_t alloc_user_pgtable(); +pgtable_t alloc_kernel_pgtable(); +// pgtable_t alloc_pgtable(); #endif \ No newline at end of file -- GitLab