日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

 

如果我們將兩個4G內存插入內存插槽,得到的內存地址空間是0到8G嗎?是不是0到4G是第一根內存,4到8G是第二根內存呢?實際情況相差甚遠,內存在物理地址空間的映射是分散的。一部分原因是4G以下有Memory map IO(mmio)空間和PCIe的配置空間,另一個原因是Interleaving會打撒內存地址到各個Channel、DIMM甚至是Rank和bank上。今天我們就一起來了解一下x86系統的地址空間分布。

物理地址空間

一個典型的物理地址空間是這樣的:

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

 

其中只有灰色部分是真正的內存,其余都是MMIO。而內存被分為High DRAM和Low DRAM,如圖:

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

 

為什么要把內存強行分割成兩塊呢?因為歷史的包袱。最早內存都很小,32位的地址(4G)空間看起來永遠也用不完,低地址被分配給內存用,高地址就自然而然被分配用來給Memory map IO。既然已經分給它們了,為了兼容以前的驅動,這一塊就被固定下來。再有內存就只能從4G以上分配了。

Low MMIO和High MMIO

Low MMIO結構如下圖:

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

 

其中有幾塊要特別說明一下:

1.Boot Vector的空間是BIOS內容映射的地址,它的大小是可以調節的,為了滿足不同大小的BIOS。

2.Local APIC是APIC中斷模式各個內核local APIC寄存器的映射地址。

3.PCI ECAM也有叫做PCIBAR,是PCIe配置地址空間的映射地址。它的起始地址可調,臺式機BIOS一般會把它設置得很高,這樣4G以下內存會比較大,方便32位windows使用。舉個例子,如果我們把PCIe BAR(BEGREG)設為0x80000000,那么盡管插了8G DIMM,4G以下也不會超過2G的內存可以使用,而2到8G的真實內存都被映射到在4G地址空間以上了,而這些是32位Windows使用不了的。所以有的主板運行32位操作系統發現可用內存小了一大塊就是這個原因。它的大小可以修改,一般可以設為64MB和128MB。

High MMIO被BIOS保留作為64位mmio分配之用,例如PCIe的64位BAR等。

Low DRAM和High DRAM

4G以下內存最高地址叫做BMBOUND,也有叫做Top of Low Usable DRAM (TOLUD) 。BIOS也并不是把這些都報告給操作系統,而是要在里面劃分出一部分給核顯、ME和SMM等功能:

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

 

紅框中是在low DRAM被“偷”的部分

4G以上的內存最高端叫做Top of Up Usable DRAM (TOUUD) ,再上面就是High MMIO了。

1MB以下比較特殊,里面全部都是已經被淘汰的傳統BIOS和DOS關心的內容,我們叫它DOS Space或者Legacy Region:

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

 

在那里,我們習慣用傳統的實模式地址來劃分它們的具體內容:

1.0~640KB,傳統DOS空間。

2.A段和B段,傳統SMM空間。VGA的MMIO也被映射到這里,可以通過寄存器切換。

3.C段和D段,legacy opROM映射空間和EBDA空間。

4.E段和F段,BIOS空間的Lower和Upper映射地址。BIOS的rom內容也會被映射到這里,方便Legacy BIOS實模式跳轉到保護模式。

內存的Interleave

從前面可以看出內存在地址空間上被拆分成兩塊:Low DRAM和High DRAM。那么在每塊地址空間上分配連續嗎?現代內存系統在引入多通道后,為了規避數據的局部性(這也是Cache為什么起作用的原因)對多通道性能的影響,BIOS基本缺省全部開啟了Interleaving,過去美好的DIMM 0和DIMM 1挨個連續分配的日子一去不復返了。

什么是Interleaving?簡單來說,就是讓內存交錯起來,如下面的動圖:

 

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

來自wikipedia, 參考資料1

這是一個bank層級的模4的interleaving。在桌面電腦上,常見的還有Channel級的、DIMM級的和Rank級的。

服務器上Interleaving更是不可或缺,它的粒度更細,可以達到數十bytes層級的interleave,它和內存的其他特性,如類似磁盤陣列RAID的內存spare, mirror特性,構成了復雜異常的內存映射系統。在BIOS里面,臺式機/筆記本內存映射相對簡單,只有一個大表和數十個寄存器;而在服務器BIOS中,有數個相互關聯的大表和寄存器陣列來解碼(decode)內存的請求,代碼的硬件邏輯也是相當復雜。關于它,我會有一篇專欄文章討論地址譯碼和地址反向解碼,詳細內容那里再說,這里只需要知道,物理內存分布在各個DIMM上就夠了。

物理地址到內存單元的反推

BIOS實際上一手導演的內存的分配,它當然可以從任何物理地址反推回內存的單元地址。我們可以用下面一組數據來唯一確定某個內存單元:

Channel #;DIMM #; Rank #;Bank #;Row #;Column #

在內存分配表缺失的情況下,BIOS甚至可以通過它填過的寄存器重建這個映射表。但實際上BIOS并不希望一般用戶知道這些信息,因為有安全性問題。

暴露內存信息容易招來內存側信道攻擊(Side Channel),比較有名的有Row hammer攻擊。簡單的來說它是通過反復寫某個內存單元,借助內存的特性,希望影響相鄰Row/Column的內容。詳細內容可以參考這里:

內存不刷新會怎樣?有趣的內存物理攻擊和旁路攻擊

有些情況確實需要知道這些信息,就是內存出錯的時候。和大家想象的不同,內存是會出錯的。尤其云服務器中內存的出錯是十分頻繁的。出錯起來也千奇百怪,開始可能是偶爾的隨機錯誤,經過ECC等校正后,就再也不會復現;而有時是某個Bit總是出錯,進而慢慢的整個row、column或者相鄰的cell開始出錯,從可以糾正的錯誤變成不可修正的錯誤,導致服務器必須停機。這時候就必須知道哪個內存壞了,進而換掉它。BIOS的報錯是通過WHEA:

報告給操作系統,但這個信息里面只有物理地址,如何才能知道是哪個內存單元壞了呢?在linux上面可以通過edca(參考資料4),有編程經驗的同學可以通過edca的程序接口(參考資料3),可以得到更加豐富的信息。

如何關掉Interleaving

對內存有特殊需求的朋友,如果希望內存連續,可以在BIOS里面關閉所有的Interleaving來達成這個目標:

內存是怎么映射到物理地址空間的?內存是連續分布的嗎?

 

注意是所有的。之后可以通過SMBIOS來看到內存分布信息(dmidecode)。

結論

BIOS作為內存的大管家,也負責內存的分配和映射memory map。它會把這些信息通過E820, GetMemoryMap函數和SMBIOS傳遞給操作系統。操作系統在此基礎上再建立頁表,產生虛擬地址。

分享到:
標簽:映射 內存
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定