Free user VM.

This commit is contained in:
Alexander Myltsev 2025-01-18 02:38:44 +04:00
parent 117f6423c4
commit e8845b5012
5 changed files with 31 additions and 7 deletions

View File

@ -7,6 +7,9 @@
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(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 PDXSHIFT 22 // offset of PDX in a linear address

View File

@ -41,7 +41,7 @@ memset(void *dst, unsigned c, uint64_t n)
// call to kalloc(). (The exception is when
// initializing the allocator; see kinit above.)
void
kfree(char *v)
kfree(void *v)
{
struct run *r;
@ -51,7 +51,7 @@ kfree(char *v)
// Fill with junk to catch dangling refs.
memset(v, 1, PGSIZE);
r = (struct run*)v;
r = v;
r->next = kmem.freelist;
kmem.freelist = r;
}

View File

@ -9,9 +9,10 @@ void* memset(void *dst, unsigned c, uint64_t n);
void freerange(void *vstart, void *vend);
void* kalloc(void);
void kfree(char*);
void kfree(void*);
pde_t *setupkvm();
void kvmalloc();
void switchkvm();
int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top);
void freevm(pde_t *pgdir);

View File

@ -92,3 +92,21 @@ int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top) {
}
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);
}

10
proc.c
View File

@ -44,11 +44,12 @@ void run_elf(const char* name) {
}
if (!vm.user_task) {
vm.user_task = kalloc();
vm.user_task->pgdir = setupkvm();
allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size);
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);
}
vm.user_task->pgdir = setupkvm();
allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size);
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);
if (read_file(&statbuf, (void*)USER_BASE, 100 << 20) <= 0) {
printk(name);
printk(": file not found\n");
@ -80,6 +81,7 @@ void run_elf(const char* name) {
_Noreturn void killproc() {
void* task_stack;
switchkvm();
freevm(vm.user_task->pgdir);
swtch(&task_stack, vm.kernel_thread);
__builtin_unreachable();
}