PCIE設備與HOST之間的地址轉換


最近剛好用到了通過PCIE的與PC端相連的ARM板子,看了看代碼,里面的地址轉換確實把我也弄得有些暈,一邊和組里的人討論一邊去問大神,終於算是把這塊給弄的明白了,在博客里稍微記錄一下,防止之后又忘記。

 

PCIE是一種高速串行計算機擴展總線標准,旨在替代老版的PCI總線,現在大多數主板都配有多個PCIE插槽,外設可以通過PCIE總線與主機HOST進行IO。

PCIE設備通過橋接到PCIE總線來訪問HOST的資源。和其他設備一樣,PCIE設備也被統一編址進了HOST,HOST可以訪問PCIE外設。

於是,重點來了:

我所使用的外設是ARM處理器的板子,搭載了裁剪后的Linux操作系統,還擁有自己的DDR內存,所以,為了讓ARM和HOST在體系結構上區分控制域,使用了非透明的橋接,對我一個小白,真是第一次接觸到這個概念。

大概的意思就是指橋接到總線上的設備和普通的外設一樣,有權利訪問到HOST的資源,但是外設本身的資源,對於HOST來說是不可見的,也就是指外設相當於對主機來說是一個黑盒。

如下圖的架構圖所示:

 

 

所以,由這個問題就引出了很重要的一部分-----地址轉換

HOST端是通過PCIE總線和外設進行信息交換的,HOST是信息的生產者,而外設是信息的消費者,從內存中取出信息進行處理。

在HOST端通過memmap在內存中申請一段預留的連續地址空間,這時需要讓外設知道這個地址以便其進行數據的讀取,但是外設中ARM芯片能夠尋找的地址編碼那又是Another story

所以需要進行地址轉換!!!!!!!!!!!!!!!!!!!

 

先說明一下HOST操作PCIE設備的方式,在主機上電操作系統啟動的時候,操作系統會掃描硬件接口,並且分配物理地址,我的PCIE外設當然也就在這個時候被賦予了物理地址,等設備接入時,驅動程序再向HOST告知這個外設需要占用的地址的Size,於是HOST的OS就會把這一段地址空間分配給external device--------這個物理地址就是HOST和PCIE交互的關鍵!

PCIE_BASE_Addr + BARX_OFFSET能夠找到PCIE接口的一個叫做BAR的寄存器,操作系統能夠寫入BAR寄存器,而external device可以獲取到BAR的值,於是,這個寄存器就充當了共享內存一樣的角色。HOST和external device的信息交換渠道也就建立起來了。

 

理清一下大概的思路,HOST將memmap申請預留的地址空間的首地址寫入PCIE接口的BAR寄存器,ARM外設內存也申請同樣大小的一部分內存,在讀寫信息時,將BAR寄存器中的地址當做基址,通過偏移量的方式使得兩部分地址空間一一對應。

 

① HOST端的數據生產者,memmap申請預留空間,將首地址通過memset設置到BAR寄存器

② external device端的數據消費者,通過mmap函數訪問自身的內存指定位置(由驅動程序設置為專門用來與HOST進行內存映射的地址空間)

③ PCIE接口處的硬件實現兩部分架構的內存地址的轉換(基址寄存器 + 偏移量)

④ 其中,基址寄存器的值由PC端賦值的BAR寄存器來給出

 

流程圖如下圖所示:

基本上就是這么一個簡單的流程。

     基於TCP/IP協議的Socket通信中,也有大量的地址轉換,而假如像這樣的HOST與外設之間的通信也基於Socket來實現的話,其中必然夾雜着大量的冗余的地址轉換等操作,一條socket語句甚至可能包含着幾百上千條指令,這顯然對於某些對速度效率要求苛刻的項目來說是扮演着披着羊皮的狼這樣一個角色了,不如直接利用系統調用來實現地址的轉化,讓整個流程更加的迅速。

 

Ps:Basically,第一次正經博客差不多就這樣一個draft一樣的感覺吧,親身寫了一下才發現沒有想象的那么輕松,感謝一下那些個被我白嫖至今的博客博主們,看了快四年的博客,每一篇博客都不好寫啊,雖說過程沒有想象中的那么開心,但記錄總歸是很有意義的事情,以后還會繼續下去的,也算是對自己的一點激勵吧。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM