【我所認知的BIOS】—>PCI option rom
By LightSeed
2009-5-22
在這裡添加一句,畢竟什麽東東都是有相應的組織來定義了spec的,那麼不管做什麽動作我們都必須嚴格按照spec規定的動作來,否則你做出來的信號就只有你自己知道了,或者起碼說不適用於業界,所以處在我現在的這個初級階段我還是想把spec都理解透徹,也鑒於此可能很多我的總結也都是會提到spec裏的東西。
1、基本概念
PCI option rom其實是叫做PCI Expansion ROM,只是平時叫PCI option rom比較多而已,當然這都沒有什麽區別啦。談談它的定義,其實到處都有的這裡簡單羅列一下。
2、PCI Expansion ROM header
按照PCI spec 2.3可以看的出, PCI Expansion ROM header是一個很重要的東西。它需要支援以下幾個功能:
①標誌了PCI device ROM在初始化時需要佔用的位址空間大小
②表明ROM address 空間的類型
③版本號
④Vendor ID 和device ID
要記住,PCI Expansion ROM永遠都不在space裏執行,它總是被copy到相對應的RAM處,在RAM裏執行它。(筆者:隨便提一下,有些PCI device的ROM是不在PCI卡上的,那麼本應該有ROM的卡,怎麼才能讓PCI device跑起來呢?這個一般都會把ROM裏的code壓入到BIOS code中,在initial PCI option ROM的時候再加壓出來。這也就是下一張要講的 解壓縮過程。)圖1是PCI Expansion ROM header的格式截圖,圖片來源於spec。
圖1 PCI Expansion ROM header的格式表
Sepc是這樣定義的,那樣我們的rom實際又是不是這樣的呢,我就曾經懷疑過。所以我就查了一下我上有的一個rom檔,我們來看看它的二進位形式。入圖2.
圖2 實際的PCI Expansion ROM 的header 截圖
從圖2中我們可以清楚地看到PCI Expansion ROM header在每個byte上對應的格式。其他的資訊應該都比較容易掌握,但是有個資訊是很重要的還得提一下:offset 03h處是ROM的入口地址。在initial的時候,直接call segment:03h。(segment 是ROM在RAM中的鏡像的端地址。)
3、PCI Data Structure Format
顧名思義,ROM的資料結構也有一定的格式,它的格式如圖3
圖3 PCI Data Structure Format截圖
相互與header的對應資訊還可以參見圖2的格式紅線標明處。
4、PCI option ROM的初始化過程
目前我遇到的PCI option ROM是作為一個模組放入到BIOS的bin檔裏,燒到BIOS晶片裏的。這種過程當然是可以省下一定的成本啦。那麼這種PCI設備的初始化應該怎麼樣去做呢?我做了一個簡單的流程圖,見圖4。
文字敘述如下:
①在BIOS code中有一個標誌”= AwXXX Decompression Bios =“,這是爲了cbrom識別用的。那麼在程式編譯的過程中,就會生成一些規定的格式,比如說一些table,它們是供CBrom在壓縮其他rom進BIOS.bin的時候方便改寫裏面的值。或者說這些框架與cbrom都是相輔相成的,cbrom在壓rom進去的時候就是按照table逐個填入一些值。
②而被壓縮進BIOS.bin的rom在E group的某個地方,它在bootblock的時候被BIOS code copy到高端地址(比如說900000H處)
③在準備initialPCI option ROM的時候會被decompress engine解壓到了一個buffer(如4000:0H)處,然後再被copy到低端的ram處(比如D000~E000h)
④就是整個POST的過程了,如下
⑤在option rom initial之前,把用cbrom壓入到BIOS code中所有的PCI 模組都解壓到指定的ram處。(200000H起始處)這裏的資料包括全部的VGA,PCI option rom完整資訊。同時生成一個ROMOrderList。
⑥遍曆所有的PCI設備,看是否還有網卡的存在。(如果班子需要用LAN boot故特殊處理)這判斷網卡的存在一般會先查看卡上是否存在,如果不存在那麼再掃描BIOS code是否被壓入了?在上面解壓的全部PCI模組中去掃描,如果Vendor ID和device ID都對應的上那麼說明屬於這個PCI設備的ROM找到。
⑦如果網卡存在,那麼check是否是需要boot的(當然如果是VGA則skip)。不存在直接skip。
⑨以上步驟後,確實需要從LAN boot,並且rom也存在。那麼插入相應資訊到ROMOrderList中去。
⑩根據ROMOrderList裏的Address,把rom 的全部資訊都copy到特定的buffer,再做相應的判斷,把buffer裏的資訊copy到shadow RAM裏面去。(比如說D0000H,當然這裏的目的地址是會變化,並做好記錄的。)同時把ES的segment指向目的地址。然後從ES:0處取rom的入口地址,call並初始化。直到ROMOrderList結束。
圖4 PCI option ROM的初始化過程。
(筆者:以上的理解均來自于AwXXX code,個人理解錯誤在所難免,不正之處望各位斧正。以上的理解過程在程式設計俱樂部和BIOS人的罎子我都有發問的全過程,有興趣也可以去看看。這裡只是那裡的一個小結。關於解壓縮的過程,我想很多很看到這裡都很想知道,敬請關注下一篇,【我所認知的BIOS】—>decompression)