天天看點

mpu 配置記憶體空間_PCIE的記憶體位址空間、I/O位址空間和配置位址空間

pci裝置與其它接口的裝置(如i2c裝置)最大的不同是存在記憶體位址空間和配置位址空間

首先區分一下IO空間和記憶體空間

cpu會通路的裝置一般有記憶體和外設寄存器,如下圖所示。x86架構采用獨立編址将記憶體操作與外設IO操作分開了才有了記憶體空間和IO空間的區分,x86平台cpu内部對記憶體和外設寄存器通路的指令也是不同的。arm等其他平台都采用統一編址,不區分記憶體和外設的通路。

IO空間:通路外部裝置寄存器的位址區域,x86平台為64k

記憶體空間:通路記憶體的位址空間,32位平台為4G

mpu 配置記憶體空間_PCIE的記憶體位址空間、I/O位址空間和配置位址空間

pci裝置的記憶體空間是怎麼回事呢?

常見的裝置都隻提供寄存器供cpu通路,對于低速外設這樣的模式是足夠的。但是對于需要大量、高速資料互動的外設就需要引入外設記憶體空間了。在網卡、顯示卡這樣的pci高速外設中不僅有寄存器還有了一塊記憶體。

配置空間和IO空間不都是外設的寄存器嗎,它們有什麼差別呢?

IO空間就和i2c裝置的寄存器空間一樣,用來擷取外設狀态、配置外設。

配置空間是一段特殊的IO空間,它的作用是為外設記憶體空間、IO空間配置設定實體位址基位址,即配置BAR(Base Address Registers)。這裡類似linux對虛拟位址的映射了,但現在配置設定的卻是實體位址。因為外設内部的記憶體位址都是從0開始編址的,當pci控制器接入多個pci裝置時如何確定pci上的記憶體位址不混亂呢,這就是配置空間的一個作用,配置空間有固定的結構,在pci總線掃描裝置時配置好BAR,這樣各個pci裝置的記憶體空間和IO空間才可通路,而不至于和其他裝置實體位址沖突。

在pci總線之前的ISA總線是使用跳線帽來配置設定外設的實體位址的,每插入一個新裝置都要改變跳線帽以配置設定實體位址,這是十分麻煩且易錯的,但這樣的方式似乎我們更容易了解。能夠配置設定自己總線上挂載裝置的實體位址這也是PCI總線相較于I2C、SPI等低速總線一個最大的特色。

為什麼隻有pci裝置可以有外設記憶體空間,i2c、usb等裝置沒有?

說起外設上可以有裝置專屬的記憶體時,指的都是pci裝置。我們更為常用的i2c、usb、spi、uart裝置怎麼都沒有這樣的說法呢?

這是因為在cpu内部架構中會有系統總線和外設總線。系統總線一般是連接配接cpu與主存的,外設總線是cpu連接配接外部裝置的。在有pci控制器的cpu架構中pci總線就取代了cpu内部的外設總線的位置,所有外設都是挂在不同層級的pci橋上的,再由pci轉成了usb、i2c、uart等接口。是以pci裝置相當于直接連在cpu總線上了,這樣pci裝置中就可以擁有cpu總線上的實體位址,和主存共享cpu的實體位址空間,當然就可以存在外設記憶體(相當于pci裝置與其他外設的控制器在一個層級上)。i2c等外設隻能通過i2c控制器間接的與cpu通信,pci裝置擁有cpu的實體位址,可以直接與cpu對話。

可簡要了解為pci總線類似cpu内部總線的延伸,i2c、usb等都僅僅是純粹的外設總線,社會層級不同。