為了控制程序的執行,linux核心必須有能力掛起正在cpu上執行的程序,換入想要切換的程序,也就是恢復以前某個掛起的程序,這就是linux的程序切換。
1程序切換的時機
一般來說,程序切換都是發生在從中斷或者系統呼叫返回使用者態的時候,最常見的是時鐘中斷。在允許核心搶占的情況下,系統呼叫被中斷打斷也有可能會引發程序切換。中斷處理和系統呼叫處理都發生在核心態,所以程序之間的切換實際上也是發生在了核心態。
2程序切換做的工作
2.1切換頁全域性目錄以安裝乙個新的位址空間。
2.2切換核心態堆疊和硬體上下文,硬體上下文提供了新程序執行所需要的所有的暫存器的所有資訊。
3程序切換的過程
程序切換統一發生在schedule()函式中,在這個裡面我們僅僅先來關注切換的過程,在核心**中切換程序的過程在switch_to()中,switch_to()是乙個巨集,其定義如下:
#define switch_to(prev,next,last) do while (0)
3.1引數說明
prev存放的是當前的current程序描述符指標。
next存放的是需要被替換進來的程序的描述符指標。
last比較麻煩,在一次程序被切換出去又切換進來的過程中,一般會涉及到3個程序,程序a,b,c,當程序a執行時,切換到程序b,然後再系統執行一段時間後,系統中執行的程序變為了程序c,然後由程序排程程式排程程序a執行,當排程程序a執行時,程序a使用的是自己的核心棧,裡面的prev和next就還是從a切換到b時的prev, next,即prev = a, next=b.然而本次從c切換到a應該將prev改變為c才對,而不是a了。
為解決這個問題switch_to()巨集在進入後,會把prev先儲存到暫存器eax中,當完成程序切換後,把eax的值存入變數last中。
3.2過程說明
採用標準的組合語言說明如下:
1在eax,edx暫存器中分別儲存prev和next的值。
movl prev, %eax
movl next, %edx
2把eflags和ebp暫存器存入prev程序的核心棧中,ebp暫存器中存放的是當前函式棧幀的棧底。
pushfl
push %ebp
3把esp暫存器的值存入prev->thread.esp中以使該值記錄prev核心棧的棧頂,應該注意由於核心態**使用統一的ess暫存器,所以該暫存器不需要被儲存。
mov %esp, 484(%eax)
4把next->thread.esp的值載入到暫存器esp中,這樣就會切換到要被切換進來程序的核心棧上,實際上完成了程序的切換。
mov next->thread.esp %esp
5把標記為1的位址記入prev->thread.eip,這樣當該程序被切換回來時,會去執行該位址的指令。
mov $1f, 480(%eax)
6把next->thread.eip值壓入核心棧,大多數情況下就是標記1指向的位址。
pushl 480(%edx)
7跳到__switch_to()函式,__switch_to()函式中我們關注的操作主要有2步:
7.1init_tss[cpu].esp0 = next_p->thread.esp,放入對應tss暫存器,在進行中斷處理或 系統呼叫時,會通過tss的esp0欄位設定當前程序核心棧。
7.2ret, 該指令會把棧頂儲存的返回位址裝入eip暫存器,從而執行返回位址的代 碼,在第6步將該值壓入了棧中,因此一般位址為標記1的位址,如果該程序是新建進 程,返回位址則是ret_from_fork()函式。
8在這裡被程序b替換的程序a再次獲得cpu,它會執行恢復eflags和ebp的指令。
1: popl %ebp
popfl
9copy eax暫存器的內容到last指向的記憶體區域,由於last和prev指向同樣的記憶體區域,這樣last就記錄了當前被替換的程序的程序描述符。
mov %eax, last
linux程序解析 程序切換
為了控制程序的執行,linux核心必須有能力掛起正在cpu上執行的程序,換入想要切換的程序,也就是恢復以前某個掛起的程序,這就是linux的程序切換。1程序切換的時機 一般來說,程序切換都是發生在從中斷或者系統呼叫返回使用者態的時候,最常見的是時鐘中斷。在允許核心搶占的情況下,系統呼叫被中斷打斷也有...
linux 程序切換,使用者態程序,核心態程序
linux 程序切換,使用者態程序,核心態程序 程序切換 一開始我並不想寫這個筆記,因為太過複雜,我一直想以簡單的方式理解核心,只從概念,避免涉及過多的 實際上,我寫筆記的時候,書已經看到很後面了,因為總要理解更多才能理解之前看似簡短實際複雜的內容。但最後發現實際上任何內容都沒有辦法跳過,即便不想看...
Linux2 6程序切換
1.程序切換是指 儲存prev程序的上下文,用next的上下文替代。其中上下文包括 頁全域性目錄 核心態堆疊 硬體上下文。2.80x86為程序切換提供的硬體支援 第一種 通過任務門 第二種 通過jmp和call指令 把硬體上下文存在tss中,執行這條指令時,通過硬體自動切換tss,完成硬體上下文的過...