1.程序的堆疊
核心在建立程序的時候,在建立task_struct的同事,會為程序建立相應的堆疊。每個程序會有兩個棧,乙個使用者棧,存在於使用者空間,乙個核心棧,存在於核心空間。當程序在使用者空間執行時,cpu堆疊指標暫存器裡面的內容是使用者堆疊位址,使用使用者棧;當程序在核心空間時,cpu堆疊指標暫存器裡面的內容是核心棧空間位址,使用核心棧。
2.程序使用者棧和核心棧的切換
當程序因為中斷或者系統呼叫而陷入核心態之行時,程序所使用的堆疊也要從使用者棧轉到核心棧。
程序陷入核心態後,先把使用者態堆疊的位址儲存在核心棧之中,然後設定堆疊指標暫存器的內容為核心棧的位址,這樣就完成了使用者棧向核心棧的轉換;當程序從核心態恢復到使用者態之行時,在核心態之行的最後將儲存在核心棧裡面的使用者棧的位址恢復到堆疊指標暫存器即可。這樣就實現了核心棧和使用者棧的互轉。
那麼,我們知道從核心轉到使用者態時使用者棧的位址是在陷入核心的時候儲存在核心棧裡面的,但是在陷入核心的時候,我們是如何知道核心棧的位址的呢?
關鍵在程序從使用者態轉到核心態的時候,程序的核心棧總是空的。這是因為,當程序在使用者態執行時,使用的是使用者棧,當程序陷入到核心態時,核心棧儲存程序在核心態執行的相關信心,但是一旦程序返回到使用者態後,核心棧中儲存的資訊無效,會全部恢復,因此每次程序從使用者態陷入核心的時候得到的核心棧都是空的。所以在程序陷入核心的時候,直接把核心棧的棧頂位址給堆疊指標暫存器就可以了。
3.核心棧的實現
核心棧在kernel-2.4和kernel-2.6裡面的實現方式是不一樣的。
在kernel-2.4核心裡面,核心棧的實現是:
union task_union ;
其中,init_stack_size的大小只能是8k。
核心為每個程序分配task_struct結構體的時候,實際上分配兩個連續的物理頁面,底部用作task_struct結構體,結構上面的用作堆疊。使用current()巨集能夠訪問當前正在執行的程序描述符。
注意:這個時候task_struct結構是在核心棧裡面的,核心棧的實際能用大小大概有7k。
核心棧在kernel-2.6裡面的實現是(kernel-2.6.32):
union thread_union ;
其中thread_size的大小可以是4k,也可以是8k,thread_info佔52bytes。
當核心棧為8k時,thread_info在這塊記憶體的起始位址,核心棧從堆疊末端向下增長。所以此時,kernel-2.6中的current巨集是需要更改的。要通過thread_info結構體中的task_struct域來獲得於thread_info相關聯的task。更詳細的參考相應的current巨集的實現。
struct thread_info ;
注意:此時的task_struct結構體已經不在核心棧空間裡面了。
在intel系統中,棧起始於末端,並朝這個記憶體區開始的方向增長。從使用者態剛切換到核心態以後,程序的核心棧總是空的,因此,esp暫存器直接指向這個記憶體區的頂端。在圖4.2中,從使用者態切換到核心態後,esp暫存器包含的位址為0x018fc00。程序描述符存放在從0x015fa00開始的位址。只要把資料寫進棧中,esp的值就遞減。
在/include/linux/sched.h中定義了如下乙個聯合結構:
union task_union ;
從這個結構可以看出,核心棧佔8kb的記憶體區。實際上,程序的task_struct結構所佔的記憶體是由核心動態分配的,更確切地說,核心根本不給task_struct分配記憶體,而僅僅給核心棧分配8k的記憶體,並把其中的一部分給task_struct使用。
task_struct
結構大約佔1k位元組左右,其具體數字與核心版本有關,因為不同的版本其域稍有不同。因此,核心棧的大小不能超過7k,否則,核心棧會覆蓋task_struct結構,從而導致核心崩潰。不過,7k大小對核心棧已足夠。
把task_struct結構與核心棧放在一起具有以下好處:
·
核心可以方便而快速地找到這個結構,用偽**描述如下:
task_struct = (struct task_struct *) stack_pointer & 0xffffe000
·
避免在建立程序時動態分配額外的記憶體
·
task_struct
結構的起始位址總是開始於頁大小(page_size)的邊界。
節省核心棧的方法有:減少區域性變數、大型陣列和結構體、巢狀呼叫鏈。
程序核心棧 使用者棧
1.程序的堆疊 核心在建立程序的時候,在建立task struct的同事,會為程序建立相應的堆疊。每個程序會有兩個棧,乙個使用者棧,存在於使用者空間,乙個核心棧,存在於核心空間。當程序在使用者空間執行時,cpu堆疊指標暫存器裡面的內容是使用者堆疊位址,使用使用者棧 當程序在核心空間時,cpu堆疊指標...
程序的使用者棧和核心棧
詳細參考 核心在建立程序的時候,在建立task struct的同時,會為程序建立相應的堆疊。每個程序會有兩個棧,乙個使用者棧,存在於使用者空間,乙個核心棧,存在於核心空間。當程序在使用者空間執行時,cpu堆疊指標暫存器裡面的內容是使用者堆疊位址,使用使用者棧 當程序在核心空間執行時,cpu堆疊指標暫...
核心棧與使用者棧
核心棧和使用者棧區別 intel的cpu分為四個執行級別ring0 ring3 核心建立程序,建立程序的同時建立程序控制塊,建立程序自己的堆疊 乙個程序有兩個堆疊,使用者棧和系統棧 使用者堆疊的空間指向使用者位址空間,核心堆疊的空間指向核心位址空間。有個cpu堆疊指標暫存器,程序執行的狀態有使用者態...