這裏顯示兩個版本的差異處。
| Both sides previous revision 前次修改 下次修改 | 前次修改 | ||
|
uefi_learning [2024/04/07 11:23] don |
uefi_learning [2025/02/06 11:42] (目前版本) don |
||
|---|---|---|---|
| 行 1: | 行 1: | ||
| ====== UEFI 學習 ====== | ====== UEFI 學習 ====== | ||
| + | |||
| + | [[https:// | ||
| + | |||
| {{: | {{: | ||
| 行 15: | 行 18: | ||
| |[Defines]| 定義本模塊的屬性變量及其他變量,這些變量可在工程文件其他塊中引用| | |[Defines]| 定義本模塊的屬性變量及其他變量,這些變量可在工程文件其他塊中引用| | ||
| |[Sources]| 列出本模塊的所有源文件及資源文件| | |[Sources]| 列出本模塊的所有源文件及資源文件| | ||
| - | |[Packages]| 列出本模塊引用到的所有包的包聲明文件。可能引用到的資源包括投文件、GUID、Protocol等,這些資源都聲明再包的包聲明文件.dec中| | + | |[Packages]| 列出本模塊引用到的所有包的包聲明文件。可能引用到的資源包括投文件、GUID、Protocol等,這些資源都聲明在包的包聲明文件.dec中| |
| |[LibraryClasses]| 列出本模塊要練接的庫模塊| | |[LibraryClasses]| 列出本模塊要練接的庫模塊| | ||
| 行 27: | 行 30: | ||
| |[FeaturePcd]| 用於列出本模塊用到的Pcd 常量| | |[FeaturePcd]| 用於列出本模塊用到的Pcd 常量| | ||
| |[PatchPcd]| 列出的Pcd 變量僅本模塊可用| | |[PatchPcd]| 列出的Pcd 變量僅本模塊可用| | ||
| + | |||
| + | [[http:// | ||
| 1、[Defines]塊: | 1、[Defines]塊: | ||
| 行 64: | 行 69: | ||
| 3、[Packages]塊: | 3、[Packages]塊: | ||
| 此塊下面列出了模組所引用到的所有包的聲明檔dec檔。如果在Sources塊內列出了原始檔案,在此塊下必須列出MdePkg/ | 此塊下面列出了模組所引用到的所有包的聲明檔dec檔。如果在Sources塊內列出了原始檔案,在此塊下必須列出MdePkg/ | ||
| - | |||
| 4、[LibraryClasses]塊: | 4、[LibraryClasses]塊: | ||
| 此塊內列出了模組所要連結的所有庫模組(使用了庫的庫函數就要列出來)。庫定義在包的dsc檔中 | 此塊內列出了模組所要連結的所有庫模組(使用了庫的庫函數就要列出來)。庫定義在包的dsc檔中 | ||
| + | 5、[BuildOptions]塊:\\ | ||
| + | 5-1、語法: | ||
| + | | ||
| + | | ||
| - | 5、[BuildOptions]塊: | + | 5-2、編譯器家族 |
| - | 1、語法: | + | 可以是MSFT(Visual Studio編譯器家族)、INTEL(Intel編譯器家族)、GCC(Gcc編譯器家族) |
| - | [BuildOptions] | + | 和 RVCT(ARM編譯器家族)中的一個 |
| - | [編譯器家族] : [$ (Target)][Tool_CHAIN_TAG][$ (Arch)]_[CC | DLINK]_FLAGS [= |==]選項 | + | Target是DEBUG、RELEASE和*中的一個,*是萬用字元 |
| + | | ||
| + | Arch是體系結構,可以是IA32、X64、IPF、EBC或ARM,*是萬用字元 | ||
| + | CC表示編譯選項, | ||
| + | DLINK表示連結選項 | ||
| + | =表示選項附加到預設選項後面, | ||
| + | ==表示僅使用所定義的選項,不用預設選項。它們後面是編譯選項或連接選項 | ||
| - | 2、編譯器家族可以是MSFT(Visual Studio編譯器家族)、INTEL(Intel編譯器家族)、GCC(Gcc編譯器家族)和 RVCT(ARM編譯器家族)中的一個 | ||
| - | Target是DEBUG、RELEASE和*中的一個,*是萬用字元 | + | ==== inf檔編譯運行 ==== |
| - | TOOL_CHAIN_TAG是編譯器的名字,編譯器定義在Conf/ | + | 原始檔案,inf工程檔完成,想要編譯運行這個模組,需要將inf工程檔添加到dsc的[Components]部分,然後就可以使用build工具編譯\\ |
| + | 模組應用程式是如何被編譯成.efi文件的:\\ | ||
| + | 1、.c源碼檔先被編譯成目的檔案.obj\\ | ||
| + | 2、連接器將目的檔案*.obj和其他的庫連接成*.dll\\ | ||
| + | 3、GenFw工具將*.dll轉化成*.efi\\ | ||
| + | 這些過程都由build命令自動完成\\ | ||
| - | Arch是體系結構,可以是IA32、X64、IPF、EBC或ARM,*是萬用字元 | + | 標準應用程式載入過程(efi檔載入)\\ |
| + | 1、將efi檔載入到記憶體\\ | ||
| + | efi模組檔————gBS -> | ||
| - | CC表示編譯選項,DLINK表示連結選項 | + | * gBS 指向啟動服務表 global Boot Servers\\ |
| + | * gST 指向系統表 global System Table\\ | ||
| + | * gRT 指向運行時服務表 global Running Time\\ | ||
| + | * gImageHandle 指向正在執行的驅動或應用程式\\ | ||
| + | |||
| + | < | ||
| + | EFI_STATUS | ||
| + | LoadDriver( | ||
| + | IN CONST CHAR16 | ||
| + | IN CONST BOOLEAN | ||
| + | ) | ||
| + | { | ||
| + | EFI_HANDLE | ||
| + | EFI_STATUS | ||
| + | EFI_DEVICE_PATH_PROTOCOL | ||
| + | EFI_LOADED_IMAGE_PROTOCOL | ||
| + | |||
| + | LoadedDriverImage | ||
| + | FilePath | ||
| + | LoadedDriverHandle | ||
| + | Status | ||
| + | |||
| + | ************************************* | ||
| + | |||
| + | // | ||
| + | // Use LoadImage to get it into memory | ||
| + | // | ||
| + | Status = gBS-> | ||
| + | FALSE, | ||
| + | gImageHandle, | ||
| + | FilePath, | ||
| + | NULL, | ||
| + | 0, | ||
| + | & | ||
| + | |||
| + | ********************************************** | ||
| + | |||
| + | // | ||
| + | // Make sure it is a driver image | ||
| + | // | ||
| + | Status = gBS-> | ||
| + | |||
| + | | ||
| + | /* | ||
| + | * 找出可执行的程序镜像Image的入口函数并执行找到的入口函数, gBS-> | ||
| + | */ | ||
| + | Status = gBS-> | ||
| + | if (EFI_ERROR(Status)) { | ||
| + | ShellPrintHiiEx(-1, | ||
| + | } else { | ||
| + | ShellPrintHiiEx(-1, | ||
| + | } | ||
| + | } | ||
| + | ********************************************************** | ||
| + | return (Status); | ||
| + | } | ||
| + | </ | ||
| - | =表示選項附加到預設選項後面,==表示僅使用所定義的選項,不用預設選項。它們後面是編譯選項或連接選項 | + | 2、進入鏡像image的入口函數 |
| + | CoreStartImage的主要作用是調用鏡像的入口函數,在這裡面SetIump/ | ||
| < | < | ||
| - | [BuildOptions] | + | EFI_STATUS |
| - | | + | EFIAPI |
| - | *_*_*_CC_FLAGS = -DHAVE_STDARG_H | + | CoreStartImage ( |
| + | | ||
| + | | ||
| + | OUT CHAR16 | ||
| + | ) | ||
| + | { | ||
| + | EFI_STATUS | ||
| + | LOADED_IMAGE_PRIVATE_DATA | ||
| + | LOADED_IMAGE_PRIVATE_DATA | ||
| + | UINT64 | ||
| + | UINTN | ||
| + | EFI_HANDLE | ||
| - | # Override MSFT build option to remove | + | ************************************************************** |
| - | | + | |
| - | | + | // Set long jump for Exit() support |
| + | // JumpContext must be aligned on a CPU specific boundary. | ||
| + | // Overallocate the buffer and force the required alignment | ||
| + | // | ||
| + | Image-> | ||
| + | | ||
| + | | ||
| + | // Image may be unloaded after return with failure, | ||
| + | // then ImageHandle may be invalid, so use NULL handle to record perf log. | ||
| + | // | ||
| + | PERF_START_IMAGE_END (NULL); | ||
| - | # Oniguruma: potentially uninitialized local variable used | + | // |
| - | | + | // Pop the current start image context |
| + | // | ||
| + | mCurrentImage = LastImage; | ||
| - | # Oniguruma: intrinsic function not declared | + | return EFI_OUT_OF_RESOURCES; |
| - | | + | |
| + | Image-> | ||
| - | | + | |
| - | | + | // |
| + | // The initial call to SetJump() must always return 0. | ||
| + | | ||
| + | // | ||
| + | if (SetJumpFlag | ||
| + | RegisterMemoryProfileImage (Image, (Image-> | ||
| + | | ||
| + | // Call the image' | ||
| + | // | ||
| + | Image-> | ||
| + | Image-> | ||
| - | # Oniguruma: 'type cast' : truncation from ' | + | ****************************************************************** |
| - | MSFT:*_*_*_CC_FLAGS = /wd4305 /wd4306 | + | |
| - | | + | |
| - | | + | // UEFI Specification - StartImage() - EFI 1.10 Extension |
| + | // To maintain compatibility with UEFI drivers that are written to the EFI | ||
| + | // 1.02 Specification, | ||
| + | // and after each image is started. If any handles are created or modified | ||
| + | // when an image is started, then EFI_BOOT_SERVICES.ConnectController() must | ||
| + | // be called with the Recursive parameter set to TRUE for each of the newly | ||
| + | // created or modified handles before StartImage() returns. | ||
| + | // | ||
| - | # Oniguruma: 'type cast' : " | + | ********************************************************************** |
| - | MSFT:*_*_*_CC_FLAGS = /wd4244 /wd4054 | + | |
| - | | + | |
| - | | + | // Save the Status because Image will get destroyed if it is unloaded. |
| + | // | ||
| + | Status = Image-> | ||
| - | # Oniguruma: signed and unsigned mismatch/ | + | ************************************************************************** |
| - | MSFT:*_*_*_CC_FLAGS = /wd4018 | + | |
| + | | ||
| + | // | ||
| + | PERF_START_IMAGE_END (Handle); | ||
| + | return Status; | ||
| + | } | ||
| - | # Oniguruma: tag_end in parse_callout_of_name | + | _ModuleEntryPoint函数: |
| - | GCC: | + | |
| - | # Oniguruma: implicit conversion from ' | + | EFI_STATUS |
| - | | + | EFIAPI |
| + | _ModuleEntryPoint | ||
| + | | ||
| + | IN CONST EFI_PEI_SERVICES | ||
| + | ) | ||
| + | { | ||
| + | if (_gPeimRevision != 0) { | ||
| + | // | ||
| + | // Make sure that the PEI spec revision of the platform is >= PEI spec revision of the driver | ||
| + | // | ||
| + | ASSERT ((*PeiServices)-> | ||
| + | } | ||
| - | | + | |
| - | | + | // Call constructor |
| - | | + | |
| + | | ||
| + | // | ||
| + | // Call the driver entry point | ||
| + | // | ||
| + | return ProcessModuleEntryPointList (FileHandle, | ||
| + | } | ||
| </ | </ | ||
| + | 3、進入模組的入口函數 | ||
| + | 在_ModuleEntryPoint中,調用了ProcessModuleEntryPointList ,然後在build過程中,會解析inf檔,生成AutoGen.c檔,裡面查看ProcessModuleEntryPointList ,它調用了應用程式工程模組的真正入口函數,就是inf檔中指定的那個入口函數 | ||
| + | < | ||
| + | EFI_STATUS | ||
| + | EFIAPI | ||
| + | ProcessModuleEntryPointList ( | ||
| + | IN | ||
| + | IN CONST EFI_PEI_SERVICES | ||
| + | ) | ||
| + | |||
| + | { | ||
| + | return PcdPeimInit (FileHandle, | ||
| + | } | ||
| + | </ | ||
| + | 標準應用程式工程模組入口函式呼叫過程:\\ | ||
| + | efi——LoadImage——StartImage——_ModuleEntryPoint——ProcessModuleEntryPointList ——inf中指定的入口函数\\ | ||
| + | 原文連結:https:// | ||
| + | |||
| + | |||
| + | ===== DSC 文件 ===== | ||
| + | .inf 用于编译一个模块, 而.dsc 文件用于编译一个Package, 它包含了[Defines]、 | ||
| + | [LibraryClasses]、[Components] 几个必需部分以及[PCD]、[BuildOptions] 等几个可选部分。 | ||
| + | |||
| + | |||
| + | ===== DEC 文件 ===== | ||
| + | .dec 文件定义了公开的数据和接口,供其他模块使用。它包含了必需区块[Defines] 以及可选区块[Includes]、[LibraryClasses]、[Guids]、[Protocols]、[Ppis] 和[PCD] 几个部分。 | ||
| + | .dec文件需要被调用模块.inf文件所包含。 | ||
| 行 187: | 行 353: | ||
| |FatPkg, FatBinPkg|FAT支持包。| \\ | |FatPkg, FatBinPkg|FAT支持包。| \\ | ||
| 原文連結:https:// | 原文連結:https:// | ||
| + | |||
| + | |||
| + | ===== Build 參數 ===== | ||
| + | |||
| + | ^ 命令參數縮寫 ^ 命令參數全稱 ^ 描述 ^ | ||
| + | |-h |--help |show this help message and exit顯示説明資訊。| | ||
| + | |-a TARGETARCH |--arch=TARGETARCH|選擇目標平臺架構,該選項被指定會取代Conf/ | ||
| + | |-p PLATFORMFILE |--platform=PLATFORMFILE|通過指定.dsc檔指定要編譯的package,該選項將會Conf/ | ||
| + | |-m MODULEFILE| --module=MODULEFILE|Build the module specified by the INF file name argument。| | ||
| + | |-b BUILDTARGET| --buildtarget=BUILDTARGET |選擇編譯成DEBUG還是RELEASE。指定該選項後會取代target.txt文件中TARGET。| | ||
| + | |-t TOOLCHAIN| --tagname=TOOLCHAIN|選擇tools_def.txt中定義的編譯工具,例如VS2012:-t vs2012| | ||
| + | |-n THREADNUMBER| |編譯器使用的執行緒數量,指定後取代target.txt檔中MAX_CONCURRENT_THREAD_NUMBER指定的執行緒數量。 Less than 2 will disable multi-thread builds.小於2就禁止多執行緒編譯。| | ||
| + | |-u| --skip-autogen | Skip AutoGen step.跳過AutoGen這一步。| | ||
| + | |-c| --case-insensitive | Don't check case of file name.檔案名不區分大小寫。| | ||
| + | |-w| --warning-as-error | Treat warning in tools as error.將警告做錯誤處理。| | ||
| + | |-j LOGFILE| --log=LOGFILE| Put log in specified file as well as on console.將編譯資訊輸出到檔。| | ||
| + | |-s| --silent| Make use of silent mode of (n)make.使用沉默模式執行make或nmake。| | ||
| + | |-q| --quiet| Disable all messages except FATAL ERRORS.編譯過程中只顯示嚴重錯誤資訊。| | ||
| + | |-d DEBUG| --debug=DEBUG| Enable debug messages at specified level.在指定的級別啟用調試消息。| | ||
| + | |-D MACROS| --define=MACROS| Macro: "Name [= Value]" | ||
| + | | | ---version| show program' | ||
| + | |||
| ===== UEFI API ===== | ===== UEFI API ===== | ||
| 行 197: | 行 385: | ||
| ==== PcdGetPtr() ==== | ==== PcdGetPtr() ==== | ||
| PcdGetPtr(PcdHelloWorldPrintString) 讀取在PcdHelloWorldPrintString 的字串。 | PcdGetPtr(PcdHelloWorldPrintString) 讀取在PcdHelloWorldPrintString 的字串。 | ||
| + | |||
| + | ==== AMI VEB ==== | ||
| + | AMI VEB 基本上就是一堆 .CIF 檔案的集合 | ||
| + | |||
| + | |||