New Process Creation:
1. initialize the memory and allocate the Memory Page.
2. initialize the kernel Process
3. Add to process list
Then run the task through the Process Scheduler
/* <Br/> * Schedule a thread that is waiting to run. <br/> * must be called with interrupts off! <Br/> * The current thread shoshould 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 shocould 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/>}
Process Scheduling for process running Switching
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/>; 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 suincluded. <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
The process switching process is as follows:
0 imitation interrupt call
1. Save the registers of the current process and enter the current stack.
2. The timer of the current process is 0.
3. The recovery switchover process is the current process (the switchover process needs to pass information and obtain the following recovery settings based on the data definition)
4. Resume the stack settings of the switchover process.
5. Return registers based on stack information
6. Disconnect
7. Run the new process