UEFI開發探索36 – UEFI Option ROM


 

 

 

圖1 UEFI Option ROM結構(From UEFI Spec 2.8 page 723)

畢竟都是脫胎於PCI/PCIE規范,和Legacy Option ROM的結構是相同的。UEFI Option ROM利用了之前保留的字節(偏移0x04處),用來表明自己的身份。

1 UEFI Option ROM的加載過程

在MdeModulePkg的源文件MdeModulePkg\Bus\Pci\PciBusDxe\PciOptionRomSupport.c中,可以窺見UEFI Option ROM的處理過程。源文件中包含了處理Option ROM的8個函數:

 

 

 

圖2 UDK2018 MdeModulePkg中處理UEFI Option ROM的代碼

Option ROM的執行文件不是在Flash上運行的,它會被拷貝到內存中,然后在內存中執行。Legacy BIOS的Option ROM一般加載到0xC0000~0xE0000(即0xC000段至0xE000段),而UEFI Option ROM並沒有這樣的約定。

仔細讀讀ProcessOpRomImage()的代碼,可以窺見處理Option Rom的過程。

ProcessOpRomImage()的入口參數只有一個:PCI_IO_DEVICE *PciDevice。這是一個指向PCI設備的指針,包含了設備的所有屬性以及其兄弟設備、父設備的信息。數據結構PCI_IO_DEVICE定義在PciBus.h中,可以對照PCI協議去理解。

函數中用do-while循環對設備進行循環處理,尋找到Option ROM的ROM signature(也即0xAA55)。而后對ROM結構進行分析,包括是否為EFI image、機器類型是否支持等,並創建其設備路徑(DevicePath)。

在UEFI中,使用Device Path去描述一個設備的位置信息,總線、啟動項等也常用它來描述。進入UEFI shell的時候,出現的各設備的字符串描述,就是Device Path:

 

 

 

圖3 TianoCore模擬環境中的啟動信息

Device Path共有六種,在Uefi Spec中有詳細的描述:

 

 

 

圖4 Device Path 分類(UEFI Spec 2.8 page 285)

函數中創建的Option ROM device path類型為MEDIA_DEVICE_PATH,這是一種能夠作為啟動項設備的Device Path。

創建完成后,調用LoadImage()和StartImage(),執行Option ROM代碼。

 

 

 

圖5 PciOptionRomSupport.c的ProcessOptionRomImage()

2 如何生成UEFI Option ROM

UEFI Option ROM實際上是UEFI driver的一種,EDKII提供了相應的工具,將生成文件轉換為Option ROM。前面已經說過了,我們現在所開發的option ROM,主要是PCI Option ROM。關於PCI Option ROM的內容可以參考《EDKII Driver Writer’s Guide for UEFI 2.3.1》,以下的介紹也主要來自於這個文檔。

有兩種方法可以生成PCI Option ROM鏡像,使用工具EfiRom轉換或直接使用EDKII的INF/FDF文件編譯生成。

EfiRom提供了源代碼,允許用戶在任何支持EDKII的操作系統上編譯。源代碼位於\BaseTools\Source\C\EfiRom下,在我開發用的機器上(Win10),編譯后的執行文件位於\BaseTools\Bin\Win32。

它提供的功能如下:

 

 

 

圖6 EfiRom功能列表

UEFI Option ROM是通過UEFI Driver轉換而來的,至於如何編寫UEFI driver,那是另外一個議題,這里不展開。

EfiRom會對傳入的efi文件(UEFI Driver)進行驗證,比如Rom頭是不是0xAA55、PCI數據結構標識是不是“PCIR”等。任何一項檢查不通過,則EfiRom會退出,創建Option ROM的過程將被終止。

生成命令如下:

EfiRom -f 0x9999 -i 0x8000 -e pcidriver.efi

其中,-f后指定Verdor ID,-i后指定 Device ID,-e之后給定需要轉換的文件。更多的轉換方法,包括如何與Legacy Option ROM一起打包轉換、如何壓縮等,請參考之前提到的手冊《EDKII Driver Writer’s Guide for UEFI 2.3.1》第18章第7節。

