新進程建立:
1 初始化記憶體,分配記憶體頁面
2 初始化核心進程
3 添加到進程列表
然後通過進程調度器調度運行
/*<br /> * Schedule a thread that is waiting to run.<br /> * Must be called with interrupts off!<br /> * The current thread should already have been placed<br /> * on whatever queue is appropriate (i.e., either the<br /> * run queue if it is still runnable, or a wait queue<br /> * if it is waiting for an event to occur).<br /> */<br />void Schedule(void)<br />{<br /> struct Kernel_Thread* runnable;</p><p> /* Make sure interrupts really are disabled */<br /> KASSERT(!Interrupts_Enabled());</p><p> /* Preemption should not be disabled. */<br /> KASSERT(!g_preemptionDisabled);</p><p> /* Get next thread to run from the run queue */<br /> runnable = Get_Next_Runnable();</p><p> /*<br /> * Activate the new thread, saving the context of the current thread.<br /> * Eventually, this thread will get re-activated and Switch_To_Thread()<br /> * will "return", and then Schedule() will return to wherever<br /> * it was called from.<br /> */<br /> Switch_To_Thread(runnable);<br />}
進程調度進行進程啟動並執行切換
Switch_To_Thread:<br />; Modify the stack to allow a later return via an iret instruction.<br />; We start with a stack that looks like this:<br />;<br />; thread_ptr<br />; esp --> return addr<br />;<br />; We change it to look like this:<br />;<br />; thread_ptr<br />; eflags<br />; cs<br />; esp --> return addr</p><p>pusheax; save eax<br />moveax, [esp+4]; get return address<br />mov[esp-4], eax; move return addr down 8 bytes from orig loc<br />addesp, 8; move stack ptr up<br />pushfd; put eflags where return address was<br />moveax, [esp-4]; restore saved value of eax<br />pushdword KERNEL_CS; push cs selector<br />subesp, 4; point stack ptr at return address</p><p>; Push fake error code and interrupt number<br />pushdword 0<br />pushdword 0</p><p>; Save general purpose registers.<br />Save_Registers</p><p>; Save stack pointer in the thread context struct (at offset 0).<br />moveax, [g_currentThread]<br />mov[eax+0], esp</p><p>; Clear numTicks field in thread context, since this<br />; thread is being suspended.<br />mov[eax+4], dword 0</p><p>; Load the pointer to the new thread context into eax.<br />; We skip over the Interrupt_State struct on the stack to<br />; get the parameter.<br />moveax, [esp+INTERRUPT_STATE_SIZE]</p><p>; Make the new thread current, and switch to its stack.<br />mov[g_currentThread], eax<br />movesp, [eax+0]</p><p>; Restore general purpose and segment registers, and clear interrupt<br />; number and error code.<br />Restore_Registers</p><p>; We'll return to the place where the thread was<br />; executing last.<br />iret
進程切換過程如下:
0 仿中斷調用
1 儲存當前進程的寄存器等資訊進入當前堆棧
2 清當前進程的計時器為0
3 恢複切換進程為當前進程(切換進程需要傳遞資訊 結合資料定義擷取下面恢複設定)
4 恢複切換進程的堆棧設定
5 根據堆棧資訊回複寄存器
6 中斷退出
7 運行新切換的進程