From 44694ba9492b03042e3cda7eae717b854905e25e Mon Sep 17 00:00:00 2001 From: Freya Murphy <freya@freyacat.org> Date: Thu, 27 Mar 2025 17:56:39 -0400 Subject: [PATCH] track changes --- include/vm.h | 4 +-- kernel/cio.c | 5 +-- kernel/user.c | 2 +- kernel/vm.c | 91 +++++++++++++++++++++++++++++++++-------------- kernel/vmtables.c | 6 ++-- 5 files changed, 74 insertions(+), 34 deletions(-) diff --git a/include/vm.h b/include/vm.h index 6c4441f..8eac999 100644 --- a/include/vm.h +++ b/include/vm.h @@ -432,12 +432,12 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm); ** hierarchy. We assume that the "new" page directory exists and ** the system portions of it should not be touched. ** -** @param old Existing page directory ** @param new New page directory +** @param old Existing page directory ** ** @return status of the duplication attempt */ -int vm_uvmdup(pde_t *old, pde_t *new); +int vm_uvmdup(pde_t *new, pde_t *old); #endif /* !ASM_SRC */ diff --git a/kernel/cio.c b/kernel/cio.c index 1e5cb3c..deb6b76 100644 --- a/kernel/cio.c +++ b/kernel/cio.c @@ -67,8 +67,9 @@ static void (*notify)(int); // calculate the memory address of a specific character position // within VGA memory -#define VIDEO_ADDR(x, y) \ - (unsigned short *)(VID_BASE_ADDR + 2 * ((y) * SCREEN_X_SIZE + (x))) +#define VIDEO_ADDR(x, y) \ + (unsigned short *)((VID_BASE_ADDR + 2 * ((y) * SCREEN_X_SIZE + (x))) | \ + 0x80000000) // port addresses #define VGA_CTRL_IX_ADDR 0x3d4 diff --git a/kernel/user.c b/kernel/user.c index 7c475e8..f444b6c 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -748,7 +748,7 @@ int user_duplicate(pcb_t *new, pcb_t *old) // Next, add a USER_PDE page table that's a duplicate of the // current process' page table - if (!vm_uvmdup(old->pdir, new->pdir)) { + if (!vm_uvmdup(new->pdir, old->pdir)) { // check for memory leak? return E_NO_MEMORY; } diff --git a/kernel/vm.c b/kernel/vm.c index 2ab5720..7d43bb8 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -168,9 +168,17 @@ void vm_init(void) kpdir = vm_mkkvm(); assert(kpdir != NULL); +#if TRACING_VM + cio_printf("vm_init: kpdir is %08x\n", kpdir); +#endif + // switch to it vm_set_kvm(); +#if TRACING_VM + cio_puts("vm_init: running on new kpdir\n"); +#endif + // install the page fault handler install_isr(VEC_PAGE_FAULT, vm_isr); } @@ -327,9 +335,9 @@ pde_t *vm_mkkvm(void) if (pdir == NULL) { return NULL; } -#if TRACING_VM - cio_puts("\nEntering vm_mkkvm\n"); - ptdump(pdir, true, 0, N_PDE); +#if 0 && TRACING_VM + cio_puts( "\nEntering vm_mkkvm\n" ); + ptdump( pdir, true, 0, N_PDE ); #endif // clear it out to disable all the entries @@ -351,10 +359,10 @@ pde_t *vm_mkkvm(void) return 0; } } -#if TRACING_VM - cio_puts("\nvm_mkkvm() final PD:\n"); - ptdump(pdir, true, 0, 16); - ptdump(pdir, true, 0x200, 16); +#if 0 && TRACING_VM + cio_puts( "\nvm_mkkvm() final PD:\n" ); + ptdump( pdir, true, 0, 16 ); + ptdump( pdir, true, 0x200, 16 ); #endif return pdir; @@ -399,7 +407,13 @@ pde_t *vm_mkuvm(void) */ void vm_set_kvm(void) { +#if TRACING_VM + cio_puts("Entering vm_set_kvm()\n"); +#endif w_cr3(V2P(kpdir)); // switch to the kernel page table +#if TRACING_VM + cio_puts("Exiting vm_set_kvm()\n"); +#endif } /** @@ -411,10 +425,16 @@ void vm_set_kvm(void) */ void vm_set_uvm(pcb_t *p) { +#if TRACING_VM + cio_puts("Entering vm_set_uvm()\n"); +#endif assert(p != NULL); assert(p->pdir != NULL); w_cr3(V2P(p->pdir)); // switch to process's address space +#if TRACING_VM + cio_puts("Entering vm_set_uvm()\n"); +#endif } /** @@ -449,8 +469,8 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, } #if TRACING_VM - cio_printf("vm_add: pdir %08x, %s, va %08x (%u, %u pgs)\n", (uint32_t)pdir, - wr ? "W" : "!W", (uint32_t)va, size); + cio_printf("vm_add: pdir %08x, %s, va %08x size %u (%u pgs)\n", + (uint32_t)pdir, wr ? "W" : "!W", (uint32_t)va, size, npages); cio_printf(" from %08x, %u bytes, perms %08x\n", (uint32_t)data, bytes, entrybase); #endif @@ -511,6 +531,10 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size, */ void vm_free(pde_t *pdir) { +#if TRACING_VM + cio_printf("vm_free(%08x)\n", (uint32_t)pdir); +#endif + // do we have anything to do? if (pdir == NULL) { return; @@ -519,6 +543,8 @@ void vm_free(pde_t *pdir) // iterate through the page directory entries, freeing the // PMTS and the frames they point to pde_t *curr = pdir; + int nf = 0; + int nt = 0; for (int i = 0; i < N_PDE; ++i) { // the entry itself pde_t entry = *curr; @@ -537,6 +563,7 @@ void vm_free(pde_t *pdir) if (IS_PRESENT(*pmt)) { // yes - free the frame km_page_free((void *)PTE_ADDR(*pmt)); + ++nf; // mark it so we don't get surprised *pmt = 0; } @@ -545,6 +572,7 @@ void vm_free(pde_t *pdir) } // now, free the PMT itself km_page_free((void *)PDE_ADDR(entry)); + ++nt; *curr = 0; } @@ -554,6 +582,11 @@ void vm_free(pde_t *pdir) // finally, free the PDIR itself km_page_free((void *)pdir); + ++nt; + +#if TRACING_VM + cio_printf("vm_free: %d pages, %d tables\n", nf, nt); +#endif } /* @@ -580,7 +613,7 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm) char *last = (char *)PGDOWN(((uint32_t)va) + size - 1); #if TRACING_VM - cio_printf("\n\nvm_map pdir %08x va %08x pa %08x size %08x perm %03x\n", + cio_printf("vm_map pdir %08x va %08x pa %08x size %08x perm %03x\n", (uint32_t)pdir, (uint32_t)va, pa, size, perm); #endif @@ -591,24 +624,27 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm) // couldn't find it return E_NO_PTE; } - // #if TRACING_VM - // cio_printf( " addr %08x pa %08x last %08x pte %08x *pte %08x\n", - // (uint32_t) addr, pa, (uint32_t) last, (uint32_t) pte, *pte - // ); - //#endif +#if 0 && TRACING_VM + cio_printf( " addr %08x pa %08x last %08x pte %08x *pte %08x\n", + (uint32_t) addr, pa, (uint32_t) last, (uint32_t) pte, *pte + ); +#endif - // create the new entry - pde_t entry = pa | perm | PTE_P; + // create the new entry for the page table + pde_t newpte = pa | perm | PTE_P; // if this entry has already been mapped, we're in trouble if (IS_PRESENT(*pte)) { - if (*pte != entry) { + if (*pte != newpte) { #if TRACING_VM - cio_puts(" ALREADY MAPPED?"); - cio_printf(" PDIX 0x%x PTIX 0x%x\n", PDIX(addr), PTIX(addr)); + cio_printf( + "vm_map: va %08x pa %08x pte %08x *pte %08x entry %08x\n", + (uint32_t)va, pa, (uint32_t)pte, (uint32_t)*pte, newpte); + cio_printf(" addr %08x PDIX 0x%x PTIX 0x%x\n", (uint32_t)addr, + PDIX(addr), PTIX(addr)); // dump the directory - ptdump(pdir, true, 0, N_PDE); + ptdump(pdir, true, PDIX(addr), 4); // find the relevant PDE entry uint32_t ix = PDIX(va); @@ -617,16 +653,15 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm) // round the PMT index down uint32_t ix2 = PTIX(va) & MOD4_MASK; // dump the PMT for the relevant directory entry - ptdump((void *)P2V(PDE_ADDR(entry)), false, ix2, 8); + ptdump((void *)P2V(PDE_ADDR(entry)), false, ix2, 4); } #endif - PANIC(0, "mapping an already-mapped address"); } } // ok, set the PTE as requested - *pte = entry; + *pte = newpte; // nope - move to the next page addr += SZ_PAGE; @@ -647,17 +682,21 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm) ** now have two sets of page tables that refer to the same physical ** frames in memory. ** -** @param old Existing page directory ** @param new New page directory +** @param old Existing page directory ** ** @return status of the duplication attempt */ -int vm_uvmdup(pde_t *old, pde_t *new) +int vm_uvmdup(pde_t *new, pde_t *old) { if (old == NULL || new == NULL) { return E_BAD_PARAM; } +#if TRACING_VM + cio_printf("vmdup: old %08x new %08x\n", (uint32_t)old, (uint32_t)new); +#endif + // we only want to deal with the "user" half of the address space for (int i = 0; i < (N_PDE >> 1); ++i) { // the entry to copy diff --git a/kernel/vmtables.c b/kernel/vmtables.c index 4dfce43..113fd8b 100644 --- a/kernel/vmtables.c +++ b/kernel/vmtables.c @@ -365,7 +365,7 @@ const pte_t id_map[N_PTE] = { }; #endif /* MAKE_IDENTITY_MAP */ -extern int _end; +extern char _end[]; /* ** Kernel address mappings, present in every page table @@ -375,7 +375,7 @@ const mapping_t kmap[] = { { KERN_BASE, 0, EXT_BASE, PDE_RW }, { KERN_VLINK, KERN_PLINK, V2P(_data), PDE_RW }, // { (uint32_t) _data, V2P(_data), V2P(_end), PDE_RW }, - { (uint32_t)_data, V2P(_data), PHYS_TOP, PDE_RW }, - { DEV_BASE, DEV_BASE, 0, PDE_RW } + { (uint32_t)_data, V2P(_data), PHYS_TOP, PDE_RW } + // { DEV_BASE, DEV_BASE, 0, PDE_RW } }; const uint_t n_kmap = sizeof(kmap) / sizeof(kmap[0]);