0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

內(nèi)存是怎么映射到物理地址空間的?內(nèi)存是連續(xù)分布的嗎?

冬至子 ? 來源:UEFI社區(qū) ? 作者:wolf uefiblog ? 2023-06-30 15:59 ? 次閱讀

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

物理地址空間

一個(gè)典型的物理地址空間是這樣的:

圖片

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

圖片

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

Low MMIO和High MMIO

Low MMIO結(jié)構(gòu)如下圖:

圖片

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

1.Boot Vector的空間是BIOS內(nèi)容映射的地址,它的大小是可以調(diào)節(jié)的,為了滿足不同大小的BIOS。

2.Local APIC是APIC中斷模式各個(gè)內(nèi)核local APIC寄存器的映射地址。

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

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

Low DRAM和High DRAM

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

圖片

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

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

1MB以下比較特殊,里面全部都是已經(jīng)被淘汰的傳統(tǒng)BIOS和DOS關(guān)心的內(nèi)容,我們叫它DOS Space或者Legacy Region:

圖片

在那里,我們習(xí)慣用傳統(tǒng)的實(shí)模式地址來劃分它們的具體內(nèi)容:

1.0~640KB,傳統(tǒng)DOS空間。

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

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

4.E段和F段,BIOS空間的Lower和Upper映射地址。BIOS的rom內(nèi)容也會(huì)被映射到這里,方便Legacy BIOS實(shí)模式跳轉(zhuǎn)到保護(hù)模式。

內(nèi)存的Interleave

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

什么是Interleaving?簡單來說,就是讓內(nèi)存交錯(cuò)起來,如下面的動(dòng)圖:

圖片

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

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

物理地址到內(nèi)存單元的反推

BIOS實(shí)際上一手導(dǎo)演的內(nèi)存的分配,它當(dāng)然可以從任何物理地址反推回內(nèi)存的單元地址。我們可以用下面一組數(shù)據(jù)來唯一確定某個(gè)內(nèi)存單元:

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

在內(nèi)存分配表缺失的情況下,BIOS甚至可以通過它填過的寄存器重建這個(gè)映射表。但實(shí)際上BIOS并不希望一般用戶知道這些信息,因?yàn)橛邪踩詥栴}。

暴露內(nèi)存信息容易招來內(nèi)存?zhèn)刃诺拦簦⊿ide Channel),比較有名的有Row hammer攻擊。簡單的來說它是通過反復(fù)寫某個(gè)內(nèi)存單元,借助內(nèi)存的特性,希望影響相鄰Row/Column的內(nèi)容。

有些情況確實(shí)需要知道這些信息,就是內(nèi)存出錯(cuò)的時(shí)候。和大家想象的不同,內(nèi)存是會(huì)出錯(cuò)的。尤其云服務(wù)器中內(nèi)存的出錯(cuò)是十分頻繁的。出錯(cuò)起來也千奇百怪,開始可能是偶爾的隨機(jī)錯(cuò)誤,經(jīng)過ECC等校正后,就再也不會(huì)復(fù)現(xiàn);而有時(shí)是某個(gè)Bit總是出錯(cuò),進(jìn)而慢慢的整個(gè)row、column或者相鄰的cell開始出錯(cuò),從可以糾正的錯(cuò)誤變成不可修正的錯(cuò)誤,導(dǎo)致服務(wù)器必須停機(jī)。這時(shí)候就必須知道哪個(gè)內(nèi)存壞了,進(jìn)而換掉它。

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

如何關(guān)掉Interleaving

對內(nèi)存有特殊需求的朋友,如果希望內(nèi)存連續(xù),可以在BIOS里面關(guān)閉所有的Interleaving來達(dá)成這個(gè)目標(biāo):

圖片

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

結(jié)論

