在業界大多數人還是稱之為UEFI BIOS,對於以往的BIOS則是稱為Legacy BIOS。
BIOS全名為Basic Input/Output System(基本輸入輸出系統),就已字面上來看,繼續把它稱之為UEFI BIOS也沒甚麼問題,而且它依然提供了許多底層的服務給上層的作業系統使用。
早期的BIOS都是由組合語言撰寫的,Legacy BIOS會提供中斷向量(Interrupt Vector)等介面用來跟與外部做溝通,例如早期的OS或應用程式,而UEFI已不需要這東西了,除非有需要使用不相容於UEFI的OS,才需要將CSM功能打開,以提供中斷向量等服務。
Legacy BIOS由各家IBV (Independent BIOS Vendor)所開發,所以除了標準的X86架構以外,整個BIOS系統由各個IBV定義,簡單來講就是各寫各的,如果開發商使用的BIOS從A公司換到P公司,可能會發現許多寫過的程式無法相容。
UEFI全名為Unified Extensible Firmware Interface,目前由UEFI協會管理與制定規格。UEFI推出一套稱為EDK(EFI Development Kit,而穩定發佈版稱之為UDK)開放原始碼的開發套件,裡面除了已經定義好的標準外(如C的header file),還有許多被已被開發出的標準程式模組。
任何人都能夠下載它並執行其模擬環境,在Windows底下提供了NT32的模擬器,可供使用者作些簡單的開發與測試。
模擬器的啟動畫面。
UEFI由約99%的C語言與1%的組合語言撰寫,裡面定義了許多標準的開放介面,這些都定義在UEFI Spec裡面。
現在各家IBV都是使用這套標準,使用這套標準的好處為,只要是使用UEFI開放出來的標準介面所開發的程式,不管是從A公司換到P公司還是從P公司換到I公司,基本上是可以正常運作的,除非使用到其他公司自行定義的介面。
左邊為UEFI在背景印出的Debug的訊息,而右邊為UEFI所提供的Shell環境,類似於DOS,提供許多指令,可做些基本的控制。
其實UEFI跟一個小型的系統沒兩樣了,提供了記憶體管理、簡單工作的排程與各項硬體周邊的控制。
現行的EDK都已經被EDKII所取代,EDKII提供了更模組化的概念,我們稱之為Package,這些Package都詳細的定義出它所提供的介面與程式,UEFI各個程式都可編譯成獨立的EFI檔案,有點類似Windows底下的EXE檔,可在UEFI的環境下被執行。
各個EFI檔案除了負責自己的工作外,也可透過所定義好的介面與其他程式做溝通、互相傳遞資料等等,例如Protocol、PPI等方式。
UEFI明確的定義出系統開機的四個階段:SEC -> PEI -> DXE -> BDS
SEC(主要是由組合語言撰寫):
系統開機(或重開機)後執行的第一條指令(0xFFFFFFF0,為系統記憶體接近4G的位置)會跳轉到這個特定的程式的位置去執行(但以現行的許多系統來說,開機第一個跑的程式其實並不是BIOS,而是例如像Intel ME等之類的韌體,待它們初始化完之後才會將控制權轉交給BIOS的第一條指令。時代在變,觀念也要變了...)。
為什麼會在接近4G的位置:因為這是x86的規範,存有UEFI BIOS的SPI Flash Part裡面的資料會被映射到接近4G的位置,簡單來說當Flash Part為16MB,其存取範圍為4G - 16M至0xFFFFFFFF (4G - 1 byte)。
以程式設計師的角度來說,對於較為低階的程式語言(如組合語言、C、C++)來說,存取與操作記憶體是輕而易舉的,所以透過硬體機制把在Flash Part上的資料映射到RAM上面,對於撰寫韌體的程式設計師來說是非常方便的!可以直接透過記憶體位置去存取ROM上的BIOS資料。
否則需要以一道一道的指令送給SPI控制器且需要等待其回覆時間,這會麻煩許多...
SEC最主要的功能是初始化CPU上的快取記憶體(L3 Cache)來當作暫時的記憶體來用。
原因是因為系統剛啟動的時候,一般的RAM尚未被初始化,而C語言在執行的時候,需要Stack來執行其各個Function,所以這時候要有一個暫時的RAM來放置Stack。
在SEC完成這個主要的項目後,會交棒給下一個階段:PEI。
PEI (The Pre-EFI Initialization):
PEI最主要的任務為初始化系統上的暫存器與記憶體,初始化記憶體需經過繁雜的時序的計算,並將其結果填到晶片組的暫存器中。這些有關晶片組的程式通常由IHV如Intel、AMD等Chipset Vendors所提供。
一般來說PEI能做的事情越少越好(雖然現在越來越多了...),將基本的硬體初始化後就把控制權交給下一個階段:DXE。
DXE (Driver Execution Environment):
這階段所負責項目就多了,提供了許多Protocol與各個DXE階段的EFI執行檔做溝通。其中跟設備最有關係的就是被稱之為DXE Driver的EFI執行檔,它會提供標準的介面,用來初始化各個周邊裝置,如各種PCI裝置(顯卡、USB控制器等)、鍵盤滑鼠(常見的有USB與PS2介面)、SATA、NVMe等...。
但基本上在這階段,上述的周邊還不會被初始化,DXE階段只是執行那些DXE Driver的程式,使他們提供出標準的介面來給BDS作執行。
DXE階段確定沒有DXE的EFI程式有需要被執行的時候,就會把控制權給BDS,其實BDS也只是隸屬於DXE中的一個程式。
BDS (Boot Device Select):
BDS就真的跟啟動到作業系統比較有關係了,在這階段可以依照系統環境要求來決定哪些周邊需要初始化的,例如像系統廠想要開機速度更快的話,或許可以在某些條件下不初始化USB相關裝置(鍵盤、滑鼠、儲存裝置等),事情多做總是會花時間的。而某些裝置沒初始化也不用擔心,作業系統有自己的Driver會負責這些事情,所以進了OS還是可以使用的。
而基本上顯卡(VGA)是一定會被初始化的,所負責的就是所謂的GOP(Graphics Output Protocol) Driver,GOP Driver除了初始化顯卡並點亮螢幕外,也提供標準的程式介面供開發者將圖像輸出到畫面上,等於是程式與顯卡溝通的橋樑,所以說在BIOS階段只要看到跟畫面有關的,基本上跟它脫離不了關係。
BDS也提供了程式給使用者作細部的設定,也就是大家孰悉的Setup或Boot Menu。
這些功能都可做成文字或GUI介面的,完全取決於各家廠商的考量,現今的許多NB都還是文字介面的。
所以如果要以是不是GUI介面來分辨是不是UEFI,也是不夠準確的。
其實如果以前的BIOS Vendor要的話,也是可以提供GUI介面給Legacy BIOS的,但可以說不合乎成本與需求(尤其以前的ROM沒那麼大...)
而BDS要從哪一個裝置啟動作業系統(OS)則是取決於Boot Order的設定,以純UEFI的OS來說,可以看到在ESP分割區(EFI System Partition,Windows安裝的時候會切割的一個100MB的隱藏分區,其大小其實可以自訂)裡面會有個efi\boot的資料夾,OS安裝之後會將其loader程式放在裡面,BDS則會依照這個標準來找到並執行該loader。
在OS的安裝檔裡面,可以已看到相對應的資料夾。
附帶一提,32bit的作業系統其檔名為bootia32.efi而64bit為bootx64.efi。
另外DXE部分可以分為32bit或64bit,這在編譯期間就需要決定,主要取決於CPU的支援性(或商業考量...)。
如果是32bit的DXE就只能執行bootia32.efi,也就是32bit的OS,而64bit則反之。
現在大部分的個人電腦都是64bit,但還是有些例外,如某些Atom系列(Clover Trail)就是32bit的環境,所以OS也只能安裝32bit的版本。
============================================================
現在UEFI可以說是包山包海,除了支援了標準的Network Stack架構外,HTTP、TLS (HTTPS)協定也支援了,未來也會導入更多安全機制,可以說是讓整體系統越來越安全(越來越肥...,相信99%的使用者都是能夠開機就好!)
============================================================
目前先打到這裡,有想到其他的再打。
出處:自己(某公司的BIOS Engineer)