From 70bf2a210423e9cb9766c786c1bb0cd828019d54 Mon Sep 17 00:00:00 2001 From: KAAAsS Date: Sun, 16 May 2021 17:17:26 +0800 Subject: [PATCH] finish exec3.9 and lab 3 --- lab3/.gdbinit | 2 +- lab3/CMakeLists.txt | 2 +- lab3/kernel/exception/exception.c | 5 +++++ lab3/kernel/exception/pgfault.c | 23 +++++++++++++++++++++++ lab3/kernel/mm/vm_syscall.c | 31 +++++++++++++++++++++++++++++++ note.org | 8 ++++++++ 6 files changed, 69 insertions(+), 2 deletions(-) diff --git a/lab3/.gdbinit b/lab3/.gdbinit index 598decb..98f1327 100644 --- a/lab3/.gdbinit +++ b/lab3/.gdbinit @@ -13,4 +13,4 @@ define add-symbol-file-auto end add-symbol-file-auto ./build/kernel.img -add-symbol-file-auto ./user/build/ramdisk/hello.bin +add-symbol-file-auto ./user/build/ramdisk/testpf.bin diff --git a/lab3/CMakeLists.txt b/lab3/CMakeLists.txt index 5588960..adc2b48 100644 --- a/lab3/CMakeLists.txt +++ b/lab3/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.14) set(CMAKE_VERBOSE_MAKEFILE on) -set(CMAKE_BUILD_TYPE "Debug") # "Release" or "Debug" +set(CMAKE_BUILD_TYPE "Release") # "Release" or "Debug" set(CHCORE_PLAT "raspi3") set(CHCORE_ARCH "aarch64") diff --git a/lab3/kernel/exception/exception.c b/lab3/kernel/exception/exception.c index 8a141f9..70c5649 100644 --- a/lab3/kernel/exception/exception.c +++ b/lab3/kernel/exception/exception.c @@ -53,6 +53,11 @@ void handle_entry_c(int type, u64 esr, u64 address) // Unknown instruction kinfo("%s", UNKNOWN); sys_exit(-ESUPPORT); + break; + case ESR_EL1_EC_DABT_LEL: + case ESR_EL1_EC_DABT_CEL: + do_page_fault(esr, address); + break; default: kdebug("Unsupported Exception ESR %lx\n", esr); break; diff --git a/lab3/kernel/exception/pgfault.c b/lab3/kernel/exception/pgfault.c index 33588d7..483120a 100644 --- a/lab3/kernel/exception/pgfault.c +++ b/lab3/kernel/exception/pgfault.c @@ -69,6 +69,7 @@ int handle_trans_fault(struct vmspace *vmspace, vaddr_t fault_addr) struct pmobject *pmo; paddr_t pa; u64 offset; + int ret; /* * Lab3: your code here @@ -86,6 +87,28 @@ int handle_trans_fault(struct vmspace *vmspace, vaddr_t fault_addr) * are recorded in a radix tree for easy management. Such code * has been omitted in our lab for simplification. */ + vmr = find_vmr_for_va(vmspace, fault_addr); + if (vmr == NULL) { + return -ENOMAPPING; + } + + pmo = vmr->pmo; + if (pmo->type != PMO_ANONYM) { + return -ENOMAPPING; + } + + // 分配物理页 + pa = virt_to_phys(kmalloc(PAGE_SIZE)); + if ((void *) pa == NULL) { + return -ENOMAPPING; + } + // 应该调用但是此处省略:commit_page_to_pmo(pmo, ..., pa); + + // 映射 + ret = map_range_in_pgtbl(vmspace->pgtbl, ROUND_DOWN(fault_addr, PAGE_SIZE), pa, PAGE_SIZE, vmr->perm); + if (ret != 0) { + return -ENOMAPPING; + } return 0; } diff --git a/lab3/kernel/mm/vm_syscall.c b/lab3/kernel/mm/vm_syscall.c index e567303..453130a 100644 --- a/lab3/kernel/mm/vm_syscall.c +++ b/lab3/kernel/mm/vm_syscall.c @@ -348,6 +348,37 @@ u64 sys_handle_brk(u64 addr) * */ + if (vmspace->heap_vmr != NULL) { + retval = vmspace->heap_vmr->start + vmspace->heap_vmr->size; + } else { + retval = vmspace->user_current_heap; + } + + if (addr == 0) { + // 初始化堆 + if (vmspace->heap_vmr != NULL) { + // 已经初始化 + return -EINVAL; + } + + // 创建堆 PMO 对象 + pmo = obj_alloc(TYPE_PMO, sizeof(*pmo)); + if (!pmo) { + return -ENOMEM; + } + pmo_init(pmo, PMO_ANONYM, 0, 0); + + // 初始化堆映射 + vmspace->heap_vmr = init_heap_vmr(vmspace, vmspace->user_current_heap, pmo); + } else if (vmspace->heap_vmr != NULL && addr > retval) { + // 增长堆 + vmspace->heap_vmr->size = addr - vmspace->heap_vmr->start; + retval = addr; + } else if (vmspace->heap_vmr != NULL && addr < retval) { + // 缩减堆 + retval = -EINVAL; + } + /* * return origin heap addr on failure; * return new heap addr on success. diff --git a/note.org b/note.org index ae49152..e235e26 100644 --- a/note.org +++ b/note.org @@ -173,3 +173,11 @@ process_create_root、thread_create_main 直接写在注释里面了。 *** 练习8 这个是最离谱的。所谓退出其实就是输出里出现了“breakpoint”。实际上程序并不会退出(评测机倒是会)。 + +*** 练习9 + +这个的关键是分配一页。我直接用了 kernel 统一的 kmalloc,反正大小够大肯定是用伙伴堆。 + +正常情况下还需要调用 commit_page_to_pmo 记录具体的分配物理页,要不然无法回收。但是注释说为了简便起见就不做了。 + +顺便吐槽一下开了 Debug 日志就没办法通过样例了,因为 brk 样例触发缺页中断会输出一个 Debug,正好在"0,[Debug]...1,2,..."。