finish exec4.1-6

This commit is contained in:
KAAAsS 2021-05-17 18:51:10 +08:00
parent 63ce2d4a49
commit 872869cf87
Signed by: KAAAsS
GPG Key ID: D56625F3E671882F
7 changed files with 34 additions and 1 deletions

View File

@ -91,6 +91,8 @@ void unlock(struct lock *lock)
* Unlock the ticket lock here
* Your code should be no more than 5 lines
*/
// 因为仍在临界区,所以可以直接 ++
lock->owner++;
}
/**
@ -101,7 +103,7 @@ void unlock(struct lock *lock)
*/
int is_locked(struct lock *lock)
{
return -1;
return lock->owner != lock->next;
}
/**
@ -110,6 +112,7 @@ int is_locked(struct lock *lock)
*/
void kernel_lock_init(void)
{
lock_init(&big_kernel_lock);
}
/**
@ -118,6 +121,7 @@ void kernel_lock_init(void)
*/
void lock_kernel(void)
{
lock(&big_kernel_lock);
}
/**
@ -126,4 +130,5 @@ void lock_kernel(void)
*/
void unlock_kernel(void)
{
unlock(&big_kernel_lock);
}

View File

@ -34,11 +34,13 @@ void enable_smp_cores(void *addr)
* _start of `start.S`. Then, what's the flag?
* You only need to write one line of code.
*/
secondary_boot_flag[i] = 1;
/* Lab4
* The BSP waits for the currently initializing AP finishing
* before activating the next one
*/
while (cpu_status[i] != cpu_run);
}
/* This information is printed when all CPUs finish their initialization */

View File

@ -54,6 +54,9 @@ void handle_entry_c(int type, u64 esr, u64 address)
* Lab4
* Acquire the big kernel lock, if the exception is not from kernel
*/
if (type >= SYNC_EL0_64) {
lock_kernel();
}
/* ec: exception class */
u32 esr_ec = GET_ESR_EL1_EC(esr);

View File

@ -91,6 +91,9 @@
* unlock the big kernel lock before returning to the user mode
*/
.macro exception_return
bl unlock_kernel
exception_exit
.endm

View File

@ -40,6 +40,9 @@ void handle_irq(int type)
* The irq is not from the kernel
* The thread being interrupted is an idle thread.
*/
if (type >= SYNC_EL0_64 || current_thread->thread_ctx->type == TYPE_IDLE) {
lock_kernel();
}
plat_handle_irq();

View File

@ -66,6 +66,7 @@ void main(void *addr)
*/
kernel_lock_init();
kinfo("[ChCore] lock init finished\n");
lock_kernel();
/* Init scheduler with specified policy. */
sched_init(&rr);
@ -112,6 +113,7 @@ void secondary_start(void)
* Inform the BSP at last to start cpu one by one
* Hints: use cpu_status
*/
cpu_status[smp_get_cpu_id()] = cpu_run;
#ifndef TEST
run_test(false);
@ -121,6 +123,7 @@ void secondary_start(void)
* Lab4
* Acquire the big kernel lock
*/
lock_kernel();
/* Where the AP first returns to the user mode */
sched();

View File

@ -181,3 +181,17 @@ process_create_root、thread_create_main 直接写在注释里面了。
正常情况下还需要调用 commit_page_to_pmo 记录具体的分配物理页,要不然无法回收。但是注释说为了简便起见就不做了。
顺便吐槽一下开了 Debug 日志就没办法通过样例了,因为 brk 样例触发缺页中断会输出一个 Debug正好在"0,[Debug]...1,2,..."。
** Lab 4
*** 练习1
基本流程其实类似。但是对于其他 cpu 并不是单纯死循环,而是等待 bss 段清空、切换权限等级、等待多核准备完成最后进入 c 入口。
*** 练习3
boot 阶段的栈是独立的。函数也没调用几个,我猜测可能是 el1_mmu_activate 函数的问题?
*** 练习6
原因是 unlock_kernel 后才进行从栈恢复,而且函数退出时内核栈还是空的,所以 unlock 的时候无所谓。