從按下PC的電源按鈕開(kāi)始,BIOS就接管系統(tǒng)控制權(quán)開(kāi)始工作,它會(huì)先進(jìn)行一些內(nèi)存和設(shè)備的初始化工作(當(dāng)然,也包括PCI設(shè)備),由于商業(yè)上的原因,Phoenix等廠商的BIOS代碼需要授權(quán)協(xié)議,下面以另外一款開(kāi)源BIOS(openbios)為例,來(lái)剖析BIOS中,PCIe設(shè)備是如何被找到以及初始化的。
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比碌曲網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式碌曲網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋碌曲地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
PCI設(shè)備的掃描是基于深度優(yōu)先搜索算法(DFS:Depth First Search),也就是說(shuō),下級(jí)分支最多的PCI橋?qū)⒆钕韧瓿善渥釉O(shè)備的掃描。下面以圖片來(lái)具體說(shuō)明,BIOS是如何一步步完成PCI 設(shè)備掃描的。
第一步:PCI Host 主橋掃描Bus 0上的設(shè)備(在一個(gè)處理器系統(tǒng)中,一般將與HOST主橋直接相連的PCI總線被命名為PCI Bus 0),系統(tǒng)首先會(huì)忽略Bus 0上的D1,D2等不會(huì)掛接PCI橋的設(shè)備,主橋發(fā)現(xiàn)Bridge 1后,將Bridge1下面的PCI Bus定為 Bus 1,系統(tǒng)將初始化Bridge 1的配置空間,并將該橋的Primary Bus Number 和 Secondary Bus Number寄存器分別設(shè)置成0和1,以表明Bridge1的上游總線是0,下游總線是1,由于還無(wú)法確定Bridge1下掛載設(shè)備的具體情況,系統(tǒng)先暫時(shí)將Subordinate Bus Number設(shè)為0xFF。如圖 1.1所示:
圖 1.1 PCIE掃描第一步
第二步:系統(tǒng)開(kāi)始掃描Bus 1,將會(huì)發(fā)現(xiàn)Bridge 2。系統(tǒng)將Bridge 2下面的PCI Bus定為Bus 2,并將該橋的Primary Bus Number 和 Secondary Bus Number寄存器分別設(shè)置成1和2,和上一步一樣暫時(shí)把Bridge 2的Subordinate Bus Number設(shè)為0xFF。如圖 1.2所示:
圖 1.2 PCIE掃描第二步
第三步:
系統(tǒng)繼續(xù)掃描Bus 2,將會(huì)發(fā)現(xiàn)Bridge 4。系統(tǒng)將Bridge 4下面的PCI Bus定為Bus 3,并將該橋的Primary Bus Number 和 Secondary Bus Number寄存器分別設(shè)置成2和3,此后
系統(tǒng)繼續(xù)掃描后發(fā)現(xiàn)Bus 3下面已經(jīng)沒(méi)有任何Bridge了,意味著該P(yáng)CI總線下已經(jīng)沒(méi)有任何掛載下游總線了,因此Bridge 4的Subordinate Bus Number的值已經(jīng)可以確定為3了。
如圖 1.3所示:
圖 1.3 PCIE掃描第三步
第四步:
完成Bus 3的掃描后,系統(tǒng)返回到Bus 2繼續(xù)掃描,發(fā)現(xiàn)Bus 2下面已經(jīng)沒(méi)有其他Bridge了。此時(shí)Bridge 2的Subordinate Bus Number的值也已經(jīng)可以確定為3了。如圖 1.4所示:
圖 1.4 PCIE掃描第四步
第五步:
完成Bus 2的掃描后,系統(tǒng)返回到Bus1繼續(xù)掃描,會(huì)發(fā)現(xiàn)Bridge 3,系統(tǒng)將Bridge 3下面的PCI Bus定為Bus 4。并將Bridge 4的Primary Bus Number 和 Secondary Bus Number寄存器分別設(shè)置成1和4,此后系統(tǒng)繼續(xù)掃描后發(fā)現(xiàn)Bus 4下面已經(jīng)沒(méi)有任何Bridge了,意味著該P(yáng)CI總線下已經(jīng)沒(méi)有掛載任何下游總線了,因此Bridge 3的Subordinate Bus Number的值已經(jīng)可以確定為4了。如圖 1.5所示:
圖 1.5 PCIE掃描第五步
第六步:
完成Bus 4的掃描后,系統(tǒng)返回到Bus 1繼續(xù)掃描, 發(fā)現(xiàn)Bus 1下面已經(jīng)沒(méi)有其他Bridge了。此時(shí)Bridge 1的Subordinate Bus Number的值已經(jīng)可以確定為4,系統(tǒng)返回Bus 0繼續(xù)掃描(Bus 0下如果有其他它Bridge,將重復(fù)上述的步驟進(jìn)行掃描)。至此,本例中的整個(gè)PCI的設(shè)備掃描已經(jīng)完成了。最終的設(shè)備和總線的掃描結(jié)果如圖 1.6所示
圖 1.6 PCIE掃描第六步
一般來(lái)說(shuō),可以通過(guò)兩個(gè)寄存器來(lái)訪問(wèn)PCI的配置空間(寄存器CONFIG_ADDRESS與CONFIG_DATA),在x86體系下,這兩個(gè)寄存器分別對(duì)應(yīng)0xCF8和0xCFC端口,對(duì)配置空間的訪問(wèn)都是通過(guò)對(duì)這兩個(gè)寄存器的讀寫來(lái)實(shí)現(xiàn)先。CONFIG_ADDRESS寄存器的具體位組成如圖 1.7所示:
圖 1.7 x86配置寄存器
Bus Number : 總線號(hào)(8 bit),范圍0--255。
Device Number: 設(shè)備號(hào)(5 bit),范圍0--31。
Function Number: 功能號(hào)(3 bit),范圍0--7。
Register Number: 寄存器號(hào)(6 bit),范圍0--63(配置空間一共256個(gè)字節(jié),分割成64個(gè)4字節(jié)的寄存器,從0--63編號(hào))。
每個(gè)PCI設(shè)備可根據(jù)上圖所示的四個(gè)信息:Bus Number, Device Number, Function Number,Register Number來(lái)進(jìn)行具體設(shè)備的定位并對(duì)其配置空間訪問(wèn)。當(dāng)訪問(wèn)PCI設(shè)備的配置空間時(shí),先根據(jù)以上格式設(shè)置CONFIG_ADDRESS寄存器,然后再讀取CONFIG_DATA寄存器即可得到相應(yīng)的配置空間寄存器的值。通過(guò)以上這些步驟,BIOS就完成了所有PCI設(shè)備的掃描,并且為每個(gè)設(shè)備分配好了系統(tǒng)資源。