Intel主板的佈局,系統的內存映射

本文作者:原理君

微信公眾號:技術原理君

​我打算從這篇文章開始寫一系列關於計算機內幕的文章,旨在揭示現代操作系統內核的工作原理。我希望能對熱愛內核的粉絲們有所幫助。我是一個熱愛Linux內核的程序員,我之前一直在編碼一線,寫過超過10萬行代碼。

這篇文章主要講述了Intel主板的佈局,CPU是如何訪問內存的,以及系統的內存映射是怎樣的?

Intel主板的佈局,系統的內存映射

先來熱個身吧,讓我們先看看現如今Intel計算機組成吧。下圖展示了主板上的主要組件:


Intel主板的佈局,系統的內存映射

現代主板的示意圖,北橋和南橋構成了芯片組(來源外國小哥的博客)


當你看圖時,請牢記一個至關重要的事實:CPU一點也不知道它連接了什麼東西。CPU僅僅通過一組針腳與外界交互,它並不關心外界到底有什麼。可能是一個電腦主板,但也可能是導彈,網絡路由器,植入腦內的設備,或CPU測試工作臺。CPU主要通過3種方式與外界交互:內存地址空間,I/O地址空間,還有中斷。

眼下,我們只關心主板和內存。安裝在主板上的CPU與外界溝通的門戶是前端總線(front-side bus),前端總線把CPU與北橋連接起來。每當CPU需要讀寫內存時,都會使用這條總線。CPU通過一部分管腳來傳輸想要讀寫的物理內存地址,同時另一些管腳用於發送將被寫入或接收被讀出的數據。一個Intel Core 2 QX6600有33個針腳用於傳輸物理內存地址(可以表示233個地址位置),64個針腳用於接收/發送數據(所以數據在64位通道中傳輸,也就是8字節的數據塊)。這使得CPU可以控制64GB的物理內存(233個地址乘以8字節)。

現在到了最難理解的部分。我們可能曾經認為內存指的就是RAM,被各式各樣的程序讀寫著。的確,大部分CPU發出的內存請求都被北橋轉送給了RAM管理器,但並非全部如此。物理內存地址還可能被用於主板上各種設備間的通信,這種通信方式叫做內存映射I/O。這類設備包括顯卡,大多數的PCI卡(比如掃描儀或SCSI卡),以及BIOS中的flash存儲器等。

當北橋接收到一個物理內存訪問請求時,它需要決定把這個請求轉發到哪裡:是發給RAM?抑或是顯卡?具體發給誰是由內存地址映射表來決定的。映射表知道每一個物理內存地址區域所對應的設備。絕大部分的地址被映射到了RAM,其餘地址由映射表來通知芯片組該由哪個設備來響應此地址的訪問請求。這些被映射為設備的內存地址形成了一個經典的空洞,位於PC內存的640KB到1MB之間。當內存地址被保留用於顯卡和PCI設備時,就會形成更大的空洞。這就是為什麼32位的操作系統無法使用全部的4GB RAM。Linux中,/proc/iomem這個文件簡明的列舉了這些空洞的地址範圍。下圖展示了Intel PC低端4GB物理內存地址形成的一個典型的內存映射:

Intel主板的佈局,系統的內存映射

Intel系統中,低端4GB內存地址空間的佈局。

實際的地址和範圍依賴於特定的主板和電腦中接入的設備,但是對於大多數Core 2系統,情形都跟上圖非常接近。所有棕色的區域都被設備地址映射走了。記住,這些在主板總線上使用的都是物理地址。在CPU內部(比如我們正在編寫和運行的程序),使用的是邏輯地址,必須先由CPU翻譯成物理地址以後,才能發佈到總線上去訪問內存。

這個把邏輯地址翻譯成物理地址的規則比較複雜,而且還依賴於當時CPU的運行模式(實模式,32位保護模式,64位保護模式)。不管採用哪種翻譯機制,CPU的運行模式決定了有多少物理內存可以被訪問。比如,當CPU工作於32位保護模式時,它只可以尋址4GB物理地址空間(當然,也有個例外叫做物理地址擴展,但暫且忽略這個技術吧)。由於頂部的大約1GB物理地址被映射到了主板上的設備,CPU實際能夠使用的也就只有大約3GB的RAM(有時甚至更少,我曾用過一臺安裝了Vista的電腦,它只有2.4GB可用)。如果CPU工作於實模式,那麼它將只能尋址1MB的物理地址空間(這是早期的Intel處理器所支持的唯一模式)。如果CPU工作於64位保護模式,則可以尋址64GB的地址空間(雖然很少有芯片組支持這麼大的RAM)。處於64位保護模式時,CPU就有可能訪問到RAM空間中被主板上的設備映射走了的區域了(即訪問空洞下的RAM)。要達到這種效果,就需要使用比系統中所裝載的RAM地址區域更高的地址。這種技術叫做回收(reclaiming),而且還需要芯片組的配合。

參考

https://manybutfinite.com/

相關推薦

推薦中...