小華的部落格: 簡略介紹 EDKI與EDKII (EDK2) 的差別

搜尋此網誌

網頁

星期五, 9月 13, 2013

簡略介紹 EDKI與EDKII (EDK2) 的差別

這篇文章主要是簡單闡述一下EDKI 與 EDKII 在BIOS工程師眼中的差別在哪裡? !
在討論之前,我們先簡單說一下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應該要寫一些。
 
希望簡略的解釋能更幫助大家在學習EDKII 甚至轉換到EDKII的時候不會驚慌失措,也比較知道為什麼要改成這樣子。




5 則留言:

匿名 提到...

謝謝小華這麼詳細的解釋 我獲益匪淺

法蘭克的筆記 提到...

Good bios technical blog, could I inter-broadcast with u ? :)

Samuel Yang 提到...

請問關於EDKII 的DSC檔裡面的source override path的機制 如果要研究應該如何看起?

匿名 提到...

好分享,幫忙校字一下~
"因此理論上EDKII 環境下產生出來的可執行檔SIZE應該要寫一些。"
"應該要小一些"
修正後請刪掉此回文

Unknown 提到...

版主您好!
讀到您精闢的文章獲益良多,一般論壇上的資訊比較凌亂沒有系統也比較淺顯,您的文章是專業又深入拜讀後能令人在關鍵的觀念更清楚正確.最近想把老主機板升級成可以從NVME的SSD開機,從爬文學到的方法土法煉鋼總是失敗,一直找不到問題癥結所,想請教您:我在華碩的P8Q77(1155腳位)主機板BIOS導入NVME的3個DXE模組(Nvme.ffd、NvmeSmm.ffs、Nvmeint13.ffs),開機時依然無法從Nvem的ssd開機,bios的開機選單也看不到從nvme開機的選項,我是在主機板pcie*4的插槽插m.2的轉接卡插上ADATA 512G XPG SX8200Pro 的ssd),如方便回文指導不勝感激,謝謝!