linux模式切換,進程切換


內核態和用戶態的切換:

用戶態到內核態的轉換:1、進行系統調用,2、異步中斷,3、外部硬件中斷

檢查特權級別的變化:當異常發生在用戶態,而異常處理函數則必須運行在內核態,則此時必須調用內核態的堆棧(系統調用必然是發生特權級的變化),步驟是,將進程的TSS段中的esp0和ss0賦值給esp,ss寄存器

於是乎,當進程由用戶態進入內核態時,必發生中斷,因為內核態的CPL優先級高,所以要進行棧的切換。那么就會讀tr寄存器以訪問該進程(現在還是用戶態)的TSS段。隨后用TSS中內核態堆棧段ss0和棧指針esp0裝載SS和esp寄存器,這樣就實現了用戶棧到內核棧的切換了。同時,內核用一組mov指令保存所有寄存器到內核態堆棧上,這也包括用戶態中ss和esp這對寄存器的內容。

最后將先前由中斷向量檢索得到的中斷處理程序的cs,eip信息裝入相應的寄存器,開始執行中斷處理程序,這時就轉到了內核態的程序執行了。

 

進程切換:

這里再次強調一下,每個進程都有一個thread_struct結構的字段thread,用於保留進程的一部分硬件上下文:

這里再次強調一下,每個進程都有一個thread_struct結構的字段thread,用於保留進程的一部分硬件上下文:
struct thread_struct {
    struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
    unsigned long   esp0;
    unsigned long   sysenter_cs;
    unsigned long   eip;
    unsigned long   esp;
    unsigned long   fs;
    unsigned long   gs;
    unsigned long   debugreg[8]; 
    unsigned long   cr2, trap_no, error_code;
    union i387_union    i387;
    struct vm86_struct __user * vm86_info;
    unsigned long       screen_bitmap;
    unsigned long       v86flags, v86mask, saved_esp0;
    unsigned int        saved_fs, saved_gs;
    unsigned long   *io_bitmap_ptr;
    unsigned long   io_bitmap_max;
};

 

待會我們就將看到,其實里邊最有用的就是eip和esp兩個字段,分別表示保存的指令和堆棧棧頂的偏移地址。但這里不包括ss寄存器的值,因為所有的切換都在內核態,那么只用為內核態的堆棧基址ss0保存一次就行了,你們這些進程切來切去,我都不便應萬變,把它保存在每個CPU所對應的那個TSS段中。這里也得出了一個很重要的結論,為了提高效率,所有內核態的進程堆棧段基地址都是相同的。

thread字段存放的都是內核棧的esp和eip,然后_switch_to()宏,此時已經進入要切換進來進程的內核棧中,把已經切換進來的進程的thread.esp0裝入本地cpu的esp0字段

切換前:被切換進程的內核棧,壓入ebp,eflag,然后把被切換進程內核棧的esp賦值給本進程的thread.esp。

切換進來的進程,把本進程的thread.ESP賦值給esp,此時便切換到本進程中,但是局部變量沒有完成切換,(向prev->thread.eip存入標記為1的地址。當被替換的進程重新恢復執行時,進程執行我們下面標記為1的那條指令:)這里的prev變量依舊屬於被切換的進程。

5. 宏把next->thread.eip的值(絕大多數情況下是上面所述標記為1的地址)壓入next的內核棧:
    pushl next->thread.eip

注意體會,當next執行完了以后的函數后,會回到這個棧的位置,執行eip對應的那條指令。

6.    跳到__switch_to()函數:
   jmp  __switch_to

7. 如干程序執行后,當A將再次獲得CPU時,它執行一些保存eflags和ebp寄存器內容內容的指令,這兩條指令的第一條指令被標記為1:
   1:
        popl %ebp
        popfl


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM