ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[OS][MIT 6.828] Lab 4: Preemptive Multitasking

2020-12-06 23:34:14  阅读:324  来源: 互联网

标签:kernel handler void Lab 6.828 pgfault Preemptive user page


Part A: Multiprocessor Support and Cooperative Multitasking

Multiprocessor Support

1.Application Processor Bootstrap

routine chain in BSP to active AP

  1. static struct mpconf *mpconfig(struct mp **pmp): Search for an MP configuration table, invoked at the beginning of mp_init().
  2. void mp_init(void): Initialize variables bootcpu, cpus ...
  3. void lapic_init(void): Initialize LAPIC of BP, i.e., write values out to registers of BP.
  4. static void boot_aps(void): Load mpentry_start into physical address 0x7000, invoke lapic_startap() to active AP.
  5. void lapic_startap(uint8_t apicid, uint32_t addr): Send startup IPI (twice!) to enter code.

routine chain in AP to set up processor

  1. mpentry_start: Similar to start in boot.S.
  2. void mp_main(void): Similar to bootmain(). Up to here, the AP has been activated and wait to hold the kernel lock.

2.Per-CPU State and Initialization

NULL

3.Locking

JOS uses the simplest big kernel lock, so no more than one environment can run in kernel mode.

I had a question of the code below in the beginning. From mpentry_start in mpentry.S, which calls mp_main, I learned that mp_main was already in kernel mode, so why lock_kernel was invoked in mp_main. I thought lock_kernel should be invoked at least before mp_main. Finally, I found I was stupid. I forgot the essence of lock. Only when access sharing data will you need a lock, and the code in mp_main before lock_kernel and in mpentry.S only sets up registers private to each CPU. Last but not least, code in user mode has no privilege to invoke lock_kernel & unlock_kernel, so how stupid was I ^_^.

// Setup code for APs
void mp_main(void)
{
	// We are in high EIP now, safe to switch to kern_pgdir 
	lcr3(PADDR(kern_pgdir));
	cprintf("SMP: CPU %d starting\n", cpunum());

	lapic_init();
	env_init_percpu();
	trap_init_percpu();
	xchg(&thiscpu->cpu_status, CPU_STARTED); // tell boot_aps() we're up

	// Now that we have finished some basic setup, call sched_yield()
	// to start running processes on this CPU.  But make sure that
	// only one CPU can enter the scheduler at a time!
	//
	// Your code here:
	lock_kernel();
	sched_yield();
}

Round-Robin Scheduling

NULL currently

System Calls for Environment Creation

NULL currently

Part B: Copy-on-Write Fork

User-level page fault handling

When user-level page fault occurs, first the CPU will trap into kernel mode following the interrupt mechanism. The Kernel will switch stack to user exception stack on behalf of user environment, and then restart the user environment running a designated user-level page fault handler. Then the user-level page fault handler will return directly to the faulting code on the original stack without transfer to kernel stack.

In a word, the stack switch like this: User Stack -> Kernel Stack -> User Exception Stack -> User Stack

steps to register user-level page fault handler the 1st time

  1. sys_page_alloc() :Allocate 1 physical page for va [UXSTACKTOP, UXSTACKTOP - PGSIZE), invoked by set_pgfault_handler().
  2. sys_env_set_pgfault_upcall() in lib/syscall.c: Wrapper of the function below. Use syscall() to enter kernel mode. Invoked by set_pgfault_handler().
  3. sys_env_set_pgfault_upcall() in kern/syscall.c: Set the page fault upcall by modifying struct Env's 'env_pgfault_upcall' field.
  4. set_pgfault_handler(): Set the page fault handler, i.e., set up the function pointer variable _pgfault_handler. Return here from step 2.

routine chain to handle user-level page fault

  1. page_fault_handler() :For routine chain before this routine, refer to 'lab3, summary of the function chain when handle a trap'. This routine save utf, set eip to env_pgfault_upcall, set esp within exception stack, and call env_run() to return to user mode.
  2. _pgfault_upcall(): Env.env_pgfault_upcall will be setted to point to this function.
  3. _pgfault_handler(): This function is registered by the user environment in the steps as described above.

标签:kernel,handler,void,Lab,6.828,pgfault,Preemptive,user,page
来源: https://www.cnblogs.com/-zyq/p/14008377.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有