本帖最後由 阿達金田一 於 2016-8-13 10:30 編輯
huhiha 發表於 2016-8-12 21:13 
網上關於mmio的資料好像比較少啊,講得都比較模糊。可能是因為它不能被打開/關閉?像關於mmio的歷史(從 ...
覺的你把問題複雜化...而且還搞混了
維基 MMIO
有些太深入的細節其實不用懂... 只要知道 MMIO 大概作用
例如 ... ( 下面打很長... 或者你可以先看最後... 在回頭來看 )
1. MMIO 就只是 硬體IO 的一方式...
MMIO 只是利用 Physical Memory Address (PMA) 來做 IO 而以 所以當存取 PMA 時...就是做 硬體IO
即然只是 IO 的一種方式... 可想而知...很早就有 MMIO 了
至少 Dos 時... 1M 傳統記憶體中 640K 主記憶體 給程式用
384K 是給硬體用的...而這應該就是 MMIO
https://www.equestionanswers.com ... getvect-setvect.php
所以大概 有 8086 和 Dos 時...就有 MMIO... 所以 MMIO 的歷史大多沒人提
2. 可能是因為現在都用 Win ... 所以你對 Win 和 整體 的 記憶體管理 .... 概念可能有點不清楚或是混亂
早期用 Dos ... 記憶體 就是直接用... 沒什麼 虛擬 或 分頁
可以試想一下... Bios 開機...就是直接用 記憶體 ... 在進入 OS(Win) 前就都算是 Bios 真實模式 (直接使用 Bios)
只是進入 OS 後... 使用者用的是 OS ... OS 在去用 Bios
也就是 進入 OS 前 ... 使用者(程式) -> Bios
也就是 進入 OS 後 ... 使用者(程式) -> OS -> Bios
所以...對 Win 要求 配置記憶體 時 ... (這和寫程式有關...如果你對這部份不瞭解... 就Pass 不用太深入)
如果一般是用 Win 自本身的 記憶體管理 去處理...
由於 Win 的 記憶體管理 是用 Virtual Memory Address(VMA) 或簡稱 Virtual Address(VA) + 分頁(PF) ... 來管理
如果要直觀一點就叫 "Win記憶體" ( VA + PF )
所以使用 Win記憶體 時 資料 未必 是存在 VA ... 也可能是在 PageFile (PF)
反之... 就是不透過 Win記憶體 來管理 記憶體 ... 而是 程式 自行管理 或 直接存取 PA
或者
Win 記憶體管理 本身應該也支援 配置 Physical Memroy 來用的方式... ( 就是 程式 在和 Win 要 記憶體 時...限定 VA 直接使用 Physical Memroy )
這是程式比較深入的部份...我也不是很懂... 因為一般寫程式是不用做 記憶體管理 都丟給 Win 來處理
https://msdn.microsoft.com/zh-tw/library/windows/desktop/aa366781(v=vs.85).aspx
3. Physical Memory Address 簡稱 Physical Address ... 就是 Physical Memory 實體(真實 or 物理)記憶體 的 位址空間
簡單說...就是 Physical Memory 的定址
x86 的 PA ... 因為 32bit ...所以只到 4G
而 PAE ... Physical Address Extension 就是 PA 的擴展版本 ... PAE 資料我就不在貼一次了 ... (所以 PAE 就當成 PA 吧)
簡單說 一般 x86 PA 是 32bit ... PAE 就是 大於 32bit 的 PA ...(但它還是 PA...只是 bit 比較長)
4. 在 x86 架構中...可能考量到 整體情況...
例如
不能保證 CPU 有 PAE 功能
OS 或 Driver 也用 PAE
x86 Leagcy Bios 開機也未必會去用到 PAE
...等等
因此 MMIO 大多也是用 32bit PA 來做 MMIO ... 通常 MMIO 是在 PA 3G - 4G 之間
MMIO 怎麼要 PA ..這其實不用懂...(有資料也未必看的懂...其實前面貼 維基MMIO 就有簡單的說明)
每個IO設備監測CPU的地址匯流排,並且在發現CPU訪問被分配到本設備的地址區域的時候做出響應,建立數據匯流排和相應設備暫存器之間的連接。為了實現CPU對MMIO設備的訪問,相應的地址空間必須給這些設備保留, 並且不能再分配給系統物理內存。這可以是永久保留,也可以是暫時性的保留。通常來說X86架構都是永久保留的,而在Commodore 64中,由於採用了IO設備和普通內存之間的堆交換技術(bank switching),可以做到暫時性保留。
5. PA(PAE) 和 VA
PA/PAE 可以看成 硬體(CPU) 的 定址 方式 ... 就是給硬體用
VA 則是 Win 本身 記憶體 管理方式 的 定址 ... 就是系統自己用
PAE 大小看 CPU , VA 大小看系統
PA <-> VA 之間有 位址 的 映射 ... 不過 PA 不一定會映射到 VA ... 也可能是 MMIO 用... 或是其它情況
PA/PAE 資料貼過就不貼
VA ... Win x86 大多是 4G , Win 7 後的 x64 大多是 128G ... ( Win7 之前的 x64 好像大多是 64G )
其它版本要上網查才知道 ... 例如
https://support.microsoft.com/zh-tw/kb/2160852
如果有看懂...就可以猜出... VA 其實就是 Win x86 為啥只能用 4G 的原因... 就是因為 VA 的限制
同理... 如果 PAE 可以用 1024G (40bit) ... 插了 RAM 512G ...
就算用 win7 x64... Win7 的 VA 也只到 128G ... 128G 後面也會和 x86 4G 情況一樣 ... Win記憶體管理 不會去用
但不是不能用...透過 PAE 應該還是可以用 ... 就像 x86 用 PAE 一樣可以用 4G 後
簡單說 PAE 看 CPU PAE bit
VA 看 Win 的 版本 ...
6. DMA 維基
這的確和 MMIO 有關 ... ( 英文版的 維基 MMIO 有提到 DMA )
DMA 只是一種硬體技術...照維基的說明...簡單說就是
可以獨立地直接讀寫系統記憶體,而不需中央處理器(CPU)介入處理
所以如果用 DMA 做 MMIO 的存取... 就比較不會增加 CPU 的負擔...
7. 這個我看不懂你要表達的意思
一個進程先經過PAE(這個我是確定的),之後要不要經過mmio?應該是要的。那麼我暫時理解為:PAE->mmio-> A(物理內存地址)。
Win程式 用的 記憶體 要嘛就丟給 Win記憶體管理 來管理 ( VA )
要嘛向 Win記憶體管理 要 Physical Memory 來用 ...
要嘛...不透過 Win記憶體管理 ... 直接存取 PA
所以... Win程式 要看怎麼寫
注意 Physical Memory 是用 PA ... 但在 Win記憶體管理 是用 VA ...只是 VA 會映射到 PA ... Win VA > Physical Memory Address
以下 WinAPI 的部份 是個人推測
A. 一般的程式 ... 和 Win 要 VA 來用
程式 -> Win 記憶體(WinAPI) -> VA - > PA/PAE 或 PF
程式 用的是 VA ... 無法控制用的 PA/PAE
B. 和 Win 要 記憶體時...限定 VA 用 Physcial Memory
程式 -> Win 記憶體(WinAPI) -> VA -> PA/PAE
C. 直接存取 PA/PAE
程式 -> WinAPI(直接存取PA/PAE API) -> PA/PAE
其中... A 和 B ... 基本上是透過 Win 的 記憶體管理 ... 所以不會去用到 MMIO
C 的話...因為不是透過 Win 記憶體管理 ... 就有可能存取到 MMIO
8. Driver 最終還是用 硬體 IO ... IO Port 和 MMIO
IO Port 和 MMIO 只是一種方式 ... Driver 是這個方式的 運作流程(方法)
Driver 和 Ramdisk 也一樣 程式
所以記憶體使用...一樣要看程式怎麼寫
例如 你查到的
是用 MMIO 來達成的... 但不能保證每一個 Ramdisk 程式都用一樣的方法
另外...用 MMIO 來達成...也要看 Ramdisk 使用 MMIO 時...用的 PA 範圍... 如果和別的 硬體 MMIO 有 重覆 或是 該位址無用... 可能就會造成問題
該文章寫的還滿清楚的
好吧,那么如果ramdisk强行去读写错误的地址空间会如何呢? 简单地说: cpu不会报错, 但是结果是不可预料的, 比如如果这段地址空间根本是一个memory hole,那么往里面写东西就是白写,读操作返回的有可能都是0xFFFFFFFF, 这样地话,作为一个虚拟磁盘而言,其结果就是数据损坏.
更为严重的是:如果有一块特殊的硬件的io空间映射在4g以上的一段地址,而ramdisk强行去写入数据,就会直接对那块硬件进行io操作,有可能会损坏硬件或者发生更奇怪的事情,比如该设备莫名其妙开始工作了等等.
不過...我個人覺的...Driver 未必不能查知...其它 MMIO 或 PA 的情況
不然 裝置管理員 或 msinfo32(MMIO) 和 RAMMAP(RAM PA) 是假的嗎
第一: 作为驱动程序,你是无法确切地知道究竟哪段物理地址空间里面是映射的你的多余的内存,目前的bios架构中,只有通过中断int 25, function 0xE820才能获知, 而这个bios中断只能在实模式下调用,也就是说windows启动之后,驱动程序是无法调用这个中断去获知的. 那么,ramdisk驱动就只能靠猜, 比如说他可以知道你装了4gb内存,而目前只认了3.5gb, 那么多出来的512m应该在4g-4.5g这个物理地址段.
當然我不會寫 Driver ... 也許 Driver 編寫時...有所限制也有可能
9.
最後關於ramdisk的問題。會不會被分頁,你說的兩種方式,我這邊沒有碰到。對於我32位系統,我主要關心的是 (1.分配系統已識別內存) 和 (2.分配未識別內存) 這兩種情況,不太清楚你說的Physical 和 Virtual 這兩種情況。你說Virtual 就是“向 Win 要記憶體”,那麼請問,我那200MB的“Driver Locked”部分是不是“向 Win 要的記憶體”?從各方面的信息來看,我都認為這種內存是 不會 被寫入分頁文件的,因此應該是對應了你所說的“1. 用 Physical Memory (Address) ”這個情況。但是我同時注意到了這一個情況,就是,這部分內存是佔用Task Manager中的“已佔用”內存的。那麼是不是應該說,也是“向 Win 要的記憶體”呢?
我們在rammap中看得到的各種信息,從各種Usage(包括左邊那一列的Process Private、Page Table、Driver Locked等)到各種List(上面那一行的Active、Standby、Free、Bad等),都應該算作是windows系統控制之下的吧?
一般來說 RAMDISK 都用 RAM PA ...
只差在用什麼方法去使用 RAM PA ... (是用 VA 中的 RAM PA 還是 非VA 的部份 ... 這個後面會補充)
而你說的 1.分配系統已識別內存 和 2.分配未識別內存 ...
我個人覺的你要表達的其實是 VA 和 非 VA 部份
也就是假定
CPU PAE 64G (36bit) , RAM 8G , Win x86 ... VA 4G
實際上 Win ... PA 最多還是可以用到 64G ... 只是被 VA 限制了
所以你覺的 1.分配系統已識別內存 ... 是 4G ... 這其實是 VA
也就是 PA(PAE) > VA , 且 RAM > VA
VA 只會使用 RAM PA 中的一部份...所以你會覺的是 1.分配系統已識別內存 和 2.分配未識別內存
VA/PA ... 4G/64G ... 非VA ... 58G/64G
VA/RAM ... 4G/8G ... 非VA ... 4G/8G
實際上 RAM 系統還是有識別到 8G ... 只是 Win 有沒有拿來用而以...有沒有配置 到 VA ... 而不是 4G 未識別
而 x64 只是 VA 比較大 ... 例如 Win7 VA 到 128G
那情況就變成
VA/PA 128G/64G ... 非 VA 0G
VA/RAM 128G/8G ... 非 VA 0G
所以會感覺 沒有 未識別
而 x86 RAMDISK PAE
只是把 非VA 部份... 也就是 Win 沒用到的 RAM ... 拿來用而以
至於向 Win 要 記憶體 ... 我前面說了可以 VA 也可以 PA (RAM PA) ...
或者可以說...2者都是 VA ...只是 VA 限定使用 RAM PA ... 這裡或者說成 Physical Memory 比較好解理
其中要注意的是
向 Win 要 記憶體 ... 就算指定用 Physical Memory ... 用的應該是也 VA 中的 Physical Memory
也就是
VA/RAM ... 4G/8G ... 非VA 4G/8G ...
如果是向 Win 要PA 記憶體(RAM PA) ...用的也是 前面 VA 4G 的部份... 而不是 非VA 4G 的部份
所以如果用 非VA 部份...一般是直接存取 PA (RAM PA)
VA , RAM , PA(PAE) 的關係 ... ( 以下 G 大小以上面假設為例 )
VA ... 使用 RAM (VA 4G/8G) 或 Page File (PF)
RAM ... 使用 PA/PAE 來定址 8G
PA/PAE... CPU 最大定址 64G
非VA RAM ... Win VA 沒用的 RAM (非VA 4G/8G)
Driver 因為一直都要用... 一般應該都是用 Physical Memory (RAM) ... 所以應該不會被 分頁
也許 Win 記憶體 管理上 當載入 Driver 時... 配置的都是 Physical Memory
不過 這也只是指 Driver 程式本身 ... 程式調用的 記憶體 另外算 ... 這部份就看程式怎麼寫
就像 一般程式... 程式本身 也是要放到記憶體... 但 程式 會去調用記憶體
例如
ramdisk 可能才 幾百K 或 幾M ... ramdisk 程式本身 ... 如果是 Driver 方式載入... 可能 ramdisk 程式本身 的 幾M 會放到 Physical Memory
但 ramdisk程式 調用來做 ramdisk ... 的 記憶體...就看使用的方法...未必會是 Physical Memory
但是...通常 Ramdisk 都是用 Physical Memory ...
而用 Physical Memory 時...看方式是調用 VA 中的 Physical Memory ... 或是
直接存取 PA (RAM PA) ... 即可以使用 非VA 的部份
最後以上只是個人的依資料的推測判斷...另外文章打太長也可能有些 筆誤 或 詞不達意 (前後修改了好幾次)
說一堆...覺的你可能只會越搞越混... 來點實際的可能你反而好理解
例如... 你的 筆電 RAM 2G ... 想插到 6G
先假設你 CPU 有 PAE ... 那情況就是
PAE ... 最小 64G ( PA 36bit )
RAM ... 6G
Win x86 ... VA 4G
A. 在 MMIO 和 RAM 衝突...沒用 ReMap 情況下
RAM PA ... PA 0 - 6G
VA PA ... PA 0 - 4G
MMIO PA ... PA 3.5G - 4G
那情況就是
VA ... 只能用 PA 0 - 3.5G ... 3.5G (RAM)
MMIO ... 用了 PA 3.5G - 4G ... 0.5G (RAM 但被 MMIO 佔用)
非VA ... PA 4G - 6G ... 2G (RAM)
若用 RAMDISK PAE ... 用 非VA 的話...可以開 2G RAMDISK ... PA 4G - 6G
所以...沒 ReMap ... RAM 會浪費掉 0.5 G 被 MMIO 佔用
若 RAMDISK 是向 Win 要 記憶體 , 並限定要 Physical Memroy ...
那用的是 VA 中的 Physical Memroy ... 也就是 VA 3.5G 的部份... 而非 非VA ... PA 4G - 6G 的 2G
B. 在 MMIO 和 RAM 衝突...用 ReMap 情況下
RAM PA ... ReMap ... PA 0 - 2G , PA 4G - 8G
VA PA ... PA 0 - 4G
MMIO PA ... PA 3.5G - 4G
那情況就是
VA ... 只能用 PA 0 - 2G ... 2G (RAM)
MMIO ... 用了 PA 3.5G - 4G ... 0.5G (MMIO)
非VA ... PA 4G - 8G ... 4G (RAM)
Win(VA) 只有 2G 可用
若用 RAMDISK PAE ... 用 非VA 的部份話...可以開 4G RAMDISK ... PA 4G - 8G
因為 ReMap ... 所以 RAM 不會 被 MMIO 佔用 0.5 G... (因為佔用的 PA ... ReMap 錯開了)
若 RAMDISK 是向 Win 要 記憶體 , 並限定要 Physical Memroy ...
那用的是 VA 中的 Physical Memroy ... 也就是 VA 2G 的部份... 而非 非VA ... PA 4G - 8G 的 4G
所以基本上...除非你遇到 硬體 比較 怪異... MMIO 在 PA 4G 以後...
然後 RAMDISK 又沒避開 MMIO 的部份... 才會造成問題
不然 RAMDISK 請安心使用...
至於 Win x64 要用 RAMDISK
因為通常沒用 非VA 的部份 ... 因為 VA 最大 128G
無 ReMap
RAM PA ... PA 0 - 6G
VA PA ... PA 0 - 6G ...
MMIO PA ... PA 3.5G - 4G
Ram 可用 5.5G .... 沒有 非VA
有 ReMap
RAM PA ... ReMap ... PA 0 - 2G , PA 4G - 8G
VA PA ... PA 0 - 2G , PA 4G - 8G
MMIO PA ... PA 3.5G - 4G
Ram 可用 6G .... 沒有 非VA
所以在 x64 上...用 VA 限定 Physical Memory 方式的 RAMDISK 就可以
要用 非VA RAMDISK ... 也沒有 非VA 的可用...
補個 PA 示意圖
上圖的 VA & RAM ... 還要減去 MMIO ... Win 記憶體管理 不會去用 MMIO 的部份
RAMDISK 若是 透過 Win記憶體管理...是用 VA 部份 ...
反之 若是直接存取 PA(PAE)... 可以去用 非VA 部份( 其實應該說...整個PA 都可以...包含VA部份 )
直接存取 PA ... 除非保證 PA 位址是 RAM ... 而且 沒有其它用途 (簡單說就是 非VA + RAM 部份...而且沒在用...)
否則可能會造成問題
不過前面也說了...除非 硬體 比較 怪異... MMIO 在 PA 4G 以後... 不然通常沒問題
因為 若是有 非VA ... RAMDISK 可以用 直接存取PA(PAE) 去用 ... 非VA 部份
若沒有 非VA (即 VA 夠大...包含所有 RAM 的部份) ...
則 RAMDISK 只要能向 Win記憶體管理 要求 配置固定使用 Physical Memory ... 而不會被分頁... 就好了
因為 Win記憶體管理 本身就不會去用 MMIO 的部份
簡單說就是 RAMDISK 可以用什麼方式 或 可以怎麼設定
x86 中... VA < RAM ... 可以用 RAMDISK PAE (直接存取 PA/PAE) ... 使用 非VA (Win 未管理) 部份 的 RAM 來建立 RAMDISK
x64 中... VA > RAM ... 用一般的 RAMDISK 方式就好 ... (通常應該是 向Win 要求 配置固定使用 Physical Memory ... 而不會被分頁)
如果向 Win 要求 記憶體時 不是 配置固定的 Physical Memory ... 也就是可能會 被分頁 ... 就不適合放 Page File
總結一句話...全看 RAMDISK 怎麼搞 RAM 而以...
|