From 6ddb762c7a7fe06096ccf344b7b15be4e035b0dd Mon Sep 17 00:00:00 2001 From: David Devecsery Date: Mon, 18 May 2020 13:35:48 -0400 Subject: [PATCH] Consolidated PHYSTOP operations, made it a little bit easier to define a dynamic phys_top --- kernel/include/defs.h | 4 ++-- kernel/src/kalloc.c | 11 +++++++++-- kernel/src/main.c | 4 ++-- kernel/src/vm.c | 21 ++++++++++++++++----- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/kernel/include/defs.h b/kernel/include/defs.h index f1f20fd..85c8636 100644 --- a/kernel/include/defs.h +++ b/kernel/include/defs.h @@ -67,7 +67,7 @@ void ioapicinit(void); char* kalloc(void); void kfree(char*); void kinit1(void*, void*); -void kinit2(void*, void*); +void kinit2(void*, void*, uint); // kbd.c void kbdintr(void); @@ -163,7 +163,7 @@ void uartputc(int); // vm.c void seginit(void); -void kvmalloc(void); +void kvmalloc(uint); pde_t* setupkvm(void); char* uva2ka(pde_t*, char*); int allocuvm(pde_t*, uint, uint); diff --git a/kernel/src/kalloc.c b/kernel/src/kalloc.c index 45f0aef..76c8f18 100644 --- a/kernel/src/kalloc.c +++ b/kernel/src/kalloc.c @@ -22,6 +22,8 @@ struct { struct spinlock lock; int use_lock; struct run *freelist; + + uint phys_top; } kmem; // Initialization happens in two phases. @@ -34,14 +36,17 @@ kinit1(void *vstart, void *vend) { initlock(&kmem.lock, "kmem"); kmem.use_lock = 0; + // We haven't found phystop yet, don't use this. + kmem.phys_top = 0; freerange(vstart, vend); } void -kinit2(void *vstart, void *vend) +kinit2(void *vstart, void *vend, uint phys_top) { freerange(vstart, vend); kmem.use_lock = 1; + kmem.phys_top = phys_top; } void @@ -62,8 +67,10 @@ kfree(char *v) { struct run *r; - if((uint)v % PGSIZE || v < end || V2P(v) >= PHYSTOP) + if((uint)v % PGSIZE || v < end || (kmem.phys_top && V2P(v) >= kmem.phys_top)) + { panic("kfree"); + } // Fill with junk to catch dangling refs. memset(v, 1, PGSIZE); diff --git a/kernel/src/main.c b/kernel/src/main.c index 6b6d639..30a5354 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -21,7 +21,7 @@ int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator - kvmalloc(); // kernel page table + kvmalloc(PHYSTOP); // kernel page table mpinit(); // detect other processors lapicinit(); // interrupt controller seginit(); // segment descriptors @@ -35,7 +35,7 @@ main(void) fileinit(); // file table ideinit(); // disk startothers(); // start other processors - kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() + kinit2(P2V(4*1024*1024), P2V(PHYSTOP), PHYSTOP); // must come after startothers() userinit(); // first user process mpmain(); // finish this processor's setup } diff --git a/kernel/src/vm.c b/kernel/src/vm.c index ebebf64..a78e8b3 100644 --- a/kernel/src/vm.c +++ b/kernel/src/vm.c @@ -111,13 +111,16 @@ static struct kmap { } kmap[] = { { (void*)KERNBASE, 0, EXTMEM, PTE_W}, // I/O space { (void*)KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kern text+rodata - { (void*)data, V2P(data), PHYSTOP, PTE_W}, // kern data+memory + + // kern data+memory -- the 0x5f.. addr should be the top of physical memory. Fill that in dynamically in setupkvm. + { (void*)data, V2P(data), 0x5F5F5F5F, PTE_W}, + { (void*)DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices }; // Set up kernel part of a page table. pde_t* -setupkvm(void) +setupkvm() { pde_t *pgdir; struct kmap *k; @@ -125,22 +128,30 @@ setupkvm(void) if((pgdir = (pde_t*)kalloc()) == 0) return 0; memset(pgdir, 0, PGSIZE); - if (P2V(PHYSTOP) > (void*)DEVSPACE) + if (P2V(kmap[2].phys_end) > (void*)DEVSPACE) + { panic("PHYSTOP too high"); + } + for(k = kmap; k < &kmap[NELEM(kmap)]; k++) + { if(mappages(pgdir, k->virt, k->phys_end - k->phys_start, - (uint)k->phys_start, k->perm) < 0) { + (uint)k->phys_start, k->perm) < 0) + { freevm(pgdir); return 0; } + } return pgdir; } // Allocate one page table for the machine for the kernel address // space for scheduler processes. void -kvmalloc(void) +kvmalloc(uint phys_top) { + kmap[2].phys_end = phys_top; + kpgdir = setupkvm(); switchkvm(); } -- 2.47.3