關於內存地址和顯存地址?

原來的8086cpu設計的時候,地址空間有一塊區域(640K-1M)之間,有一塊作為顯存使用,可現在的顯存動不動就2G了,分配給顯存的地址段是不是和8086已經不一樣了?如果是這樣,那現在的cpu地址分配是如何做到和8086兼容的(比如在8086上直接操作顯卡的彙編代碼在現在的機器上也能執行)


反對前面的回答,000B8000這塊內存在保護模式下也是能用的,只不過你們不知道怎麼用。

首先,題主要先明白物理地址和虛擬地址的概念。

wiki應該是打不開,給題主個百度的鏈接:

物理地址_百度百科

原來的8086cpu設計的時候,地址空間有一塊區域(640K-1M)之間,有一塊作為顯存使用

這裡你說的預留的地址,是指物理地址,這一段地址的準確範圍是000A0000-000BFFFF,不管是32位還是64位CPU,這一段物理內存地址一直都保留給顯存使用,不區分32位還是64位,也不區分保護模式還是實模式

以下是我電腦上的截圖(系統環境為Win7 64位,CPU是i7 4770K):

可見這一段內存至今仍然是留給顯卡使用的。

那麼現在為什麼不能直接用這段內存了?

因為現在的軟體都運行在保護模式下,訪問的地址都是虛擬地址,而並非物理地址,包括你使用cmd命令打開的環境,都是虛擬地址,雖然32位XP里能用debug命令向000B8000上寫數據並能顯示在cmd的界面里,但本質上,這都是虛擬出來的

如果要想用這段顯存怎麼辦?

自己寫一個簡易的操作系統,不啟動顯卡的各種圖形加速功能,CPU進入保護模式後在GDT里映射一個4G的數據段,與物理地址一致,那麼向000B8000上寫數據,就會像過去DOS一樣顯示在屏幕上,所以保護模式下也可以訪問這一段內存。所以,保護模式下,也可以用它。

顯卡那麼多顯存是怎麼映射的?

再看截圖:

有很多內存地址被映射給顯存了,就是通過這種映射關係,把一些物理地址留給顯存,使得CPU能像訪問內存一樣訪問顯存資源。

當然,實際情況是,2G顯存未必完全映射,而是只映射一部分地址,顯卡有一些開放的寄存器能夠控制哪部分顯存映射過來,這樣就能使得CPU在使用比較少的物理地址範圍的情況下,訪問全部的顯存。

還有一個很有意思的事情:在虛擬機里,找到映射的高地址部分的第一塊內存區域,寫一個能直接訪問物理地址的程序(比如一個驅動),去讀這一塊內存,然後寫到文件里,再用屏幕截圖,也寫到文件里,會發現截圖的內容和顯存里讀出來的內容基本上是一樣的。


PCIe顯卡內部的存儲RAM和CPU的RAM並不在一個定址域內。有些顯卡會在pci的BAR內可以map出來。VGA mode的顯卡A段和B段也是在設置了VGA 特性後反向地址解碼而來。

pci的基礎知識見我的專欄


那一段地址空間是A0000-BFFFF,現在的X86主機仍然把這一段地址空間分配給顯卡,設備管理器-顯示適配器-資源 分配裡面可以看得到,這個是傳統VGA地址空間。


早就不兼容了,那隻能用於實模式的dos程序。


現在的系統已經跑不了實模式程序了


現在顯卡地址是物理地址,就是跟普通硬體驅動沒啥區別,這個地址一般不會給應用進程可見。至於之前的地址,在bios啟動的時候還是有效的,在沒有進入保護模式之前。進入保護模式之後就看操作系統映射了。cmd是虛擬86模式,操作系統可以把這個物理地址直接映射為虛擬地址,也可以用異常模擬。不是全屏的時候,會使用異常。比如訪問640k一個4位元組,就會觸發訪問異常(設置訪問許可權不可訪問即可),然後根據異常指令,來模擬顯示,用圖形顯示驅動來完成以前dos程序的兼容。

至於定址空間,32位的只有4g,進程的用戶空間一般2g或者3g,操作系統,驅動程序需要1-2g。那麼如何分配這麼大的顯存呢?顯卡驅動在映射內存的時候,可以多次映射,每個線程都有一個映射表,也可以搞多個線程,或者一個線程裡面重新載入映射。比如顯卡是2g,分配的定址空間可能就500m,那麼要4次映射才能完整讀寫2g顯卡。因此32位系統也是可以支持4g顯存的。有的32位系統物理定址是48位的,那麼超過4g內存也是支持。

對於現在大部分64位機器跟操作系統來說,這個映射就更加方便了,虛擬地址空間足夠用了。

以上內容全部來自實踐,大學的時候就寫過一個操作系統內核,包括顯卡驅動。當初費了很大的勁才搞出圖形功能。


這個framebuffer應該只和顯示(display)有關,純2D領域的問題。

顯示(display)有幾套方案,對應幾套寄存器。

從軟體工程師角度理解:最古老的是VGA模式,再接著是VESA模式。在這個層面,是沒有3D的。再接著就是現代的帶MMU模式,此時的所謂的framebuffer,個人理解是沿用傳統的概念,但只是從顯存里划出的一部分專門用於最終顯示(display)的內存,一般這塊內存已經不是bios初始化時劃定的那塊0xbffff物理內存了,剩餘的大量空間,一塊用於mmu本身的配置,另一塊就是可以使用的顯存,用於存放texture,GPU指令等數據,這個一般都是3D來用,暫且不表。

系統啟動的顯示,一般有2個階段,多則3個階段。分別是

1. bios初始化 的vga模式 (實模式)

2. VESA模式 或增強的fb模式 (保護模式)

3.自帶MMU的顯示驅動接管後的fb模式 (保護模式)


這個是歷史遺留下來的,確切說是bios為了提供vesa兼容模式給弄的。在沒有bios的板子上,這個地址自然和圖形沒任何關係。


推薦閱讀:

C 語言是學編程的基礎嗎?
在編程過程中boolean變數一般怎麼命名?
計算機系的學生應該考什麼證?
如何從學術原型代碼拓展成工業級別代碼?
C++語言有什麼方便的GUI開發框架?

TAG:中央處理器CPU | 編程 | 顯卡 | 計算機組成原理 |