linux內核源代碼學習(2)內存映射模式終於搞清楚了

2009-08-12 00:38我發表於百度空間,今天移過來
linux內核源代碼學習(2)內存映射模式終於搞清楚了
                                                                                                                                           ------flyli
今天通過不斷的讀《linux內核代碼情景分析》和在網上查閱資料,終於把內存映射的總得機理高清楚了
下面是我參考的一篇文章(cttnbcj兄弟在csdn上發的一篇帖子,具體地址爲http://topic.csdn.net/u/20081011/07/a3d92bd2-19d5-4e25-89c3-bf8f7308bcef.html)
=====================================
段xxxx:偏移yyyyyyyy 
首先,xxxx是無法表示段的基址的,對於這個地址,首先要看xxxx的TI位是否爲0(即xxxx的第二位),如果是,則從GDTR中獲取GDT的基 址,然後在GDT中以段選擇器xxxx的高12位得出索引,根據索引偏移找到相應的段描述符,段描述符包括段的基址,限長,優先級各種屬性,這就得到了段 的起始地址,加上yyyyyyyy即是要找的內存的線性地址zzzzzzzz。  如果TI位爲1,則表示段描述符放在LDT中,第一步的操作還是從GDTR中獲取GDT的基址,然後從LDTR寄存器獲得索引(非XXXX的高十二位), 注意,這時根據索引偏移得到得並不是段描述符,而是得到LDT段的位置,然後根據xxxx的高十二位從LDT段中獲得段描述。再以這個段描述符信息得到段 基址,再加上偏移yyyyyyyy得到要找的線性地址zzzzzzzz。可以寫個簡單的模擬程式來表示:
if( xxxx的第二位==1 ) //段描述符的位置在GDTR中
{
A1=(GDTR的前三十二位); //把GDTR的基址給A1
段描述符=A1+(xxxx的高12位);  //可獲得段描述符
線性地址 = 段描述符中的基址+yyyyyyyy;
}
else  //TI位爲0,表示在段描述符在LDT中
{
A1=(GDTR的前三十二位);
A2=A1+LDTR;  //A2即是LDT描述符表的入口,注:LDTR是16位的 (自己註釋:GDTR只有一張表,而且基地址(在內核中)確定的,任務切換時候,也不會改變!每個LDTR又是指向自己任務的,所以任務切換時候,只是改 變LDTR寄存器中的內容(改變在GDT中的索引),找到另一個LDT段的描述符(包含了LDT的開始基地址和界限),然後加上段選擇子的索引,找出地址 中的位置!),還要要注意的是LDT表的基地址和界限是在LDT的高速緩存中,任務不切換的話,v高速緩存高速緩存的內容不會變!
段描述符=A2+(xxxx的高十二位) //LDT描述符表入口加上偏移,即是相應的段描述符 自己註釋:書上寫的A2(應該是表示從LDT的開始基地址吧)LDT的基地址+索引纔是局部描述符正確的位置
線性地址 = 段描述符中的基址+yyyyyyyy;
}
========================================

原來GDT和LDT之所以一個叫Global(全局)一個叫Local(局部)是因爲其實局部的描述表LDT僅僅是GDT的一個引索而已,
爲什麼要有一個GDTR,並且GDTR的結構和LDTR不一樣呢?

這主要是因爲系統只有一個GDT,而GDT的描述符有不能存放在GDT中(LDT的描述符都存放在GDT中),所以就需要一個GDTR來指示GDT在內存中的位置。因爲GDTR是直接指示內存地址,而LDTR主要指示LDT描述符在GDT中的位置和屬性,所以GDTR和LDTR的結構也不同。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章