導航:首頁 > 軟體知識 > UEFI程序運行時如何編譯

UEFI程序運行時如何編譯

發布時間:2022-12-28 16:11:26

1. ubuntu中UEFI在環境中運行Hello world

運行「make -C BaseTools」。
具體步驟:
首先安裝必須的軟體:sudo apt-get install build-essential uuid-dev iasl git gcc-5 nasm python3-distutils。
第二步,將edk2-vUDK2018.tar.gz解壓到~/src/MyWorkspace下。
第三步,拷貝OpenSSL Crypto Library,到指定的網站下載openssl庫解壓到指定文件夾下。
第四步,生成BaseTools。進入目錄~/src/MyWorkspace,運行「make -C BaseTools」,生成所需的工具軟體。

2. 如何生成uefi啟動文件 如何添加UEFI啟動

uefi作為傳統bios的接班者,擁有圖形化界面、植入硬體驅動等bios無法支持的功能,早在win8發布時就已宣布全面支持uefi,讓眾多主板廠商爭相把uefi作為主板標准配置之一。日前,u深度發布出uefi版u盤啟動盤製作工具,方便使用ufei啟動的電腦實現u盤啟動,現在我們就給大家介紹u深度uefi版啟動盤製作工具製作uefi啟動u盤的步驟。

製作ufei啟動u盤前,需要准備一個可以正常使用的u盤,推薦使用容量2GB以上的空間大小。

1、運行u深度v3.0ufei版u盤啟動盤製作工具,如圖所示:

以上關於運用u深度ufei版製作uefi啟動u盤的全過程,首次使用該軟體的用戶可以參照以上步驟進行學習製作。在使用ufei啟動u盤進入電腦時,需要注意選擇uefi開頭的啟動項才可以體驗uefi啟動的效果。

3. 第五章 UEFI 的基礎服務

[TOC]

系統表是重要的數據介面之一,是用戶空間通往內核空間的通道。

(1)在應用程序和驅動中訪問系統表

系統表是 UEFI 內核的一個全局結構體,其指針作為程序映像入口函數的參數傳遞到用戶空間。程序映像(包括 UEFI 應用程序、DXE 驅動程序、UEFI 驅動程序)的入口函數有統一的格式,函數原型如下:

(2)系統表指針從內核傳遞到用戶空間的過程

程序映像的入口函數通常是 _MoleEntryPoint。當應用程序或驅動載入到內存形成 Image 後,_MoleEntryPoint 函數地址被賦值給 Image 對象的 EntryPoint,然後 Image->EntryPoint 會被執行,最終會從 Image 的入口函數 _MoleEntryPoint 執行到模塊的入口函數。

系統表可分為以下6個部分

系統表數據結構:

UEFI 中的表通常都以 EFI_TABLE_HEADER 開頭,數據結構如下:

這三個控制台設備以及 ConIn、ConOut、StdErr 三個 Protocol 在驅動 ConSplitterDxe 中被初始化。

ConfigurationTable 是系統配置表,指向 EFI_CONFIGUTATION_TABLE 數組,數組中每一項是一個表,這個表的數據結構如下:

在 UEFI 中只有一個地址空間,所有程序都運行在 RING0 優先順序,應用程序地址空間(用戶空間)佔用 UEFI 地址空間的一部分。

系統表的地址可以通過模塊的入口函數的參數得到。示例:

上面示例中的模塊入口函數 UefiMain 中使用傳入的參數 SystemTable 訪問系統表。EDK2 為了方便開發者,提供了 UefiBootServicesTableLib,在 UefiLib 定義了全局變數 gST
、gBS、gImageHandle。這三個全局變數在函數 中被初始化,該函數是庫 UefiBootServicesTableLib 的構造函數,在 AutoGen.c 中的 ProcessLibraryConstructorList 被調用,而 ProcessLibraryConstructorList 是在 UefiMain 之前被調用的。

構造函數 源碼:

gST 變數是定義在用戶空間的變數,而它指向的系統表定義在 UEFI 內核中。在應用程序或驅動工程文件的 [LibraryClasses] 里引用 UefiBootServicesTableLib 後,就可以使用 gST 訪問系統表了。示例:

其實就是使用 gST 和 gBS 替換掉 SystemTable 和 SystemTable->BootServices。

