PCI裝置的地址空間 【轉】
PCI配置空間(PCI Configuration Space)
圖 1. 標準 PCI 匯流排的組織結構圖
PCI裝置(PCI device)都有一個配置空間,大小為256位元組,實際上是一組連續的暫存器,位於裝置上。配置空間的前64位元組是配置空間起始段,它對於每種型別的裝置都是相同的。顯示了PCI 裝置的配置空間起始段。
其中頭部64位元組是PCI標準規定的,格式如下:
圖 2. PCI 裝置的配置空間起始段
還有PCI網橋的地址空間:
圖 3. PCI 橋的配置空間起始段
剩餘的部分是PCI裝置自定義的。
PCI配置空間頭部有6個BAR(Base Address Registers),BAR記錄了裝置所需要的地址空間的型別(memory space或者I/O space),基址以及其他屬性。BAR的格式如下:
可以看出,裝置可以申請兩類地址空間,memory space和I/O space,它們用BAR的最後一位區別開來。
說到地址空間,計算機系統中,除了我們常說的memory address(包括邏輯地址、虛擬地址(線性地址)、CPU地址(實體地址)),還有I/O address,這是為了訪問I/O裝置(主要是裝置中的暫存器)而設立的,大部分體系結構中,memory address和I/O address都是分別編址的,且使用不同的定址指令,構成了兩套地址空間,也有少數體系結構將memory address和I/O address統一編址(如ARM)。
有兩套地址空間並不意味著計算機系統中需要兩套地址匯流排,實際上,memory address和I/O address是共用一套地址匯流排,但通過控制匯流排上的訊號區別當前地址匯流排上的地址是memory address還是I/O address。北橋晶片(Northbridge,Intel稱其Memory Controller Hub,MCH)負責地址的路由工作,它內部有一張address map,記錄了memory address,I/O address的對映資訊,一個典型的address map如圖:
我們來看北橋是如何進行地址路由的。根據控制匯流排上的訊號,北橋首先可以識別地址屬於memory space還是I/O space,然後分別做處理。
比如若是memory space,則根據address map找出目標裝置(DRAM或Memory Mapped I/O),若是DRAM或VGA,則轉換地址然後傳送給記憶體控制器或VGA控制器,若是其它I/O裝置,則傳送給南橋。
若是I/O space,則傳送給南橋(Southbridge,Intel稱其I/O Controller Hub,ICH),南橋負責解析出目標裝置的bus, device, function號,併傳送資訊給它。
PCI裝置會向計算機系統申請很多資源,比如memory space, I/O space, 中斷請求號等,相當於在計算機系統中佔位,使得計算機系統認識自己。
PCI裝置可以通過兩種方式將自己的I/O儲存器(Registers/RAM/ROM)暴露給CPU:
在memory space申請地址空間,或者在I/O space申請地址空間。
這樣,PCI裝置的I/O儲存器就分別被對映到CPU-relative memory space和CPU-relative I/O space,使得驅動以及作業系統得以正常訪問PCI裝置。對於沒有獨立I/O space的體系結構(如ARM),memory space和I/O space是統一編址的,也就是說memory space與I/O space等價了,這時,即使PCI裝置在BAR表明了要申請I/O space,實際上也是分配在memory space的,所以驅動無法使用I/O埠指令訪問I/O,只能使用訪存指令。在Windows驅動開發中,PCM_PARTIAL_RESOURCE_DESCRIPTOR記錄了為PCI裝置分配的硬體資源,可能有CmResourceTypePort,
CmResourceTypeMemory等,後者表示一段memory地址空間,顧名思義,是通過memory space訪問的,前者表示一段I/O地址空間,但其flag有CM_RESOURCE_PORT_MEMORY和CM_RESOURCE_PORT_IO兩種,分別表示通過memory space訪問以及通過I/O space訪問,這就是PCI請求與實際分配的差異,在x86下,CmResourceTypePort的flag都是CM_RESOURCE_PORT_IO,即表明PCI裝置請求的是I/O地址空間,分配的也是I/O地址空間,而在ARM或Alpha等下,flag是CM_RESOURCE_PORT_MEMORY,表明即使PCI請求的I/O地址空間,但分配在了memory
space,我們需要通過memory space訪問I/O裝置(通過MmMapIoSpace對映實體地址空間到虛擬地址空間,當然,是核心的虛擬地址空間,這樣驅動就可以正常訪問裝置了)。
為了為PCI裝置分配CPU-relative space,計算機系統需要知道其所申請的地址空間的型別、基址等,這些資訊記錄在裝置的BAR中,每個PCI配置空間擁有6個BAR,因此每個PCI裝置最多能對映6段地址空間(實際很多裝置用不了這麼多)。PCI配置空間的初始值是由廠商預設在裝置中的,於是裝置需要哪些地址空間都是其自己定的,可能造成不同的PCI裝置所對映的地址空間衝突,因此在PCI裝置列舉(也叫匯流排列舉,由BIOS或者OS在啟動時完成)的過程中,會重新為其分配地址空間,然後寫入PCI配置空間中。
通過memory space訪問裝置I/O的方式稱為memory mapped I/O,即MMIO,這種情況下,CPU直接使用普通訪存指令即可訪問裝置I/O。
通過I/O space訪問裝置I/O的方式稱為port I/O,或者port mapped I/O,這種情況下CPU需要使用專門的I/O指令如IN/OUT訪問I/O埠。
常見的MMIO例子有,VGA card將framebuffer對映到memory space,NIC將自己的片上緩衝對映到memory space,實際上,最典型的MMIO應該是DRAM,它將自己的儲存空間對映到memory space,是佔用CPU地址空間最多的“裝置”。
相關文章
- 裝置地址
- 程式地址空間
- Linux新增裸裝置空間(Redhat)LinuxRedhat
- linux 使用裸裝置建立表空間Linux
- 裸裝置表空間對映檔案
- PCIE配置和地址空間
- [轉]用裸裝置擴資料庫表空間專題(完整版)資料庫
- linux下使用裸裝置建立oracle表空間LinuxOracle
- aix5.3上使用裸裝置建立表空間AI
- 環境變數和地址空間變數
- 管理表空間(表空間的屬性)轉貼
- AIX 5.3 10.2g rac環境下 給表空間擴容(裸裝置表空間)AI
- HPUNIX下表空間檔案系統到裸裝置測試
- logrotate 不支援不同裝置間的日誌轉儲logrotate
- 網路裝置配置與管理————17、網路地址轉換NAT
- "物聯網"智慧家居裝置有可能侵犯你最私密的家庭空間
- 程式的虛擬地址空間——NULL指標分割槽Null指標
- Linux下PCI轉串列埠卡驅動安裝方法Linux串列埠
- 安裝Red Hat Linux 9最小磁碟空間(轉)Linux
- 我的硬碟空間哪去了?(轉)硬碟
- 國產處理器龍芯地址空間詳解
- android 獲取裝置IP和Mac地址AndroidMac
- 06、配置裝置忽略報文目的MAC地址Mac
- linux下表空間檔案系統移動到裸裝置測試Linux
- oracle10g的sysaux空間暴增與空間回收-轉載OracleUX
- C++名稱空間的使用 (轉)C++
- 安裝Oracle後,經常使用的修改表空間的SQL程式碼(轉)OracleSQL
- 將字典管理表空間轉換為本地管理表空間
- 2-色彩空間轉換
- [轉移]ORACLE MOVE 表空間Oracle
- 轉移表空間到ASMASM
- JAXB玩轉名稱空間
- 從system/sysaux空間轉移TABLE&Index到其它表空間UXIndex
- oracle 裸裝置(轉載)Oracle
- Linux下即插即用裝置的安裝(轉)Linux
- 安裝XP時PCI.SYS報錯
- Windows外殼名字空間的瀏覽 (轉)Windows
- 虛擬空間的陷阱--對微軟的檄文 (轉)微軟