BIOS作為內(nèi)存的大管家,也負(fù)責(zé)內(nèi)存的分配和映射memory map。它會(huì)把這些信息通過E820, GetMemoryMap函數(shù)和SMBIOS傳遞給操作系統(tǒng)。操作系統(tǒng)在此基礎(chǔ)上再建立頁表,產(chǎn)生虛擬地址。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5359

    瀏覽量

    120812
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    595

    瀏覽量

    27451
  • DRAM芯片
    +關(guān)注

    關(guān)注

    1

    文章

    84

    瀏覽量

    18038
  • PCIe接口
    +關(guān)注

    關(guān)注

    0

    文章

    120

    瀏覽量

    9759
  • DOS系統(tǒng)
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    1414
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    鴻蒙內(nèi)核源碼分析:物理地址映射

    MMU的本質(zhì) 虛擬地址(VA):就是線性地址,鴻蒙內(nèi)存部分全是VA的身影,是由編譯器和鏈接器在定位程序時(shí)分配的,每個(gè)應(yīng)用程序都使用相同的虛擬內(nèi)存地址
    的頭像 發(fā)表于 11-03 10:28 ?2127次閱讀

    操作系統(tǒng)中的邏輯地址物理地址

    本文是關(guān)于操作系統(tǒng)中邏輯地址物理地址之間的區(qū)別。計(jì)算機(jī)操作系統(tǒng)中的內(nèi)存使用兩種不同類型的地址;物理地址
    發(fā)表于 09-14 14:26 ?4094次閱讀

    EC SRAM映射到CPU Memory空間的共享內(nèi)存設(shè)計(jì)

    ShareMemory,顧名思義就是共享內(nèi)存。這個(gè)概念在很多計(jì)算機(jī)系統(tǒng)中都存在,本文特指 EC SRAM 映射到 CPU Memory 空間的共享內(nèi)存設(shè)計(jì)。
    的頭像 發(fā)表于 11-18 15:11 ?1740次閱讀
    EC SRAM<b class='flag-5'>映射到</b>CPU Memory<b class='flag-5'>空間</b>的共享<b class='flag-5'>內(nèi)存</b>設(shè)計(jì)

    為什么MMU的地址映射物理地址會(huì)跳變?

    關(guān)于MMU的地址映射,32位的cpu有4G的虛擬地址空間,將它分為4096個(gè)小塊,每個(gè)小塊是1M,用描述符進(jìn)行虛擬地址
    發(fā)表于 08-22 05:45

    關(guān)于ARM的統(tǒng)一編制與內(nèi)存映射機(jī)制

    中很大一部分是留給內(nèi)存條中的內(nèi)存的,但也常被映射到其他存儲(chǔ)器上(如顯存、BIOS等)。在程序指令中的虛擬地址經(jīng)過段映射和頁面
    發(fā)表于 10-23 15:53

    【HarmonyOS】虛擬地址<->物理地址是如何映射

    MMU的本質(zhì)虛擬地址(VA): 就是線性地址, 鴻蒙內(nèi)存部分全是VA的身影, 是由編譯器和鏈接器在定位程序時(shí)分配的,每個(gè)應(yīng)用程序都使用相同的虛擬內(nèi)存地址
    發(fā)表于 11-03 16:20

    鴻蒙內(nèi)核源碼分析(內(nèi)存映射篇):虛擬地址物理地址之間是如何映射

    MMU的本質(zhì)虛擬地址(VA): 就是線性地址, 鴻蒙內(nèi)存部分全是VA的身影, 是由編譯器和鏈接器在定位程序時(shí)分配的,每個(gè)應(yīng)用程序都使用相同的虛擬內(nèi)存地址
    發(fā)表于 11-19 10:52

    ARM32 Linux的內(nèi)存布局

    Kernel維護(hù)的,所以Kernel可以決定1GB的虛擬地址空間具體映射到什么物理地址。但是不管Kernel怎么映射,最多也只能
    發(fā)表于 04-24 14:20

    Linux虛擬內(nèi)存物理內(nèi)存的深刻分析

    內(nèi)存地址,這是有獨(dú)立內(nèi)存空間的好處當(dāng)不同的進(jìn)程使用同樣的代碼時(shí),比如庫文件中的代碼,物理內(nèi)存中可以只存儲(chǔ)一份這樣的代碼,不同的進(jìn)程只需要把自己的虛擬
    發(fā)表于 05-31 08:00

    IO端口與IO內(nèi)存區(qū)別詳解

    地址的概念 1)物理地址:CPU地址總線傳來的地址,由硬件電路控制其具體含義。物理地址中很大一部分是留給
    發(fā)表于 01-17 12:40 ?1947次閱讀
    IO端口與IO<b class='flag-5'>內(nèi)存</b>區(qū)別詳解

    鴻蒙內(nèi)核中虛擬地址物理地址之間是如何映射

    虛擬地址(VA):?就是線性地址?鴻蒙內(nèi)存部分全是VA的身影?是由編譯器和鏈接器在定位程序時(shí)分配的,每個(gè)應(yīng)用程序都使用相同的虛擬內(nèi)存地址空間
    發(fā)表于 11-19 14:45 ?9次下載
    鴻蒙內(nèi)核中虛擬<b class='flag-5'>地址</b>與<b class='flag-5'>物理地址</b>之間是如何<b class='flag-5'>映射</b>的

    詳解io端口與io內(nèi)存

    (一)地址的概念 1)物理地址:CPU地址總線傳來的地址,由硬件電路控制其具體含義。物理地址中很大一部分是留給
    發(fā)表于 02-11 15:37 ?0次下載
    詳解io端口與io<b class='flag-5'>內(nèi)存</b>

    Linux內(nèi)存映射的原理

    物理地址是處理器在系統(tǒng)總線上看到的地址。使用RISC的處理器通常只實(shí)現(xiàn)一個(gè)物理地址空間,外圍設(shè)備和物理內(nèi)
    的頭像 發(fā)表于 01-15 09:55 ?2129次閱讀

    Linux虛擬地址空間物理地址空間的關(guān)系

    很多人接觸Linux的內(nèi)存管理是從malloc()這個(gè)C語言庫函數(shù)開始,也是從那時(shí)開始就知道了虛擬內(nèi)存的概念。但很多人可能并不知道虛擬地址是如何轉(zhuǎn)換成物理地址的,今天帶你搞懂虛擬
    的頭像 發(fā)表于 10-08 11:40 ?1229次閱讀
    Linux虛擬<b class='flag-5'>地址</b><b class='flag-5'>空間</b>和<b class='flag-5'>物理地址</b><b class='flag-5'>空間</b>的關(guān)系

    linux系統(tǒng)查看物理地址

    將從基礎(chǔ)知識(shí)開始,逐步介紹高級(jí)技術(shù)。 什么是物理地址 物理地址是指訪問計(jì)算機(jī)內(nèi)存或其他硬件設(shè)備時(shí)使用的真實(shí)物理位置。在計(jì)算機(jī)系統(tǒng)中,每個(gè)設(shè)備都有一個(gè)唯一的
    的頭像 發(fā)表于 11-16 16:47 ?3573次閱讀