在討論之前,我們先簡單說一下Package是甚麼東西?
Package是甚麼?
在EDKI裡面,我們在寫UEFI driver的時候並不會有所謂的 "Module" 的概念在裡面。我們開發的時候都是以 driver為單位,並不會考慮一些模組化的問題。
[註] UEFI 的可執行檔案我們的術語是Image或是Driver,所以當你聽到這個術語時把他當成類似EXE執行檔就可以了。
而 EDKII裡面,他加上了 Package這個概念(模組化)。其實可以把它看成是一個目錄,而這個目錄名稱會是"xxxPkg",而目錄裡面就是一堆相關的UEFI driver。
所謂的相關的UEFI Driver是說,假如你看到目錄名稱是"NetworkPkg",那麼這個Package裡面的東西就跟Network有關,所以在這個目錄內可以有其他子目錄去存放著 PEI/DXE/SMM/APP 的 Driver或是 Library。
而組成一個 Package的元素(一個PKG目錄內)必定包含一個 *.dec 和 *.dsc
Package的好處是甚麼? 就是"獨立"
在EDKI 的時候,你想單獨產生一個特定的CODE時,你至少"整套CODE"要先產生一次! 而EDKII使用這種"獨立"的概念就不需要整套CODE build完才產生你要的CODE!
但也是因為獨立,所以有很多地方都是為了解決獨立出來問題而去改了一堆Build tool動作跟你描述.dsc還有.FDF的動作。
EDKI與EDKII主要的差別?
- Build process的改變
EDKI : 由ProcessDsc.exe執行將 *.inf 轉換成 makefile 的動作
EDKII: 由Build.py 去處理,同時還會產生 AutoGen.c & AutoGen.h (Parsing *.dec )
- DSC file / FDF file
在EDKI裡,決定一個 driver要放在那一個 firmware volume裡是在"1個.dsc"就可以決定的,通常都會是叫做PlatformDsc.dsc或是 Build.dsc這個檔案!
在檔案內你會透過FV=FVREVOVERY的方式把底下的UEFI Driver通通放進去FVREVOVERY.FV,接著透過Flashmap.fdf去規劃ROM的區域,然後決定 FVMAIN.FV放進去哪個區域。
但是 EDKII為了實現 Package這個概念,所以.dsc不再用來描述UEFI driver要放到哪個FV,而只是拿來決定要不要BUILD這目錄下的UEFI driver而已!
描述那些UEFI DRIVER放到ROM的哪個位置的動作就變成EDKII新的FDF SPEC所描述的那些動作,所以你必須要新的FDF 格式中描述你那些UEFI driver是要放進去ROM裡面的。
- PCD/DEC
因為EDKII還希望做到不用改到Source code就能夠改變CODE的行為,所以延伸出了PCD這種控制方式,不過我是覺得它需要額外寫TOOL去達到他的理念而增加了許多BIOS工程師的麻煩。
PCD我自己是分成兩部分學習,一部分是屬於如何在RUNTIME管理PCD Database的部分,另一部分就是如何透過DEC FILE去產生PCD的預設值以及有哪些PCD LIB與Header file可以存取他,因為這部分牽扯到實作面(靠的是C語言巨集),所以需要邊開著CODE邊解釋,所以很難使用文章解釋,希望大家有機會在業界遇到我時在幫大家解釋吧^^.
你暫時可以簡單把他想像成是一個變數宣告的方式,變數會有生命週期(整個RUNTIME或是某一個DRIVER而已)與屬性(唯讀/可讀寫),可以方便你在CODE裡面存取他!
以上的部分大致上就是EDKI 與EDKII的差別,對於BIOS工程師來說可能會需要去習慣新的DSC/INF/DEC/FDF寫法,以及BUILD.py這個工具的用法,其他的就是要去習慣各家IBV對於PCD的作法!
EDKI與EDKII Reference Code的差別?
EDKI 與 EDKII Reference code的部分,以目前我接觸到的部分來說最大的差別在於"移植的觀念"。
EDKI 身不好移植到不同平台,所以EDKII在這部分是希望能夠好移植,而他的使用的方式是約束大家使用同一個EntryPoint,也就是說在EDKII RC code部分,如果大家的EntryPoint都能指向同一個地方做完一些跟Platform相關的事情之後再跳回去Driver EntryPont,那麼下次如果要移植到不同平台時,我只要把這個共通的EntryPoint改寫就好了。
所以在 RC CODE部分,你會看到他先透過共同的_ModuleEntryPoint,然後再從C_FLAG設定的給EDKII Gule Library的EntryPoint 跳回去你設定的Driver EntryPoint,這就是他主要的改變!
因為EDKII Glue Library做掉一些事情了,所以以前在UEFI Driver內可能一開始會去呼叫InitDxeLib()來初始化gBS/gRT/gST的動作就不用做了,另外Smm Driver寫法也略有不同,其實都是因為被偷做,所以你可以少做!
EDKI與EDKII Code Size的差別?
由於EDKI 本身在LIBRARY撰寫部分並沒有明確規範,所以連結出來的可執行檔的CODE SIZE會比較大,在EDKII上也針對了這部分重新改寫了原來的LIBRARY以減少連結時的CODE SIZE,因此理論上EDKII 環境下產生出來的可執行檔SIZE應該要寫一些。