finish exec3.9 and lab 3
This commit is contained in:
parent
28a1f7d5a2
commit
70bf2a2104
@ -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
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
8
note.org
8
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,..."。
|
||||
|
Loading…
x
Reference in New Issue
Block a user