另一種轉換方法是使用INF/FDF,在build命令執行的時候,自動調用efirom將其轉換為指定的Option ROM。這是我常用的方法,編譯的同時就完成了轉換過程,一個典型的INF例子如下:

 

 

 

圖7 INF例子

Vendor ID和Device ID可以在Inf文件中指定,其他包括PCI類碼、PCI版本、是否對Option ROM進行壓縮(PCI_COMPRESS)都可以指定。

不管是采用EfiRom工具直接轉換,還是使用Inf文件,都只能對一個UEFI Driver進行處理。如果需要同時管理多個UEFI Driver,以及生成多種類型的Option ROM(IA32、X64等),可以使用FDF文件進行處理。具體的內容就不一一討論了,同樣可以參考上述的編程手冊。

3 軟件結構

UEFI Option ROM實質上是UEFI Driver,因此最好找一個比較“純潔”的Driver例子開始。在github的EDKII部分找了很久,始終沒有找到合適的。EDKII現在提供了開發驅動的工具 UEFI Driver Wizard,我沒有去使用過,也許很多示例都集成到這里面去了。

最終還是使用了我以前使用的BlankDrv,我一向以這個為基礎構建UEFI Option ROM。它目前還可以在這個地方下載:

https://sourceforge.net/projects/edk2/files/EDK%20II%20Releases/Demo%20apps/

對於Driver的開發,《UEFI原理與編程》中說得很詳細,值得好好研究一下。不過,我的目標是開發出UEFI Option ROM,很多細節不需要深究。

所開發的Option ROM是遵循UEFI driver module的,實際上也算是PCI Driver,所以它必須實現EFI_DRIVER_BINDING_PROTOCOL,並實例化Supported(), Start(), and Stop() 這三個服務。

前面已經探討過如何啟動Option ROM了,目前我們主要關心在哪里加上實際執行的代碼。

大部分執行代碼是在Start()中添加的,Start()主要的任務是啟動硬件設備,在函數中最重要的事情是調用InstallProtocolInterface()或者InstallMultipleProtocolInterfaces()在ControllerHandle上安裝驅動Protocol。

而Stop()函數用來卸載驅動,並停止硬件設備,基本上不需要修改BlankDrv提供的原始代碼。

Supported()用來評估傳遞給Driver的device handle所指明的pci controller是否能被driver所驅動,主要通過Vendor ID、Device ID、Class code判定。

如前所述,具體的驅動細節可以參考其他的文檔,架構搭建完后,就可以專注在Option ROM的功能實現上了。之前35篇博客中所討論的議題,所編寫的代碼,完全可以移植到Option ROM中,只要硬件設備的擴展ROM大小足夠。

 

 

 

圖8 UEFI Option ROM code

4 編譯及演示

因為涉及到公司商業上的原因,原始代碼不能貼出。我正在考慮使用另外一種PCI-E芯片做測試卡,ROM空間大些,做一些相對復雜的功能,到時再將代碼公開。

編譯和寫入到測試卡的過程,可以參考博客:“UEFI開發探索12 – Oprom測試板”。

這里把測試的結果再貼一次:

 

圖9 UEFI Option ROM演示

至此,UEFI探索系列的主線-UEFI Option ROM的開發就完成了。

對我來說,真是個不錯的經歷。從決定寫這個系列博客,到現在已經半年多了。每周都強迫自己坐到書桌旁開始敲字,從不習慣到成自然,現在都成為我每周必做的功課了。

在這個過程中,我完成了很多知識的補全。不過,感覺上了解越多,不理解的也越來越多。

計划中還有14篇,將針對各個我感興趣的議題再進行整理。這個探索的旅程還遠到沒結束的時候。
————————————————
版權聲明:本文為CSDN博主「luobing4365」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/luobing4365/article/details/102597109

 

參考---->

https://blog.csdn.net/luobing4365/article/details/102597109


免責聲明!

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



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