Free user VM.
This commit is contained in:
parent
117f6423c4
commit
e8845b5012
@ -7,6 +7,9 @@
|
|||||||
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
|
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
|
||||||
#define PGROUNDDOWN(a) (((a)) & ~((uintptr_t)(PGSIZE-1)))
|
#define PGROUNDDOWN(a) (((a)) & ~((uintptr_t)(PGSIZE-1)))
|
||||||
|
|
||||||
|
#define NPDENTRIES 1024 // # directory entries per page directory
|
||||||
|
#define NPTENTRIES 1024 // # PTEs per page table
|
||||||
|
|
||||||
#define PTXSHIFT 12 // offset of PTX in a linear address
|
#define PTXSHIFT 12 // offset of PTX in a linear address
|
||||||
#define PDXSHIFT 22 // offset of PDX in a linear address
|
#define PDXSHIFT 22 // offset of PDX in a linear address
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ memset(void *dst, unsigned c, uint64_t n)
|
|||||||
// call to kalloc(). (The exception is when
|
// call to kalloc(). (The exception is when
|
||||||
// initializing the allocator; see kinit above.)
|
// initializing the allocator; see kinit above.)
|
||||||
void
|
void
|
||||||
kfree(char *v)
|
kfree(void *v)
|
||||||
{
|
{
|
||||||
struct run *r;
|
struct run *r;
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ kfree(char *v)
|
|||||||
// Fill with junk to catch dangling refs.
|
// Fill with junk to catch dangling refs.
|
||||||
memset(v, 1, PGSIZE);
|
memset(v, 1, PGSIZE);
|
||||||
|
|
||||||
r = (struct run*)v;
|
r = v;
|
||||||
r->next = kmem.freelist;
|
r->next = kmem.freelist;
|
||||||
kmem.freelist = r;
|
kmem.freelist = r;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,9 +9,10 @@ void* memset(void *dst, unsigned c, uint64_t n);
|
|||||||
|
|
||||||
void freerange(void *vstart, void *vend);
|
void freerange(void *vstart, void *vend);
|
||||||
void* kalloc(void);
|
void* kalloc(void);
|
||||||
void kfree(char*);
|
void kfree(void*);
|
||||||
|
|
||||||
pde_t *setupkvm();
|
pde_t *setupkvm();
|
||||||
void kvmalloc();
|
void kvmalloc();
|
||||||
void switchkvm();
|
void switchkvm();
|
||||||
int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top);
|
int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top);
|
||||||
|
void freevm(pde_t *pgdir);
|
||||||
|
|||||||
18
kernel/vm.c
18
kernel/vm.c
@ -92,3 +92,21 @@ int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void freept(pte_t *pt) {
|
||||||
|
for (int i = 0; i < NPTENTRIES; i++) {
|
||||||
|
if (pt[i] & PTE_P) {
|
||||||
|
kfree((char*)P2V(PTE_ADDR(pt[i])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kfree((char*)pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freevm(pde_t *pgdir) {
|
||||||
|
for (int i = 0; i < NPDENTRIES / 2; i++) {
|
||||||
|
if (pgdir[i] & PTE_P) {
|
||||||
|
freept((pte_t*)P2V(PTE_ADDR(pgdir[i])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kfree(pgdir);
|
||||||
|
}
|
||||||
|
|||||||
4
proc.c
4
proc.c
@ -44,11 +44,12 @@ void run_elf(const char* name) {
|
|||||||
}
|
}
|
||||||
if (!vm.user_task) {
|
if (!vm.user_task) {
|
||||||
vm.user_task = kalloc();
|
vm.user_task = kalloc();
|
||||||
|
}
|
||||||
vm.user_task->pgdir = setupkvm();
|
vm.user_task->pgdir = setupkvm();
|
||||||
allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size);
|
allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size);
|
||||||
allocuvm(vm.user_task->pgdir, USER_STACK_BASE - 2 * PGSIZE, USER_STACK_BASE);
|
allocuvm(vm.user_task->pgdir, USER_STACK_BASE - 2 * PGSIZE, USER_STACK_BASE);
|
||||||
switchuvm(&vm.user_task->tss, vm.user_task->stack.bottom, vm.user_task->pgdir);
|
switchuvm(&vm.user_task->tss, vm.user_task->stack.bottom, vm.user_task->pgdir);
|
||||||
}
|
|
||||||
if (read_file(&statbuf, (void*)USER_BASE, 100 << 20) <= 0) {
|
if (read_file(&statbuf, (void*)USER_BASE, 100 << 20) <= 0) {
|
||||||
printk(name);
|
printk(name);
|
||||||
printk(": file not found\n");
|
printk(": file not found\n");
|
||||||
@ -80,6 +81,7 @@ void run_elf(const char* name) {
|
|||||||
_Noreturn void killproc() {
|
_Noreturn void killproc() {
|
||||||
void* task_stack;
|
void* task_stack;
|
||||||
switchkvm();
|
switchkvm();
|
||||||
|
freevm(vm.user_task->pgdir);
|
||||||
swtch(&task_stack, vm.kernel_thread);
|
swtch(&task_stack, vm.kernel_thread);
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user