啟動服務是 UEFI 的核心數據結構,可以分為以下幾類:UEFI 事件服務、內存管理服務、Protocol 管理服務、Protocol 使用類服務、驅動管理服務、Image 管理服務、ExitBootServices、其他服務。

啟動服務由 UEFI 表頭和表項組成,表中每一項是一個函數指針,該函數用於提供一項服務。

事件是非同步操作的基礎,使得在 UEFI 系統內可以執行並發操作。UEFI 事件服務包含事件(Event)、定時器(Timer)、任務優先順序(TPL)三類服務。

詳見第六章。

內存管理服務主要提供內存的分配與釋放服務、管理系統內存映射。主要包括:AllocatePages、FreePages、AllocatePool、FreePool、GetMemoryMap。

AllocatePool/FreePool 用法

AllocatePool 和 FreePool 服務函數原型:

枚舉類型 EFI_MEMORY_TYPE:

調用 gBS->ExitBootServices 之後, EfiBootServicesCode 和 EfiBootServicesData 類型內存被回收;EfiLoaderCode 和 EfiLoaderData 由 OS Loader 和操作系統決定是否回收;EfiACPIReclaimMemory 類型內存在 APCI 啟用後被回收;其他類型內存保留。

AllocatePages/FreePages 用法

內存和驅動開發中經常會要求分配到的內存不得跨頁,或需要分配完整的內存頁,為此提供了分配頁的服務 AllocatePages。

AllocatePages 和 FreePages 服務函數原型:

枚舉類型 EFI_AlLOCATE_TYPE

GetMemoryMap 用法

GetMemoryMap 用於取得系統中所有的內存映射。

GetMemoryMap 服務函數原型:

EFI_MEMORY_DESCRIPTOR 數據結構

Protocol 管理服務提供安裝與卸載 Protocol 的服務,以及注冊 Protocol 通知函書(安裝時調用)的服務。

詳見第八章、第九章。

Protocol 使用類服務包括 Protocol 的打開與關閉,查找支持 Protocol 的控制器,主要提供 Protocol 使用者使用。

詳見第四章。

驅動管理服務包括將驅動安裝到控制器的 connect 服務和將驅動從控制器上卸載的 disconnect 服務。

詳見第九章。

Image 管理服務包括載入、卸載、啟動、退出 UEFI 應用程序或驅動。

啟動服務中的 Image 管理服務

ExitBootService 用於結束啟動服務,該服務成功返回後,系統進入 RT 期。操作系統載入器從啟動服務接過對計算機系統的控制權後必須調用該服務。

啟動服務中的其他服務

從進入 DXE 階段運行時服務被初始化,直到操作系統結束,運行時服務都一直存在並向上層提供服務。運行時服務主要包括:時間服務、讀寫系統變數、虛擬內存服務、其他服務。

時間服務包括:讀取 / 設置硬體事件、讀取 / 設置喚醒定時器。

GetTime/SetTime

計算機硬體時鍾由單獨的電池供電,操作系統啟動時通過讀取硬體時鍾獲得事件。

GetTime/SetTime 服務函數原型:

時鍾性能用 EFI_TIME_CAPABILITIES 表示:

GetWakeupTime/SetWakeupTime

GetWakeupTime 用於讀取喚醒定時器的狀態,SetWakeupTime 用於啟用或禁用喚醒定時器。

GetWakeupTime/SetWakeupTime 服務函數原型:

UEFI 系統變數服務包括:GetVariable、SetVariable、GetNextVariableName。

GetVariable 用法

GetVariable 用於根據變數名獲取變數值和屬性。

GetVariable 服務函數原型:

SetVariable 用法

SetVariable 有三項功能:新建、更新、刪除變數。

SetVariable 服務函數原型:

GetNextVariableName 用法

GetNextVariableName 用於獲取下一個系統變數,通過這個服務可以遍歷系統中的變數。

GetNextVariableName 服務函數原型:

要啟動搜索(獲得第一個變數),需要 VariableName 指向空字元串。

虛擬內存服務包括:SetVirtualAddressMap 和 ConvertPointer。這兩個服務只有在運行時期間被操作系統載入器調用。

調用流程:

SetVirtualAddressMap/ConvertPointer 服務函數原型:

*Address 作為輸入參數時是物理地址,作為輸出參數時返回對應的虛擬地址。ConvertPointer 通過查詢系統的內存映射表計算出給定物理地址的虛擬地址。當 DebugDispositon 設置了 EFI_OPTION_PTR 標志時,輸入參數 *Address 允許為空。

