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