【前 言】
2011年9月,筆者次接觸UEFI的項(xiàng)目。
當(dāng)時(shí),我們正與國(guó)內(nèi)某PC大廠合作,開(kāi)發(fā)一款安全計(jì)算機(jī)。這款產(chǎn)品包含一個(gè)嵌入BIOS中的軟件模塊,此模塊是用匯編語(yǔ)言編寫的Option ROM。由于合作方計(jì)劃將BIOS架構(gòu)全部轉(zhuǎn)為UEFI,因此要求我們將軟件模塊移植到UEFI架構(gòu)下。
在對(duì)UEFI的理解還非常初級(jí)的情況下,筆者忐忑地接下了任務(wù)。用了三周時(shí)間,在AMI的集成工具上,筆者使用C語(yǔ)言將原有的軟件模塊重寫為了UEFI驅(qū)動(dòng),總算是圓滿完成了任務(wù)。
這之后,筆者花了不少時(shí)間去研究UEFI的公開(kāi)文檔,嘗試著做了很多實(shí)驗(yàn)。在此期間,UEFI規(guī)范從2.3升級(jí)到2.8;身邊的計(jì)算機(jī)運(yùn)行Legacy BIOS的越來(lái)越少,運(yùn)行UEFI BIOS的越來(lái)越多。UEFI的開(kāi)發(fā)效率高、可擴(kuò)展性好,而且系統(tǒng)性能和安全性都很高,支持X86、ARM和RISC-V等多種指令集架構(gòu)。時(shí)至今日,UEFI已經(jīng)成為事實(shí)上的BIOS標(biāo)準(zhǔn),所有有志于底層開(kāi)發(fā)的工程師都有必要深入了解UEFI架構(gòu)及其編程方法。
【本書的寫作初衷】
因十年前的項(xiàng)目機(jī)緣,筆者開(kāi)始學(xué)習(xí)UEFI的相關(guān)知識(shí),并利用業(yè)余時(shí)間,以UEFI開(kāi)發(fā)探索為名,撰寫了UEFI開(kāi)發(fā)的系列博客。在此期間,認(rèn)識(shí)了不少業(yè)界的朋友,在產(chǎn)品開(kāi)發(fā)、市場(chǎng)推廣方面,我們有過(guò)相當(dāng)多的探討。
也是因?yàn)槿绱,?dāng)國(guó)產(chǎn)自主計(jì)算機(jī)從前幾年開(kāi)始大批量出貨,而大部分BIOS采用了UEFI架構(gòu)時(shí),筆者一點(diǎn)都不感到奇怪。基于此認(rèn)識(shí),公司的產(chǎn)品針對(duì)國(guó)產(chǎn)自主計(jì)算機(jī)的軟件架構(gòu)進(jìn)行了較大改造,如果沒(méi)有UEFI架構(gòu)的支持,這是做不到的。
在產(chǎn)品開(kāi)發(fā)的過(guò)程中,能夠參考的資料,除去UEFI規(guī)范等公開(kāi)資料外,英文資料有Intel Press出版的Beyond BIOS和Harnessing the UEFI Shell。中文資料,則只有戴正華老師的《UEFI原理與編程》。作為主流的BIOS架構(gòu),可供參考的書籍實(shí)在太少。
筆者長(zhǎng)期進(jìn)行Legacy BIOS和UEFI BIOS的ROM開(kāi)發(fā),對(duì)于底層編程有豐富的項(xiàng)目經(jīng)驗(yàn)。因此,萌生了將日常的實(shí)踐經(jīng)驗(yàn)記錄下來(lái)并集結(jié)成冊(cè)的想法。希望能為UEFI的推廣,特別是國(guó)產(chǎn)化計(jì)算機(jī)的發(fā)展,貢獻(xiàn)自己的一份力量。
【本書特點(diǎn)及讀者對(duì)象】
本書以實(shí)踐為主,主要特點(diǎn)如下。
●是為數(shù)不多的介紹國(guó)產(chǎn)計(jì)算機(jī)UEFI開(kāi)發(fā)的書籍。
●針對(duì)每個(gè)主題,都準(zhǔn)備了相應(yīng)的示例和代碼,目的是以實(shí)例講解知識(shí)點(diǎn)。
●偏重于解決實(shí)際項(xiàng)目中遇到的問(wèn)題,包括漢字顯示、構(gòu)建GUI界面、訪問(wèn)PCIE設(shè)備和USB設(shè)備等。
書中詳細(xì)地介紹了如何在Windows/Linux主機(jī)上搭建UEFI開(kāi)發(fā)和調(diào)試環(huán)境,以及構(gòu)建和編譯UEFI程序,非常適合UEFI開(kāi)發(fā)初學(xué)者閱讀,可以幫助他們循序漸進(jìn)地進(jìn)入U(xiǎn)EFI世界。
本書也很適合UEFI的專業(yè)開(kāi)發(fā)者,包括云終端、顯卡、還原卡等領(lǐng)域的開(kāi)發(fā)者使用。書中提供的豐富的源代碼能為項(xiàng)目開(kāi)發(fā)提供很好的參考。
【本書如何閱讀】
開(kāi)發(fā)UEFI程序,要求程序員有C/C 語(yǔ)言的背景。如果了解對(duì)應(yīng)架構(gòu)(比如X86、ARM、RISC -V等)的匯編語(yǔ)言和Python語(yǔ)言,對(duì)于調(diào)試和理解編譯過(guò)程會(huì)更有幫助,當(dāng)然這不是必需的。
本書的代碼倉(cāng)庫(kù)為https://gitee.com/luobing4365/uefi-practical-programming.git或者h(yuǎn)ttps://github.com/luobing/uefi-practical-programming.git。讀者可以使用GIT工具,將代碼下載到本地閱讀。
按照本書介紹的示例進(jìn)行操作,需要用到各種參考手冊(cè),特別是UEFI規(guī)范參考手冊(cè)(目前版本為V2.8)、庫(kù)函數(shù)參考手冊(cè)等。這些文檔可以在www.uefi.org和GitHub的倉(cāng)庫(kù)tianocore/tianocore.github.io中找到。
另外,在調(diào)試UEFI程序的過(guò)程中,會(huì)用到各種調(diào)試工具,包括WINDBG或DBG等,讀者可以根據(jù)自己的知識(shí)背景選擇熟悉的工具。本書沒(méi)有詳細(xì)介紹調(diào)試工具的用法,建議讀者參考張銀奎老師的《軟件調(diào)試》,這也是筆者常備的參考書籍。
【本書共分12章,具體內(nèi)容如下】
第1章 概覽了Legacy BIOS和UEFI BIOS的組成部分,并分析、比較了Legacy BIOS和UEFI BIOS的優(yōu)缺點(diǎn),介紹了UEFI BIOS的組成部分和啟動(dòng)過(guò)程,以及它在國(guó)產(chǎn)計(jì)算機(jī)發(fā)展中所起的作用。
第2章 介紹了如何在Windows和Linux主機(jī)上搭建UEFI的開(kāi)發(fā)環(huán)境和調(diào)試環(huán)境。為方便測(cè)試和調(diào)試UEFI程序,還介紹了如何制作Legacy BIOS和UEFI BIOS下的UEFI啟動(dòng)盤。
第3章 介紹了UEFI中各種工程文件的規(guī)范,包括DSC文件、INF文件和DEC文件等。詳細(xì)描述了構(gòu)建UEFI應(yīng)用和UEFI包的方法,以及如何使用C 語(yǔ)言編寫UEFI程序。
第4章 介紹了UEFI圖形顯示的原理,實(shí)現(xiàn)了各種基本圖形的顯示,并基于圖形函數(shù),使用點(diǎn)陣顯示的方式,在UEFI環(huán)境下顯示漢字。另外介紹了UEFI提供的HII(人機(jī)接口基礎(chǔ)架構(gòu)),以及使用HII實(shí)現(xiàn)漢字和字符串顯示的方法。
第5章 介紹了如何在UEFI環(huán)境下顯示BMP格式、PCX格式和JPEG格式的圖像,以及如何使用HII方式進(jìn)行圖像的顯示。還介紹并實(shí)現(xiàn)了各類圖像特效,其相關(guān)方法可直接應(yīng)用于各類項(xiàng)目中。
第6章 介紹了UEFI下GUI的基本組成和實(shí)現(xiàn),構(gòu)建了初級(jí)的UEFI GUI框架,并將開(kāi)源GUI框架GuiLite移植到了UEFI環(huán)境下。
第7章 介紹了如何使用UEFI提供的API訪問(wèn)各類外設(shè),包括PCI/PCIE設(shè)備、SMBus設(shè)備和串口設(shè)備。
第8章 詳細(xì)介紹了UEFI驅(qū)動(dòng),包括服務(wù)型驅(qū)動(dòng)和UEFI驅(qū)動(dòng)模型。以筆者自制的開(kāi)發(fā)板YIE001為例,介紹了如何編寫一種特殊的UEFI驅(qū)動(dòng)Option ROM,它在顯卡、網(wǎng)卡等板卡設(shè)備上應(yīng)用比較廣泛。
第9章 介紹了USB規(guī)范,以及UEFI下對(duì)USB訪問(wèn)的支持。使用開(kāi)發(fā)板YIE002,實(shí)現(xiàn)了自制的USB HID設(shè)備,并使用它演示如何在UEFI下訪問(wèn)USB HID設(shè)備。
第10章 介紹了如何在實(shí)際的UEFI環(huán)境下,以及各種虛擬機(jī)中,搭建UEFI的網(wǎng)絡(luò)測(cè)試環(huán)境。還介紹了UEFI對(duì)網(wǎng)絡(luò)的支持,以及如何編寫UEFI下的TCP4和TCP6的網(wǎng)絡(luò)程序。
第11章 介紹了龍芯的發(fā)展歷史,以及目前的產(chǎn)品線。以龍芯主打的桌面級(jí)產(chǎn)品3A4000為例,介紹了龍芯CPU架構(gòu)和指令集,以及如何使用Linux Lab學(xué)習(xí)龍芯的指令集和匯編語(yǔ)言。另外介紹了如何使用廠商提供的代碼和工具,配合開(kāi)源的EDK2代碼,搭建龍芯平臺(tái)的UEFI開(kāi)發(fā)環(huán)境。
第12章 介紹了飛騰平臺(tái)的系列產(chǎn)品,以桌面級(jí)產(chǎn)品FT-2000/4為例,對(duì)飛騰CPU架構(gòu)和指令集進(jìn)行了概括性描述,并使用ARM提供的開(kāi)源工具,配合EDK2代碼,搭建了支持包括飛騰在內(nèi)的ARM64的UEFI開(kāi)發(fā)環(huán)境。為方便沒(méi)有實(shí)際飛騰硬件平臺(tái)的開(kāi)發(fā)人員使用和實(shí)驗(yàn),還介紹了如何使用QEMU搭建飛騰平臺(tái)的UEFI測(cè)試環(huán)境。
對(duì)讀者而言,如果是為X86平臺(tái)開(kāi)發(fā)UEFI項(xiàng)目,建議先熟悉第1~3章的內(nèi)容,然后根據(jù)自己的需要選擇相應(yīng)的章節(jié)進(jìn)行閱讀;如果是為國(guó)產(chǎn)計(jì)算機(jī)平臺(tái)開(kāi)發(fā)項(xiàng)目,則建議熟悉了第1~3章和第11~12章后,再去選擇相應(yīng)的章節(jié)進(jìn)行學(xué)習(xí)。
●第1章 UEFI的世界 1
1.1 Legacy BIOS1
1.1.1 Legacy BIOS的啟動(dòng)過(guò)程2
1.1.2 Legacy BIOS的不足之處4
1.2 UEFI BIOS6
1.2.1 UEFI標(biāo)準(zhǔn)概述6
1.2.2 UEFI BIOS的優(yōu)點(diǎn)8
1.2.3 UEFI BIOS的啟動(dòng)過(guò)程9
1.2.4 國(guó)產(chǎn)計(jì)算機(jī)與UEFI13
1.3 本章小結(jié)15
●第2章 UEFI開(kāi)發(fā)和調(diào)試環(huán)境搭建16
2.1 搭建Windows下的UEFI開(kāi)發(fā)環(huán)境17
2.1.1 安裝開(kāi)發(fā)工具17
2.1.2 配置開(kāi)發(fā)環(huán)境18
2.1.3 編譯UEFI模擬器和UEFI程序20
2.1.4 使用模擬器運(yùn)行UEFI程序22
2.2 Windows下調(diào)試UEFI程序24
2.2.1 使用Visual Studio調(diào)試UEFI程序24
2.2.2 使用WINDBG調(diào)試UEFI程序27
2.3 搭建Linux下的UEFI開(kāi)發(fā)環(huán)境30
2.3.1 安裝開(kāi)發(fā)工具31
2.3.2 配置開(kāi)發(fā)環(huán)境32
2.3.3 編譯UEFI模擬器和UEFI程序32
2.3.4 使用模擬器運(yùn)行UEFI程序33
2.4 Linux下調(diào)試UEFI程序34
2.4.1 使用GDB調(diào)試UEFI程序34
2.4.2 使用Intel UDK Debugger Tool和GDB調(diào)試UEFI程序37
2.5 制作UEFI啟動(dòng)盤40
2.6 本章小結(jié)41
●第3章 構(gòu)建UEFI應(yīng)用42
3.1 模塊和包概述42
3.2 搭建UEFI工程模塊44
3.2.1 DSC文件44
3.2.2 INF文件50
3.2.3 3種入口函數(shù)的UEFI應(yīng)用55
3.2.4 庫(kù)模塊的編寫61
3.2.5 其他工程文件63
3.3 搭建UEFI包72
3.3.1 包的DSC和DEC文件72
3.3.2 添加并編譯模塊73
3.4 用C 編寫UEFI應(yīng)用74
3.4.1 支持基礎(chǔ)功能75
3.4.2 支持全局類77
3.5 使用UEFI Protocol81
3.5.1 Protocol概述81
3.5.2 支持使用Protocol的函數(shù) 83
3.5.3 使用Protocol示例91
3.6 本章小結(jié)93
●第4章 圖形與漢字顯示94
4.1 UEFI圖形顯示95
4.1.1 圖形顯示的Protocol 95
4.1.2 圖形顯示基本函數(shù)的實(shí)現(xiàn)101
4.2 UEFI漢字顯示寫像素點(diǎn)的方式107
4.2.1 點(diǎn)陣字的顯示與字庫(kù)提取108
4.2.2 寫像素點(diǎn)的漢字顯示110
4.3 UEFI漢字顯示HII方式115
4.3.1 HII字體與字庫(kù)提取116
4.3.2 HII漢字顯示119
4.3.3 HII字符串127
4.4 本章小結(jié)132
●第5章 圖像顯示及特效133
5.1 UEFI圖像顯示寫屏方式134
5.1.1 BMP圖像顯示 134
5.1.2 PCX圖像顯示140
5.1.3 JPEG圖像顯示145
5.2 UEFI圖像顯示HII方式150
5.2.1 圖像處理Protocol150
5.2.2 HII圖像顯示153
5.3 圖像顯示的特效 157
5.3.1 圖像塊處理基本函數(shù)的實(shí)現(xiàn)157
5.3.2 顏色變換特效161
5.3.3 鏡像顯示165
5.3.4 圖像塊顯示與清屏166
5.4 本章小結(jié)170
●第6章 GUI開(kāi)發(fā)與移植172
6.1 支持GUI的基礎(chǔ)服務(wù) 172
6.1.1 UEFI事件處理 173
6.1.2 UEFI鍵盤處理179
6.1.3 UEFI鼠標(biāo)處理 185
6.1.4 構(gòu)建GUI框架186
6.2 開(kāi)源GUI框架191
6.2.1 GuiLite介紹191
6.2.2 使用GuiLite編程 195
6.3 GUI框架的移植200
6.4 本章小結(jié)203
●第7章 UEFI環(huán)境下訪問(wèn)外設(shè)205
7.1 訪問(wèn)PCI/PCIE設(shè)備205
7.1.1 與PCI/PCIE設(shè)備通信的機(jī)制206
7.1.2 支持訪問(wèn)PCI/PCIE設(shè)備的Protocol209
7.1.3 訪問(wèn)PCI/PCIE設(shè)備示例213
7.2 訪問(wèn)SMBus設(shè)備216
7.2.1 SMBus協(xié)議簡(jiǎn)介216
7.2.2 支持訪問(wèn)SMBus設(shè)備的Protocol218
7.2.3 訪問(wèn)SMBus設(shè)備示例220
7.3 訪問(wèn)串口設(shè)備223
7.3.1 串口協(xié)議簡(jiǎn)介223
7.3.2 支持訪問(wèn)串口設(shè)備的Protocol225
7.3.3 訪問(wèn)串口設(shè)備示例228
7.4 本章小結(jié)230
●第8章 UEFI驅(qū)動(dòng)與Option ROM232
8.1 服務(wù)型驅(qū)動(dòng)233
8.1.1 安裝與卸載Protocol233
8.1.2 構(gòu)建服務(wù)型驅(qū)動(dòng)236
8.1.3 訪問(wèn)示例Protocol242
8.2 UEFI驅(qū)動(dòng)模型243
8.2.1 EFI Driver Binding Protocol 243
8.2.2 EFI Component Name Protocol247
8.2.3 完成驅(qū)動(dòng)框架及其測(cè)試248
8.2.4 構(gòu)建UEFI驅(qū)動(dòng)及其測(cè)試程序251
8.2.5 測(cè)試UEFI驅(qū)動(dòng)256
8.3 編寫Option ROM258
8.3.1 PCI Option ROM簡(jiǎn)介258
8.3.2 編寫UEFI Option ROM264
8.3.3 編譯及測(cè)試Option ROM268
8.4 本章小結(jié)272
●第9章 UEFI與USB273
9.1 USB規(guī)范簡(jiǎn)介274
9.1.1 USB通信原理276
9.1.2 USB描述符280
9.1.3 USB標(biāo)準(zhǔn)命令285
9.1.4 USB HID設(shè)備287
9.2 支持USB訪問(wèn)的Protocol292
9.2.1 EFI_USB2_HC_PROTOCOL292
9.2.2 EFI_USB_IO_PROTOCOL294
9.2.3 列舉USB控制器和設(shè)備297
9.3 訪問(wèn)USB HID設(shè)備299
9.3.1 制作USB HID設(shè)備299
9.3.2 在UEFI下訪問(wèn)USB HID設(shè)備305
9.4 本章小結(jié)307
●第10章 UEFI與網(wǎng)絡(luò)309
10.1 準(zhǔn)備UEFI網(wǎng)絡(luò)測(cè)試環(huán)境311
10.1.1 搭建Nt32模擬器的網(wǎng)絡(luò)環(huán)境311
10.1.2 在真實(shí)UEFI環(huán)境下使用網(wǎng)絡(luò)313
10.1.3 在虛擬機(jī)UEFI環(huán)境下使用網(wǎng)絡(luò):VirtualBox314
10.1.4 在虛擬機(jī)UEFI環(huán)境下使用網(wǎng)絡(luò):QEMU314
10.1.5 IPv6網(wǎng)絡(luò)測(cè)試環(huán)境搭建316
10.2 使用UEFI Protocol開(kāi)發(fā)網(wǎng)絡(luò)程序317
10.2.1 開(kāi)發(fā)Windows的TCP4服務(wù)端程序318
10.2.2 開(kāi)發(fā)UEFI的TCP4客戶端程序323
10.3 使用StdLib的Socket接口開(kāi)發(fā)網(wǎng)絡(luò)程序334
10.3.1 使用Socket編寫UEFI TCP4客戶端程序334
10.3.2 開(kāi)發(fā)Windows的TCP6服務(wù)端程序337
10.3.3 使用Socket編寫UEFI TCP6客戶端程序340
10.4 本章小結(jié)342
●第11章 龍芯平臺(tái)上開(kāi)發(fā)UEFI程序343
11.1 龍芯平臺(tái)概述343
11.1.1 龍芯產(chǎn)品介紹344
11.1.2 3A4000的CPU架構(gòu)簡(jiǎn)介346
11.2 龍芯匯編語(yǔ)言348
11.2.1 安裝Linux Lab349
11.2.2 龍芯匯編語(yǔ)言實(shí)驗(yàn)351
11.3 龍芯平臺(tái)UEFI開(kāi)發(fā)環(huán)境354
11.3.1 搭建龍芯平臺(tái)UEFI開(kāi)發(fā)環(huán)境355
11.3.2 編譯示例工程356
11.4 本章小結(jié)357
●第12章 飛騰平臺(tái)上開(kāi)發(fā)UEFI程序358
12.1 飛騰平臺(tái)概述359
12.1.1 飛騰產(chǎn)品介紹359
12.1.2 FT-2000/4的CPU架構(gòu)簡(jiǎn)介361
12.2 搭建飛騰平臺(tái)UEFI開(kāi)發(fā)環(huán)境363
12.2.1 準(zhǔn)備EDK2環(huán)境364
12.2.2 使用Linux系統(tǒng)與gcc-arm365
12.2.3 使用Linux系統(tǒng)與Linaro UEFI工具367
12.3 飛騰平臺(tái)的UEFI程序測(cè)試368
12.3.1 Windows系統(tǒng)下的UEFI測(cè)試環(huán)境369
12.3.2 Linux系統(tǒng)下的UEFI測(cè)試環(huán)境372
12.3.3 測(cè)試示例工程372
12.4 本章小結(jié)374
附錄 UEFI Shell內(nèi)置命令375