怎樣訪問pcie整個4k的配置空間 - blfbuaa - 博客園 (cnblogs.com)
PCI device enumeration using ports 0xCF8, 0xCFC - antek's tech blog (anadoxin.org)
IntroductionToReverseEngineering (ost2.fyi)
Day1_00_Advanced x86 - BIOS and SMM Internals - Motivation.pdf (opensecuritytraining.info)
Day1_01_Advanced x86 - BIOS and SMM Internals - QuickAsideTools.pdf (opensecuritytraining.info)
Day1_XX_Advanced x86 - BIOS and SMM Internals - SMI Suppression.pdf (opensecuritytraining.info)
Day1_XX_Advanced x86 - BIOS and SMM Internals - Memory Map.pdf (opensecuritytraining.info)
Day1_02_Advanced x86 - BIOS and SMM Internals - Chipset Architecture.pdf (ost2.fyi)
[Day1_03_Advanced x86 - BIOS and SMM Internals - Boot Overview.pdf (ost2.fyi)]
(https://www.ost2.fyi/IntroBIOS_files/Day1_03_Advanced%20x86%20-%20BIOS%20and%20SMM%20Internals%20-%20Boot%20Overview.pdf)
Day1_XX_Advanced x86 - BIOS and SMM Internals - Reset Vector.pdf (opensecuritytraining.info)
Day1_04_Advanced x86 - BIOS and SMM Internals - IO.pdf (opensecuritytraining.info)
Day1_05_Advanced x86 - BIOS and SMM Internals - PCI.pdf (opensecuritytraining.info)
Day1_06_Advanced x86 - BIOS and SMM Internals - PCI XROMs.pdf (opensecuritytraining.info)
Day1_07_Advanced x86 - BIOS and SMM Internals - SMM.pdf (opensecuritytraining.info)
Day1_08_Advanced x86 - BIOS and SMM Internals - SMRAM.pdf (ost2.fyi)
Day1_09_Advanced x86 - BIOS and SMM Internals - SMM and Caching.pdf (opensecuritytraining.info)
Day1_10_Advanced x86 - BIOS and SMM Internals - Other Fun with SMM.pdf (opensecuritytraining.info)
Day2_00_Advanced x86 - BIOS and SMM Internals - SPI Programming.pdf (ost2.fyi)
Day2_01_Advanced x86 - BIOS and SMM Internals - SPI Flash.pdf (ost2.fyi)
Day2_02_Advanced x86 - BIOS and SMM Internals - Flash Descriptor.pdf (opensecuritytraining.info)
Day2_03_Advanced x86 - BIOS and SMM Internals - SPI Flash Protection Mechanisms.pdf (ost2.fyi)
Day2_04_Advanced x86 - BIOS and SMM Internals - UEFI.pdf (opensecuritytraining.info)
IntroBIOS_files/Day2_05_Advanced x86 (studylib.net)
Day2_06_Advanced x86 - BIOS and SMM Internals - UEFI Secure Boot.pdf (opensecuritytraining.info)
Day2_07_Advanced x86 - BIOS and SMM Internals - Trusted Computing.pdf (ost2.fyi)
Day2_08_Advanced x86 - BIOS and SMM Internals - Conclusion.pdf (opensecuritytraining.info)
怎樣訪問pcie整個4k的配置空間
眼下用于訪問PCIe配置空間寄存器的方法須要追溯到原始的PCI規(guī)范棺克。
為了發(fā)起PCI總線配置周期纠吴,Intel實現(xiàn)的PCI規(guī)范使用IO空間的CF8h和CFCh來分別作為索引和數(shù)據(jù)寄存器豁跑,這樣的方法能夠訪問全部PCI設(shè)備的255 bytes配置寄存器系枪。Intel Chipsets眼下仍然支持這樣的訪問PCI配置空間的方法。
PCIe規(guī)范在PCI規(guī)范的基礎(chǔ)上固额,將配置空間擴展到4K bytes眠蚂,至于為什么擴展到4K,詳細能夠參考PCIe規(guī)范斗躏,這些功能都須要配置空間逝慧。原來的CF8/CFC方法仍然能夠訪問全部PCIe設(shè)備配置空間的頭255 bytes,可是該方法訪問不了剩下的(4K-255)配置空間。
怎么辦呢笛臣?Intel提供了第二種PCIe配置空間訪問方法栅干。Intel Chipset通過將配置空間映射到內(nèi)存地址空間。PCIe配置空間能夠像對映射范圍內(nèi)的內(nèi)存進行read/write一樣來訪問了捐祠。
這樣的映射是由北橋芯片來完畢的碱鳞,可是不同芯片的映射方式也是不同的。
1踱蛀、CF8h/CFCH Method
Intel Chipsets使用IO空間的CF8h/CFCh地址來訪問PCI設(shè)備的配置寄存器窿给。該方法相同能夠訪問PCIe設(shè)備的頭255配置寄存器。
[圖片上傳失敗...(image-7d0084-1701472178156)]
為了對已知PCI設(shè)備發(fā)起一個PCI總線配置周期率拒,軟件必須運行下面步驟:
PCI設(shè)備的總線號必須被填寫到IO地址CF8h的[23:16] bits
PCI設(shè)備的設(shè)備號必須被填寫到IO地址CF8h的[15:11] bits
PCI設(shè)備的功能號必須被填寫到IO地址CF8h的[10:8] bits
須要訪問的寄存器雙字地址必須被填寫到IO地址CF8h的[7:2] bits
CF8h的最高位為配置位崩泡。該位必須設(shè)置為1
對于寫操作,將設(shè)備的特定信息組合成一個雙字(4bytes)后猬膨。寫到CFCh地址
-
對于讀操作角撞,將設(shè)備的特定信息組合成一個雙字后,把數(shù)據(jù)從CFCh讀回來
當(dāng)運行6或者7步驟時勃痴,對應(yīng)的PCI配置read/write cycle被Created by Intel Chipset谒所,并在須要時傳遞到整個系統(tǒng)。在步驟4配置須要讀寫的寄存器地址時沛申。該空間僅僅有6位劣领,也就說僅僅有64個地址可寫,可是PCI配置空間不是256嗎铁材?別急尖淘,記得是雙字地址,一個Dword=4 bytes著觉。也就是說4 * 64 = 256村生。剛好,不是嗎饼丘?
2趁桃、Memory Mapped Method
PCIe規(guī)范為每一個PCIe設(shè)備加入了很多其它的配置寄存器≡岷粒空間為4K镇辉。雖然CF8h/CFCh方法仍然可以訪問lower 255 bytes屡穗,可是必須提供第二種方法來訪問剩下的4K range寄存器贴捡。
Intel的解決方式是使用了預(yù)留256MB內(nèi)存地址空間,對這段內(nèi)存的不論什么訪問都會發(fā)起PCI 配置cycle村砂±谜可是為什么是256MB?
聽我慢慢解釋給大家聽:猶豫4K的配置空間是directly mapped to memory的,那么PCIe規(guī)范必須保證全部的PCIe設(shè)備的配置空間占用不同的內(nèi)存地址,依照PCIe規(guī)范汛骂,支持最多256個buses罕模。每一個Bus支持最多32個PCI devices,每一個device支持最多8個function,也就是說:占用內(nèi)存的最大值為:256 * 32 * 8 * 4K = 256MB帘瞭。
這段256MB的內(nèi)存區(qū)將依據(jù)intel chipset的不同淑掌。能夠映射到系統(tǒng)內(nèi)存映射范圍內(nèi)的不論什么位置,一般北橋芯片都會有一個寄存器來指明PCI配置空間的內(nèi)存映射地址蝶念,它叫PCIe Configuration Register Base Address Register (BAR)抛腕,例如以下圖:
[圖片上傳失敗...(image-dcec0d-1701472178155)]
當(dāng)軟件訪問指定PCIe設(shè)備的配置寄存器時,必須正確計算該寄存器映射到內(nèi)存的詳細地址媒殉,那么怎么計算呢担敌,參考上圖我們能夠知道,busNo=0,deviceNo=0,funcNo=0的地址剛好是BAR廷蓉,一條總線占用的最大空間計算例如以下:
SIZE_PER_BUS = 4K * 32 * 8 = 256K = 1M = 100000h
SIZE_PER_DEVICE = 4K * 8 = 8000h
SIZE_PER_FUNC = 4K = 1000h
訪問總線號為busNo全封,設(shè)備號為DevNo,功能號為funcNo的offset寄存器的計算公式是:
Memory Address = PCIe Configuration Register Base Address Register (BAR)
+ busNo * SIZE_PER_BUS
+ devNo * SIZE_PER_DEVICE
+ funcNo * SIZE_PER_FUNC
+ offset
For example, to access the following configuration register:
? PCI Express Configuration Register F0000000h
? Bus Number 15h
? Device Number 00h
? Function Number 05h
? Register Offset 84h
Memory Address = F0000000h + 15h * 100000h + 00h * 8000h + 05h * 1000h + 84h
= F1505084h
如今我們能夠從已知的busNo桃犬,devNo刹悴,funcNo和offset來計算映射后的內(nèi)存地址。那么反過來攒暇。給定的內(nèi)存地址颂跨,我們想知道這個地址的busNo, devNo, funcNo和offset信息,能夠嗎扯饶?當(dāng)然能夠恒削,計算公式例如以下:
busNo = (Memory Address - BAR) / SIZE_PER_BUS;
devNo = (Memory Address - BAR - busNo * SIZE_PER_BUS) / SIZE_PER_DEVICE;
funcNo = (Memory Address - BAR - busNo * SIZE_PER_BUS
- devNo * SIZE_PER_DEVICE) / SIZE _PER_FUNC;
offset = Memory Address - BAR - busNo * SIZE_PER_BUS - devNo * SIZE_PER_DEVICE
- funcNo * SIZE_PER_FUNC;
又或offset = Memory Address & 0x0FFFh;(為什么是0x0FFFh?自己想想啦)
想起來了么?因此PCIe的配置空間大小就是4K啊尾序。
3钓丰、芯片組的異同
上面說的BAR,也就是PCI配置空間寄存器映射到內(nèi)存的基地址寄存器每币。在intel chipset中的實現(xiàn)方式也千差萬別携丁。在前期的intel chipset中。該寄存器被包括在芯片組(MCH ,GMCH)的內(nèi)存控制器部分兰怠。
另外梦鉴。因為被PCIe配置空間占用的256M內(nèi)存空間會屏蔽掉DRAM使用該段內(nèi)存區(qū)。大部分的Intel Chipset同意BIOS來配置該空間大小揭保,因此在實際應(yīng)用中肥橙,一般就應(yīng)用前面幾個總線號,BIOS通過檢測PCIe總線的擴展深度來動態(tài)設(shè)置該映射內(nèi)存區(qū)的大小秸侣,比方PM965芯片組存筏,假設(shè)配置軟件檢測系統(tǒng)使用不大于64的總線號宠互,那么該軟件將編程內(nèi)存映射大小為64M,剩下的(256M-64M = 192M)留給DRAM椭坚。
4予跌、PCIe配置空間的內(nèi)存映射對32bit系統(tǒng)的影響
因為PCIe配置空間占用了256M內(nèi)存空間,并且該被占用空間對DRAM來說是不可用的善茎,這意味著256M空間消失于系統(tǒng)內(nèi)存券册,這在32bit系統(tǒng)中更為明顯。
比方垂涯。在32 bit WINxp中汁掠,理論上能夠訪問到的內(nèi)存是4G,假設(shè)4G空間都被DRAM給占用集币。因為PCIe的存在考阱。被PCIe占用的那部分內(nèi)存空間對OS來說是不可用的,莫名的消失了最多256M內(nèi)存鞠苟,這也是大部分Intel Chipset同意BIOS來配置該空間大小的原因乞榨。
在64 bit 系統(tǒng)中。不存在這個問題当娱,由于系統(tǒng)能夠訪問超過4G的內(nèi)存空間吃既。Intel Chipset會包括控制邏輯把該PCIe的內(nèi)存映射到above 4G。這樣跟DRAM就沒有沖突跨细。
在64bit系統(tǒng)中鹦倚,不可能使用2的64次方的內(nèi)存吧。哈哈冀惭,總會沒有使用到的內(nèi)存空間震叙。
5、訪問PCIe配置空間的C轉(zhuǎn)換代碼
//**********************************************************************
unsigned long PCIeBase = 0xF0000000UL;
unsigned long FinalAddress;
unsigned long Bus = 0;
unsigned long Device = 0;
unsigned long Function = 0;
unsigned long Register = 0;
//**********************************************************************
void Convert_to_Memory()
{
FinalAddress = PCIeBase +
(Bus0x100000UL) +
(Device0x8000) +
(Function0x1000) +
Register;
}
//**********************************************************************
void Convert_to_Register()
{
Bus = (FinalAddress-PCIeBase) / (0x100000UL);
Device = (FinalAddress-PCIeBase - (Bus0x100000UL)) / (0x8000);
Function = (FinalAddress-PCIeBase - (Bus0x100000UL) -
(Device0x8000)) / (0x1000);
Register = (FinalAddress) & (0x00000FFF)
}