【前 言】
2011年9月,筆者次接觸UEFI的項(xiàng)目。
當(dāng)時,我們正與國內(nèi)某PC大廠合作,開發(fā)一款安全計(jì)算機(jī)。這款產(chǎn)品包含一個嵌入BIOS中的軟件模塊,此模塊是用匯編語言編寫的Option ROM。由于合作方計(jì)劃將BIOS架構(gòu)全部轉(zhuǎn)為UEFI,因此要求我們將軟件模塊移植到UEFI架構(gòu)下。
在對UEFI的理解還非常初級的情況下,筆者忐忑地接下了任務(wù)。用了三周時間,在AMI的集成工具上,筆者使用C語言將原有的軟件模塊重寫為了UEFI驅(qū)動,總算是圓滿完成了任務(wù)。
這之后,筆者花了不少時間去研究UEFI的公開文檔,嘗試著做了很多實(shí)驗(yàn)。在此期間,UEFI規(guī)范從2.3升級到2.8;身邊的計(jì)算機(jī)運(yùn)行Legacy BIOS的越來越少,運(yùn)行UEFI BIOS的越來越多。UEFI的開發(fā)效率高、可擴(kuò)展性好,而且系統(tǒng)性能和安全性都很高,支持X86、ARM和RISC-V等多種指令集架構(gòu)。時至今日,UEFI已經(jīng)成為事實(shí)上的BIOS標(biāo)準(zhǔn),所有有志于底層開發(fā)的工程師都有必要深入了解UEFI架構(gòu)及其編程方法。
【本書的寫作初衷】
因十年前的項(xiàng)目機(jī)緣,筆者開始學(xué)習(xí)UEFI的相關(guān)知識,并利用業(yè)余時間,以UEFI開發(fā)探索為名,撰寫了UEFI開發(fā)的系列博客。在此期間,認(rèn)識了不少業(yè)界的朋友,在產(chǎn)品開發(fā)、市場推廣方面,我們有過相當(dāng)多的探討。
也是因?yàn)槿绱耍?dāng)國產(chǎn)自主計(jì)算機(jī)從前幾年開始大批量出貨,而大部分BIOS采用了UEFI架構(gòu)時,筆者一點(diǎn)都不感到奇怪。基于此認(rèn)識,公司的產(chǎn)品針對國產(chǎn)自主計(jì)算機(jī)的軟件架構(gòu)進(jìn)行了較大改造,如果沒有UEFI架構(gòu)的支持,這是做不到的。
在產(chǎn)品開發(fā)的過程中,能夠參考的資料,除去UEFI規(guī)范等公開資料外,英文資料有Intel Press出版的Beyond BIOS和Harnessing the UEFI Shell。中文資料,則只有戴正華老師的《UEFI原理與編程》。作為主流的BIOS架構(gòu),可供參考的書籍實(shí)在太少。
筆者長期進(jìn)行Legacy BIOS和UEFI BIOS的ROM開發(fā),對于底層編程有豐富的項(xiàng)目經(jīng)驗(yàn)。因此,萌生了將日常的實(shí)踐經(jīng)驗(yàn)記錄下來并集結(jié)成冊的想法。希望能為UEFI的推廣,特別是國產(chǎn)化計(jì)算機(jī)的發(fā)展,貢獻(xiàn)自己的一份力量。
【本書特點(diǎn)及讀者對象】
本書以實(shí)踐為主,主要特點(diǎn)如下。
●是為數(shù)不多的介紹國產(chǎn)計(jì)算機(jī)UEFI開發(fā)的書籍。
●針對每個主題,都準(zhǔn)備了相應(yīng)的示例和代碼,目的是以實(shí)例講解知識點(diǎn)。
●偏重于解決實(shí)際項(xiàng)目中遇到的問題,包括漢字顯示、構(gòu)建GUI界面、訪問PCIE設(shè)備和USB設(shè)備等。
書中詳細(xì)地介紹了如何在Windows/Linux主機(jī)上搭建UEFI開發(fā)和調(diào)試環(huán)境,以及構(gòu)建和編譯UEFI程序,非常適合UEFI開發(fā)初學(xué)者閱讀,可以幫助他們循序漸進(jìn)地進(jìn)入UEFI世界。
本書也很適合UEFI的專業(yè)開發(fā)者,包括云終端、顯卡、還原卡等領(lǐng)域的開發(fā)者使用。書中提供的豐富的源代碼能為項(xiàng)目開發(fā)提供很好的參考。
【本書如何閱讀】
開發(fā)UEFI程序,要求程序員有C/C 語言的背景。如果了解對應(yīng)架構(gòu)(比如X86、ARM、RISC -V等)的匯編語言和Python語言,對于調(diào)試和理解編譯過程會更有幫助,當(dāng)然這不是必需的。
本書的代碼倉庫為https://gitee.com/luobing4365/uefi-practical-programming.git或者h(yuǎn)ttps://github.com/luobing/uefi-practical-programming.git。讀者可以使用GIT工具,將代碼下載到本地閱讀。
按照本書介紹的示例進(jìn)行操作,需要用到各種參考手冊,特別是UEFI規(guī)范參考手冊(目前版本為V2.8)、庫函數(shù)參考手冊等。這些文檔可以在www.uefi.org和GitHub的倉庫tianocore/tianocore.github.io中找到。
另外,在調(diào)試UEFI程序的過程中,會用到各種調(diào)試工具,包括WINDBG或DBG等,讀者可以根據(jù)自己的知識背景選擇熟悉的工具。本書沒有詳細(xì)介紹調(diào)試工具的用法,建議讀者參考張銀奎老師的《軟件調(diào)試》,這也是筆者常備的參考書籍。
【本書共分12章,具體內(nèi)容如下】
第1章 概覽了Legacy BIOS和UEFI BIOS的組成部分,并分析、比較了Legacy BIOS和UEFI BIOS的優(yōu)缺點(diǎn),介紹了UEFI BIOS的組成部分和啟動過程,以及它在國產(chǎn)計(jì)算機(jī)發(fā)展中所起的作用。
第2章 介紹了如何在Windows和Linux主機(jī)上搭建UEFI的開發(fā)環(huán)境和調(diào)試環(huán)境。為方便測試和調(diào)試UEFI程序,還介紹了如何制作Legacy BIOS和UEFI BIOS下的UEFI啟動盤。
第3章 介紹了UEFI中各種工程文件的規(guī)范,包括DSC文件、INF文件和DEC文件等。詳細(xì)描述了構(gòu)建UEFI應(yīng)用和UEFI包的方法,以及如何使用C 語言編寫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)建了初級的UEFI GUI框架,并將開源GUI框架GuiLite移植到了UEFI環(huán)境下。
第7章 介紹了如何使用UEFI提供的API訪問各類外設(shè),包括PCI/PCIE設(shè)備、SMBus設(shè)備和串口設(shè)備。
第8章 詳細(xì)介紹了UEFI驅(qū)動,包括服務(wù)型驅(qū)動和UEFI驅(qū)動模型。以筆者自制的開發(fā)板YIE001為例,介紹了如何編寫一種特殊的UEFI驅(qū)動Option ROM,它在顯卡、網(wǎng)卡等板卡設(shè)備上應(yīng)用比較廣泛。
第9章 介紹了USB規(guī)范,以及UEFI下對USB訪問的支持。使用開發(fā)板YIE002,實(shí)現(xiàn)了自制的USB HID設(shè)備,并使用它演示如何在UEFI下訪問USB HID設(shè)備。
第10章 介紹了如何在實(shí)際的UEFI環(huán)境下,以及各種虛擬機(jī)中,搭建UEFI的網(wǎng)絡(luò)測試環(huán)境。還介紹了UEFI對網(wǎng)絡(luò)的支持,以及如何編寫UEFI下的TCP4和TCP6的網(wǎng)絡(luò)程序。
第11章 介紹了龍芯的發(fā)展歷史,以及目前的產(chǎn)品線。以龍芯主打的桌面級產(chǎn)品3A4000為例,介紹了龍芯CPU架構(gòu)和指令集,以及如何使用Linux Lab學(xué)習(xí)龍芯的指令集和匯編語言。另外介紹了如何使用廠商提供的代碼和工具,配合開源的EDK2代碼,搭建龍芯平臺的UEFI開發(fā)環(huán)境。
第12章 介紹了飛騰平臺的系列產(chǎn)品,以桌面級產(chǎn)品FT-2000/4為例,對飛騰CPU架構(gòu)和指令集進(jìn)行了概括性描述,并使用ARM提供的開源工具,配合EDK2代碼,搭建了支持包括飛騰在內(nèi)的ARM64的UEFI開發(fā)環(huán)境。為方便沒有實(shí)際飛騰硬件平臺的開發(fā)人員使用和實(shí)驗(yàn),還介紹了如何使用QEMU搭建飛騰平臺的UEFI測試環(huán)境。
對讀者而言,如果是為X86平臺開發(fā)UEFI項(xiàng)目,建議先熟悉第1~3章的內(nèi)容,然后根據(jù)自己的需要選擇相應(yīng)的章節(jié)進(jìn)行閱讀;如果是為國產(chǎn)計(jì)算機(jī)平臺開發(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的啟動過程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的啟動過程9
1.2.4 國產(chǎn)計(jì)算機(jī)與UEFI13
1.3 本章小結(jié)15
●第2章 UEFI開發(fā)和調(diào)試環(huán)境搭建16
2.1 搭建Windows下的UEFI開發(fā)環(huán)境17
2.1.1 安裝開發(fā)工具17
2.1.2 配置開發(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開發(fā)環(huán)境30
2.3.1 安裝開發(fā)工具31
2.3.2 配置開發(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啟動盤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 庫模塊的編寫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)陣字的顯示與字庫提取108
4.2.2 寫像素點(diǎn)的漢字顯示110
4.3 UEFI漢字顯示HII方式115
4.3.1 HII字體與字庫提取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開發(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 開源GUI框架191
6.2.1 GuiLite介紹191
6.2.2 使用GuiLite編程 195
6.3 GUI框架的移植200
6.4 本章小結(jié)203
●第7章 UEFI環(huán)境下訪問外設(shè)205
7.1 訪問PCI/PCIE設(shè)備205
7.1.1 與PCI/PCIE設(shè)備通信的機(jī)制206
7.1.2 支持訪問PCI/PCIE設(shè)備的Protocol209
7.1.3 訪問PCI/PCIE設(shè)備示例213
7.2 訪問SMBus設(shè)備216
7.2.1 SMBus協(xié)議簡介216
7.2.2 支持訪問SMBus設(shè)備的Protocol218
7.2.3 訪問SMBus設(shè)備示例220
7.3 訪問串口設(shè)備223
7.3.1 串口協(xié)議簡介223
7.3.2 支持訪問串口設(shè)備的Protocol225
7.3.3 訪問串口設(shè)備示例228
7.4 本章小結(jié)230
●第8章 UEFI驅(qū)動與Option ROM232
8.1 服務(wù)型驅(qū)動233
8.1.1 安裝與卸載Protocol233
8.1.2 構(gòu)建服務(wù)型驅(qū)動236
8.1.3 訪問示例Protocol242
8.2 UEFI驅(qū)動模型243
8.2.1 EFI Driver Binding Protocol 243
8.2.2 EFI Component Name Protocol247
8.2.3 完成驅(qū)動框架及其測試248
8.2.4 構(gòu)建UEFI驅(qū)動及其測試程序251
8.2.5 測試UEFI驅(qū)動256
8.3 編寫Option ROM258
8.3.1 PCI Option ROM簡介258
8.3.2 編寫UEFI Option ROM264
8.3.3 編譯及測試Option ROM268
8.4 本章小結(jié)272
●第9章 UEFI與USB273
9.1 USB規(guī)范簡介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訪問的Protocol292
9.2.1 EFI_USB2_HC_PROTOCOL292
9.2.2 EFI_USB_IO_PROTOCOL294
9.2.3 列舉USB控制器和設(shè)備297
9.3 訪問USB HID設(shè)備299
9.3.1 制作USB HID設(shè)備299
9.3.2 在UEFI下訪問USB HID設(shè)備305
9.4 本章小結(jié)307
●第10章 UEFI與網(wǎng)絡(luò)309
10.1 準(zhǔn)備UEFI網(wǎng)絡(luò)測試環(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ò)測試環(huán)境搭建316
10.2 使用UEFI Protocol開發(fā)網(wǎng)絡(luò)程序317
10.2.1 開發(fā)Windows的TCP4服務(wù)端程序318
10.2.2 開發(fā)UEFI的TCP4客戶端程序323
10.3 使用StdLib的Socket接口開發(fā)網(wǎng)絡(luò)程序334
10.3.1 使用Socket編寫UEFI TCP4客戶端程序334
10.3.2 開發(fā)Windows的TCP6服務(wù)端程序337
10.3.3 使用Socket編寫UEFI TCP6客戶端程序340
10.4 本章小結(jié)342
●第11章 龍芯平臺上開發(fā)UEFI程序343
11.1 龍芯平臺概述343
11.1.1 龍芯產(chǎn)品介紹344
11.1.2 3A4000的CPU架構(gòu)簡介346
11.2 龍芯匯編語言348
11.2.1 安裝Linux Lab349
11.2.2 龍芯匯編語言實(shí)驗(yàn)351
11.3 龍芯平臺UEFI開發(fā)環(huán)境354
11.3.1 搭建龍芯平臺UEFI開發(fā)環(huán)境355
11.3.2 編譯示例工程356
11.4 本章小結(jié)357
●第12章 飛騰平臺上開發(fā)UEFI程序358
12.1 飛騰平臺概述359
12.1.1 飛騰產(chǎn)品介紹359
12.1.2 FT-2000/4的CPU架構(gòu)簡介361
12.2 搭建飛騰平臺UEFI開發(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 飛騰平臺的UEFI程序測試368
12.3.1 Windows系統(tǒng)下的UEFI測試環(huán)境369
12.3.2 Linux系統(tǒng)下的UEFI測試環(huán)境372
12.3.3 測試示例工程372
12.4 本章小結(jié)374
附錄 UEFI Shell內(nèi)置命令375