finish exec4.1-6
This commit is contained in:
parent
63ce2d4a49
commit
872869cf87
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -91,6 +91,9 @@
|
||||
* unlock the big kernel lock before returning to the user mode
|
||||
*/
|
||||
.macro exception_return
|
||||
|
||||
bl unlock_kernel
|
||||
|
||||
exception_exit
|
||||
.endm
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
14
note.org
14
note.org
@ -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 的时候无所谓。
|
||||
|
Loading…
x
Reference in New Issue
Block a user