4. 編譯UEFI版本Grub2引導多系統文件efi

官網源碼地址
首先要從grub官網下在grub2,grub2中包含所有grub2相關的命令,可以用來生成grub2引導,這里著重介紹製作UEFI版本的grub2

內置配置文件為:grub.cfg,內置配置文件搜索/EFI/grub/compile.cfg 文件,並將其設定為配置文件。
將其保存在grub2解壓的壓縮目錄下,內容如下:

在grub2壓縮包下面解壓目錄下打開命令行,輸入以下命令:下面是編譯64的文件

以上生成完畢,在文件夾下會出現一個bootx64.efi文件,BOOTIA32.efi 文件夾,

將其和x86_64-efi、locale文件夾、unicode.pf2一起拷貝到第一個fat/fat32分區,並新建一個grub.cfg。

其中,x86_64-efi為模塊目錄,locale為地區語言,unicode.pf2為字體,grub.cfg為引導載入的配置文件

目錄如下:

FAT/FAT32
#########################
/EFI/Boot/bootx64.efi
/EFI/Boot/BOOTIA32.efi
/EFI/grub/grub.cfg
/EFI/grub/unicode.pf2
/EFI/grub/x86_64-efi/
/EFI/grub/locale/

#####################

x64.cfg內容示例:

[plain] view plain
function load_video {
if [ x$feature_all_video_mole = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}

insmod part_gpt
insmod fat
set root='hd0,gpt1'

font="/EFI/grub/unicode.pf2"
if loadfont prefix/locale
set lang=zh_CN
insmod gettext
fi

terminal_output gfxterm

insmod jpeg
if background_image /EFI/grub/background.jpg; then
true
else
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
if background_color 255,255,155,0; then
clear
fi
fi

set default=0

set timeout_style=menu
set timeout=5

menuentry "啟動 delta win7" --class windows --class os {
insmod ntfs
set root='(hd0,gpt2)'

}

menuentry "local win7" --class windows --class os {
insmod ntfs
set root='(hd0,gpt3)'

}

menuentry "ubuntu16.04 x86" --class ubuntu --class os {
insmod ext2
set root='(hd0,gpt5)'
linux /vmlinuz ro root=/dev/sda5
initrd /initrd.img
echo "Start Ubuntu 16.04"
}

menuentry "ubuntu16.04 x64" --class ubuntu --class os {
insmod ext2
set root='(hd0,gpt6)'
linux /vmlinuz ro root=/dev/sda6
initrd /initrd.img
echo "Start Ubuntu 16.04"
}

menuentry "-------------------" --class ubuntu --class os{
set root=(hd0,gpt1)
}

menuentry "ubuntu-efi" --class ubuntu --class os {
insmod ext2
set root='(hd0,gpt5)'
chainloader /efi/grub.efi
}

menuentry "install ubuntu" --class ubuntu --class os {
insmod ext2
insmod loopback
set root=(hd0,gpt4)
set isofile=/OS/linux/ubuntu-16.04.2-desktop-amd64.iso
loopback loop isofile
initrd (loop)/casper/initrd.lz
}

menuentry "-------------------" --class ubuntu --class os{
set root=(hd0,gpt1)
}

menuentry "reboot" --class windows --class os{
insmod reboot
reboot
}

menuentry "halt" --class windows --class os{
insmod halt
halt
}

https://wiki.archlinux.org/index.php/GRUB_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
https://help.ubuntu.com/community/UEFIBooting

http://ftp.gnu.org/gnu/grub/
http://ftp.gnu.org/gnu/grub/grub-2.02-for-windows.zip

https://www.gnu.org/software/grub/manual/grub.html

http://jingyan..com/article/c85b7a640cd7d6003bac95f8.html

https://packages.ubuntu.com/source/trusty/grub2

https://www.kernel.org/pub/linux/utils/boot/syslinux/

http://www.jinbuguo.com/linux/grub.cfg.html
http://blog.csdn.net/listener_ri/article/details/45621947

http://bbs.wuyou.net/forum.php?mod=viewthread&tid=385353

在進入grub界面如果出現

問題出在引導配置文件沒有找到.
那麼如何調試呢?
可以嘗試列印變數的方法,輸入C進入命令模式
輸入gettext $prefix
我們發現還是提示(hd0,gp1)/EFI/grub
說明目錄並沒有被更改,我們可以驗證一下放到此目錄在跑起來.
發現果然又可以了,後面原因就是便宜目錄的compile.cfg裡面的目錄並沒有修改到根目錄。

打開cfg文件查看是不是配置了語言文件,但是目錄不存在

如果依然亂碼,修改文件編碼為utf-8

在④步驟中,已經生成BIOS模式所需的內核文件Core.img,其大小是86.5 KB
生成的只是單單BIOS模式的內核文件,還無法引導Grub2,還需要個啟動文件Boot.img,該文件很小,只有512Byte,位於i386-pc文件夾,該文件的作用是啟動Grub2,然後載入內核文件Core.img
所以這里的最後壹步就是把啟動文件Boot.img和內核文件Core.img以二進制形式合並,合並後的文件我個人稱呼為扇區文件G2ldr(不知道這個文件有沒標準的名稱),因為可以直接導入到扇區,來引導啟動Grub2,也可以由GRUB4DOS直接載入這個扇區文件來啟動Grub2。
老樣子,先給出命令(如果命令行的路徑不是Grub2包所在的路徑,就先要修改命令行的路徑,前面有提到)
Copy /B i386-pc\Boot.img+Core.img G2ldr

用bootice 導入扇區
恢復扇區數改成63不能大於63的
之所以會超過是定製問題, 那麼這個不會

學習uefi和bios所使用的啟動器模擬
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=335197

具體教程來自 http://bbs.wuyou.net/forum.php?mod=viewthread&tid=339411&extra=page%3D1

: qq5274202

我的cmd批處理定製

那麼bios載入方式如何啟動呢。

出現這個錯誤,說明文件系統是不支持引導此分區,可以一個一個測試
輸入 ls
出現了(hd0) (hd0,msdos2) (hd0,msdos1)
(hd1)
出現了msdos的都可以引導bios,
嘗試輸入了ls (hd0,msdos2)顯示的是存儲盤的內容,
嘗試輸入(hd0,msdos1)顯示的是uefi分區內容.

而輸入 其他的都顯示未知的系統,也驗證了bios只識別mbr分區表.

於是我把grub移動到了uefi分區 也就是(hd0,msdos1) 然後輸入如下內容
後依次輸入如下內容:

成功載入菜單.

5. 如何編譯第一個uefi程序

1,按EDK推薦,相應的子模塊放到相應的文件夾中,所以新建文件夾hello,裡面放入hello.c和hello.inf,結構如下:
「C:\MyWorkSpace\MdeMolePkg\Application\hello\hello.c」
「C:\MyWorkSpace\MdeMolePkg\Application\hello\hello.inf」
2,記事本打開」C:\MyWorkSpace\Nt32Pkg\Nt32Pkg.dsc」,在 [Components] 下,加入一句:
MdeMolePkg/Application/hello/hello.inf
//相當於Visual_studio在sln中加入一個proj.
3,hello.c的代碼如下:
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>

EFI_STATUS
EFIAPI
UefiMain
(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
{
SystemTable->ConOut->OutputStri

閱讀全文

與UEFI程序運行時如何編譯相關的資料

熱點內容
excel怎麼生成每月每周數據 瀏覽:467
建築技術工程專業怎麼樣 瀏覽:89
獲取數據中心授權在哪裡 瀏覽:116
u盤數據加密有哪些 瀏覽:454
專利申請的技術背景指什麼 瀏覽:536
學信息工程可以做什麼工作 瀏覽:342
佳音乾燥盒a程序b程序有什麼用 瀏覽:951
tableau如何修改數據 瀏覽:557
小程序怎麼開發聯盟 瀏覽:703
蘭州市服裝市場在哪裡 瀏覽:563
什麼樣的活才算技術活 瀏覽:545
三板市場生意怎麼樣 瀏覽:384
猶太人的技術是哪裡來的 瀏覽:823
如何和外資交易 瀏覽:291
vivo手機如何導入舊手機的數據 瀏覽:66
手機開機程序如何升級 瀏覽:883
父子二手車過戶交易發票怎麼開 瀏覽:252
南昌傢具批發市場什麼時候開門 瀏覽:54
如何選取數據中的和為一定數 瀏覽:758
在交易貓買號被賣家找回怎麼辦 瀏覽:236