![]() |
進學致和,行方思遠。 |
在「write uefi program without edk2」之後, 我已經不用 edk2 來開發 uefi, 當然也不用在處理哪些可怕的 inf, dsc 檔案。
使用 c++ 也不需要像這篇這麼花功夫, 之後不會用本篇的方法來使用 c++, 這篇就留個紀錄。
我也知道為什麼 global object ctor 沒有被正常喚起, 因為沒做任何事情, 本來就不會被正常喚起, 手動呼叫 GLOBAL_XX function 算是正常用法。
以下原文:
edk2 並沒有支援用 c++ 來開發 uefi 程式, 我真是不敢相信還有這麼原始的開發環境, 竟然不支援 c++。我可是 c++ 愛好者, 不能用自己喜歡的語言開發程式, 感覺很不爽。
c++ 的好處我說過好幾次了 (疑! 我根本沒說過!!), c 我也是可以寫的, 為什麼堅持用 c++ 呢? 還真的說不上原因, 大概是網路上很多的討論都對 c++ 很不好, 什麼 XX 比不上 C, YY 比不上 JAVA, 這些言論更讓我對 c++ 抱不平, 決定要多多推廣 c++, 我又不善
《UEFI原理与编程》第十章說明如何用 c++ (g++) 來開發 uefi 程式並提供了 GcppPkg 這個範例, 不過很可惜, 這部份書上寫的不夠詳細, 我花費了不少時間還是搞不定怎麼使用這個範例。
最後我做了和 GcppPkg 類似的事情, 再加上《UEFI原理与编程》第十章的說明, 搞出了自己的 c++ 作法。所以我雖然沒搞定書上的 GcppPkg 範例, 但是書中內容還是幫了我不少。
最困難的是編譯環境, 花了不少時間我才搞定 (沒有搞懂, 是搞定), 找了 edk2/AppPkg/Applications/Main/Main.c 來修改, 這是使用 c 語言 main 的開發方式。
我建立了 edk2/AppPkg/Applications/Main/m.cpp (從 edk2/AppPkg/Applications/Main/Main.c 複製而來), 也複製了一份 m.inf, m.inf 最重要的是 L27 ~ 42, 把 source code 的檔案填進去, build 就會去編譯這些檔案。
再來是把這個 m.inf 加到 AppPkg.dsc。
以下是測試的 c++ 檔案。cout 和 vector 不是 edk2 提供的, 是移植我那個玩具標準 c++ 程式庫得來的, namespace 是 DS 而不是 std, 書上的範例是移植 stl 過來, 我既然已經有自己的版本, 玩具歸玩具, 沒道理不用的。
還順便測試一下目前最潮的 lambda 語法。
還有 setjmp/longjmp x64 的版本。
build -p AppPkg/AppPkg.dsc 就可以編譯出 m.efi 了, 不過先別急著打這個指令, 還要寫個 script gcc (書上提供了一個, 照抄後再加上 g++ option, ref list 1), 判斷是 .c 檔時出動 gcc, .cpp 檔時出動 g++。當然也可能要修改 uefi/edk2/BaseTools/Scripts/GccBase.lds, 不過目前就不要搞太複雜, 這樣就可以了。
好了, 現在可以痛快的敲下 build -p AppPkg/AppPkg.dsc
fig 2 為測試畫面, ctor/dtor 正常發動了, lambda 也正常, DS::vector, DS::cout 也正常, 感謝 bjarne stroustrup; 感謝 c++。
![]() |
fig 2模擬器測試畫面 |
為了保險起見, 我在真實機器上同樣也做了測試, 真的是可以跑的。
真實機器的 uefi 執行畫面 |
global object ctor/dtor 沒有搞定, 比我想的還複雜些, 這不是什麼問題, 不要用就好了。 XD
我是用手動呼叫 GLOBAL_XX function 來搞定這件事。
uefi-shceme 就是這麼做的。
uefi function 手冊: http://www.bluestop.org/edk2/docs/trunk/getchar_8c.html