1. 程式人生 > 實用技巧 >程序上下文和中斷上下文

程序上下文和中斷上下文

linux0.11系統共使用了四種堆疊

一種是系統初始化時臨時使用的堆疊

一種是供核心程式自己使用的堆疊(核心堆疊),只有一個位於系統地址空間固定的位置,也是後來任務0的使用者態堆疊。

一種是每個任務通過系統呼叫,執行核心程式時使用的堆疊,我們稱之為任務的核心態堆疊,每個任務都有自己獨立的核心態堆疊。

一種是任務在使用者態執行的堆疊,位於任務(程序)地址空間的末端,稱為使用者態堆疊

任務的堆疊

每個任務都有自己的核心態堆疊,與每個任務的任務資料結構(task_struct)放在同一頁中.

這是在建立新任務時,fork()程式在任務狀態段tss(只是一個位於記憶體的結構體裡面存著eip esp...)的

核心級堆疊欄位(tss.esp0和tss.ss0)中設定的。

任務0的堆疊

任務0的堆疊比較特殊,任務0的資料段和程式碼段相同,段基地址都是從0開始,限長也都是640K。

這個地址範圍也就是核心程式碼和資料所在的地方。在執行了move_to_user_mode()之後,他的核心堆疊位於其任務資料結構所在頁面的末端,而他的使用者態堆疊就是前面進入保護模式後所使用的堆疊 ,即sched.c的user_stack陣列的位置。

任務0的核心態堆疊是在其人工設定的初始化任務資料結構中指定的,而他的使用者態堆疊是在執行move_to_user_mode()時,在模擬iret返回之前的堆疊中設定的。

iret具體作用:中斷的返回,具體是返回標誌暫存器CS IP

複習一下暫存器:

CS DS SS ES都是段暫存器

AX BX CX DX通用暫存器

在核心裡面指向核心棧:SS:堆疊段 ESP:堆疊指標

SS:記錄的是段選擇器,使用者程式不可以程序修改

ESP:指向堆疊內部特定位置的32位的指標。

程式碼指令就是CS:程式碼段 EIP:指令地址暫存器


核心態與使用者態堆疊的切換

任務呼叫和系統呼叫時就會進入核心,執行核心程式碼。

此時核心程式碼就會使用該任務的核心態堆疊進行操作。

當進入核心程式時,由於優先順序發生了改變(從使用者態轉到核心態),使用者態堆疊的堆疊段和堆疊指標以及eflags會被儲存在人物的核心態堆疊中。而在執行iret推出核心程式,回到使用者程式時,將恢復使用者態堆疊的堆疊和eflags。

程序上下文和中斷上下文

當一個程序在執行時,CPU的所有暫存器中的值、程序的狀態以及堆疊中的內容被稱為該程序的上下文。

當核心需要切換到另一個程序時,它需要儲存當前程序的所有狀態,即儲存當前程序的上下文,以便在再次執行該程序時,能夠必得到切換時的狀態執行下去。在LINUX中,當前程序上下文均儲存在程序的任務資料結構中。

在發生中斷時,核心就在被中斷程序的上下文中,在核心態下執行中斷服務例程。但同時會保留所有需要用到的資源,以便中繼服務結束時能恢復被中斷程序的執行