PCZONE 討論區

PCZONE 討論區 (https://www.pczone.com.tw/vbb3/)
-   -- 電 腦 硬 體 討 論 版 (https://www.pczone.com.tw/vbb3/forum/14/)
-   -   【轉貼】PAE (https://www.pczone.com.tw/vbb3/thread/14/140350/)

DDSC 2008-03-27 11:28 PM

【轉貼】PAE
 
在檔案中發現了這文章,可看性頗佳,就貼出了,原文是在2004年在TANET的程設語言板所取出的,作者是 CIH,應該大家都知道的人OK

--------->開始
[code]
03 Jun 2004 , CIH

我只是單純以技術來探討這些問題.

若有錯誤的地方,
麻煩大家糾正.

感恩啦~~~

1.
關於DOS/4GW.

時間: 我大二(約民國84年)
機器: 386
工具: 用softice去trace
能力背景: 那時寫過DOS extender

那年我有實務寫DOS extender的經驗,
靠自己的程式,
去動IDTR, GDTR, CR3等等system registers,
同時最後動CR0的PE, PG,
讓386從DOS下的real mode, 切到protected mode,
此刻可以定址4GB, 並支援MMU(因為我有enable PG), 一個page是4KB大小.
其定址方式, 是selector:offset.
這樣的DOS extender, 可以些許"相容", DOS/BIOS call,
也就是int 21h, int 13h等依然可以正常執行,
其原因, 我是把x86從protected mode切到V86 mode(此mode,依然在protected mode),
程式的寫法是利用iret從PM->V86,
切到V86 mode後,
CPU是segment:offset定址方式(跟real mode一樣),
就可以正常呼叫這些DOS/BIOS call,
為了避免V86 mode下的程式讀取I/O產生GP, 所以那時我把IOPL(在cflag裡面)設成3,
以便讓ring 3權限的DOS/BIOS擁有完全I/O控制權(包括可以正常執行cli/sti等指令).
當然呼叫BIOS/DOS程式前, 我會去查IVT(位於phys addr最前面, 所謂中斷向量表),
然後取出16-bit segment, 以及16-bit offset,
並且把stack裡面CS/IP的值, 給一個我指定的address,
以便執行我給的非法指令, 產生非法指令exception, 才能再回到protected mode下.
那時也利用MMU,
把64KB限制的VGA, 拉成1MB.

同道理,
DOS/4GW也是這樣,
我也trace過它.
之前是用watcom c++編譯的,
裡面有附所謂DOS/4GW這樣的dos extender.

它可以讓你在DOS下,
可以擁有4GB定址的能力,
同時DOS/BIOS call依然正常可以執行!!

原理也如我的做法一樣!!

倒是那時trace它,
若它發現沒有DPMI存在,
就會自己動CR0,
若存在的話,
會靠DPMI協助, 切到protected mode.
不過此刻是16-bit segment定址方式,
無法access到4GB, 最後它會配置32-bit Segment Descriptor,
最後才可以存取到4GB.

2.
關於386定址,

CPU定址最大是4GB.
因為segment, page記憶體管理描述表, 只能存取最大到4GB.
或許很多人有看過一些資料, 會看過64TB, 這樣的數據,
這是因為GDT/LDT這些表最大共有2^14=16384個(16-bit的selector減去2-bit的RPL),
也就是最大可以指16384個segment, 而每個segment最大是4GB,
故16384x4GB=65536GB=64TB.

286已經有protected mode, 不過是16-bit protected mode.
從386以後, 就有32-bit protected mode.

3.
在x86 CPU上,
以Windows/Linux Kernel而言,
目前對memory的保護方式,
是不透過segment那一層(ring0-ring3),
而是透過page來保護(只有兩種權限user/kernel).

4.
至於現在"聽說"有些x86版子可以插到大於4GB的RAM,
同時OS依然可以存取到所有RAM, 為何呢!??

我已經脫離這領域很久了,
也不知道為何現在可以access超過4GB的physically address.
也非常好奇,
剛剛查詢一下網路...

=========================
以下內容,我沒有實際寫過這樣的東西,
單純從網路文件得知,
看完後的心得.
=========================

果真,
從Pentium以後,
就有36位元的定址能力.

當CR4的PAE啟動後,
其page的轉換方式,
就跟之前386不同.

簡單而言,
那些分頁目錄(PDE), 分頁表(PTE),
原本在386下,
只能定址到2^32=4GB,
現在全部可以定址到2^36=64GB.

那我們真的擁有64GB的定址空間嗎!???

對,
我們可以定址到64GB,
不過呢,
從邏輯位址(selector:offset, 例如CS:EIP或是DS:ESI),
其EIP以及ESI等等暫存器, 全是32-bit, 最大只能到4GB.
再透過segment這一層, 轉換成32-bit linear address, 最後透過這個所謂"36-bit" page轉換後,
就可以定址64GB內, 任意的最大4GB空間.

也就是,
簡單形容一下,
雖然整個空間是64GB,
不過,
我們依然最大最大只能擁有4GB大小的window,
只能利用這個4GB window在64GB中移動.

舉個例子,
31GB到35GB
32GB到36GB

對程式而言,
依然只能看到最大4GB,
不過這個最大4GB, 可能坐落在整個64GB任何一塊.

大致上是這樣,
有興趣的人,
可以上網找資料,
研究一下~~~

Bless you~~

--------------------------------------------------------------------------------

根據之前我寫的文章,
我再補充一下,
在x86 Pentium系列後(根據網路文章描述,我沒徹底考證過),
啟動PAE後,
那到底程式(可能kernel/driver/AP),
擁有是4GB的最大空間, 還是64GB的最大空間!??

"假設"板子上插了64GB的RAM.

因為所有程式(無論user mode/kernel mode),
都要透過第一層的segment把邏輯位址selector:offset(32-bit),
轉換成32-bit linear address,
再透過第二層所謂36-bit page轉換後,
最大可以定址64GB裡面的4GB大小.

是故,
無論如何,
最大只能定址4GB.

不過,
假設OS(有ring 0權限),
有個function可以去設定page相關tables,
隨意讓其它程式呼叫(包括ring 3),
並重新remap linear address與physically address的對應關係.

若此function叫做"4GB_Linear_To_Phys".

若,
4GB_Linear_To_Phys(0) ==> 0-4GB(linear)就是 0-4GB(physically address).
4GB_Linear_To_Phys(1) ==> 0-4GB(linear)就是 4-8GB(physically address).
..
4GB_Linear_To_Phys(15) ==> 0-4GB(linear)就是60-64GB(physically address).

因此,
我們可以讓ring 3程式,
可以access到整個64GB的RAM.

簡易程式如下:

unsigned char *p = NULL;

for ( i = 0 ; i < 16 ; i++ )
{
4GB_Linear_To_Phys(i);

p = 0;
do
{
c = *p;
p++;
} while ( p != 0 );
}

當然,
以上程式,
基本上,
我認為,
不可能~~~~
對OS很困擾, 是個不可能的做法!!!!!!
當然硬要幹的話,
一定也可以!!!

其原因是,
一但整個4GB被重新map,
把linear address的4GB, 對應到不同的4GB大小physically address.
此刻程式, 包括OS本身, 整個系統立刻死掉!!
假設,
我們的,
0-4GB(linear)就是 0-4GB(physically address).

若AP在linear address的1M, OS在linear address的3GB.
所以當然AP在phys addr的1M, OS在phys addr的3GB.
P.S 此刻我是指所謂4GB flat mode.

若此時,
ring 3的AP,
呼叫
4GB_Linear_To_Phys(1);

沒做特別處理前,
若直接切page,
這時,
0-4GB(linear)就是 4-8GB(physically address).
而4-8GB(physically address)根本沒有任何程式碼, 資料, 完全空的!!
當然0-4GB(linear)也是空的, 因此立刻整個系統, 徹底死掉!!!!!

所以我們的4GB_Linear_To_Phys這個function,
一開始就得把相關AP, OS, 以及所有使用的記憶體,
全部相對應copy到RAM(phys addr)的4GB-8GB.
最後才去更改page對應.

因此這樣function,
根本不可能真正運用在OS,
不可能這樣做!!!
若是某個白爛OS, 硬這樣的話, 我認了!!!!

不過倒是kernel可以提供這樣的function,
例如:
256MB_Linear_To_Phys,

virt=256MB_Linear_To_Phys(0)
==> virt到virt+256M(linear)就是 0-256MB(physically address).

virt=256MB_Linear_To_Phys(1)
==> virt到virt+256M(linear)就是 256MB-512MB(physically address).

virt=256MB_Linear_To_Phys(2)
==> virt到virt+256M(linear)就是 512MB-768MB(physically address).

依此類推...

這樣的做法,
絕對性沒問題!!!
只要kernel(ring 0),
有提供如此function,
AP就可以透過上面那樣程式,
一個迴圈的程式, 可以讀取到整個64GB的RAM.

大致上是這樣,
希望能提供大家清晰的觀念與幫助~~~

感恩啦~~~~

--------------------------------------------------------------------------------

最後再補充一下我小小的想法,
x86 Pentium以後系列,
啟動PAE後,
事實上,
還是定址最大4GB, 只是這個4GB是位於64GB以內任何一段.

當然,
如我之前文章所提,
若OS有提供修改page tables之類的function,
依然AP可以 "間接" 讀取到整個64GB!!

所以,
那到底一個AP最大定址空間是4GB, 還是64GB!????
我也不知道, 這些文字的"定義"是如何~~~~~
倒是我還是偏向於,
程式最大是定址4GB大小, 只是若OS有提供特殊system call,
則可以透過這樣function, 利用這個window, "間接" 存取到64GB.

結論: 我實在不知道這個"最大定址空間大小"中文正確意義是什麼,
或許其他人會比較清楚.

那,
若要改變x86 Pentium CPU,
徹底一次定址到64GB的話,
也就是只要ds:esi這樣一行組合語言指令, 就可以access到0-64GB.
我們該怎麼作!?

個人想法:
1. registers要變成36-bit(如: eip, esi, esp等)
2. Segment Descriptor
此table, 原本其中兩個欄位,
base address以及segment limit各是32-bit,
必須都改成36-bit, 才能把selector(16-bit):offset(36-bit)這個邏輯位址,
轉成36-bit linear address.
P.S base address這一欄, 事實上, 在我們這個舉例中, 可以不用變.
重要的是, segment limit一定要36-bit.
3. Page轉換這一層, 要重新定義, 重改.
原本x86 Pentium系列, 啟動PAE後,
是有能力把32-bit linear address,
透過我叫做"所謂"36-bit page的轉換.
不過, 轉換成32-bit phys addr, 依然最大只能定址4GB,
只不過此4GB(2^32)是位於64GB(2^36)裡面的一個window.
是故, 此架構, 要全改.
變成有能力, 把36-bit linear address,
轉換成36-bit phys addr.


大概這樣,
奔忙中,
沒空看這個板,
以後有空,
再聊我實際寫這類程式的經驗~~~~

再次感恩啦~~~
[/code]


所有時間均為 +8。現在的時間是 09:50 PM



 XML   RSS 2.0   RSS 
本站使用 vBulletin 合法版權程式
站務信箱 : [email protected]

本論壇所有文章僅代表留言者個人意見,並不代表本站之立場,討論區以「即時留言」方式運作,故無法完全監察所有即時留言,若您發現文章可能有異議,請 email :[email protected] 處理。