本文分析基于Linux 0.11內(nèi)核,,轉(zhuǎn)載請(qǐng)標(biāo)明出處,http://blog.csdn.net/yming0221/archive/2011/06/01/6459119.aspx 在main.c的程序中,當(dāng)設(shè)備初始化完畢后,,程序?qū)膬?nèi)核模式切換到用戶模式,也就是所說的任務(wù)0,,執(zhí)行fork()函數(shù)(該函數(shù)使用內(nèi)嵌的匯 編,,防止函數(shù)調(diào)用弄亂堆棧,造成寫時(shí)復(fù)制COPY_ON_WRITE)切換到用戶堆棧并執(zhí)行任務(wù)0使用iret指令,,首先將有關(guān)的值壓入堆棧,,然后執(zhí) 行iret指令。將剛剛壓入對(duì)堆棧的數(shù)據(jù)根據(jù)標(biāo)志位彈入相應(yīng)的寄存器,。
執(zhí)行iret前的堆棧如下: 一下這段話引用自http://faydoc./cpu/iret.htm
If the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure, without a task switch. The code segment being returned to must be equally or less privileged than the interrupt handler routine (as indicated by the RPL field of the code segment selector popped from the stack). As with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is to virtual-8086 mode, the processor also pops the data segment registers from the stack. ----------------------------------- 由于在sched_init()中已經(jīng)設(shè)置了標(biāo)志寄存器中的vm標(biāo)志為0,,所以iret掉用后不會(huì)發(fā)生任務(wù)切換,,而是繼續(xù)執(zhí)行EIP指向的指令故繼續(xù)執(zhí)行 1標(biāo)號(hào)的代碼,開始執(zhí)行任務(wù)0,,任務(wù)0的堆棧段選擇符為0x17,,在sched_init()中已設(shè)置了任務(wù)0 的任務(wù)描述符和局部描述符為INIT_TASK
|
|