BIOS/UEFI基礎——DSC檔案
綜述
DSC的全稱就是EDK Platform Description。dsc包含了模組,變數定義,庫函式,PCD等內容,此外還包含編譯選項,它的目的就是指定需要編譯的內容,以及編譯的引數。
本文參考《edk-ii-dsc-specification.pdf》(以下簡稱參考文件)。它可以在https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Specifications下載到。本文中使用到的程式碼示例來自https://gitee.com/jiangwei0512/vUDK2018.git。
語法
本節介紹dsc檔案的大致語法。
基本語法
先簡單介紹一些fdf檔案中使用到的基本語法:
1. 註釋使用#;
2. 使用=設定常量,使用DEFINE設定巨集,但是DEFINE語句中還是有=;
3. 可以使用整型,布林值,EFI_GUID等值;
4. $()獲取DEFINE語句定義的巨集的值;
基本語句
DEFINE語句,定義一個巨集:
DEFINE SECURE_BOOT_ENABLE = FALSE
定義的巨集可以通過$()來訪問,下面是一個例子:
!if $(SECURE_BOOT_ENABLE) == TRUE
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
!else
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
注意這裡定義的巨集也可以在fdf檔案中使用。
!if語句:判斷語句,為TRUE時才包含其內部的元件,其語法如下:
!if $(MACRO) 或者 !if $(MACRO) == "Literal String" 或者 !if $(MACROALPHA) == $(MACROBETA) 或者 !if $(MACRONUM) == 數字 或者 !if $(MACROBOOL) == 布林值或者!if 布林值。
注意需要與!endif語句一起使用,中間也可以有!else語句,上面已經有例子說明。其它類似的還有!ifdef語句和!ifndef語句。
Section
Section的大致格式如下:[oo.xx.zz]。這裡oo是必選的,而xx、zz等需要根據oo的值來確定是否存在以及具體是什麼內容。下面就介紹這些常用的Section關鍵字。
[Defines]
定義在這裡的巨集或者常量在dsc檔案和fdf檔案都是有效的,且有些值是需要傳遞給編譯和生成工具的,因此這個Section是dsc中必須的。下面是一個例子:
[Defines]
PLATFORM_NAME = LearnUefi
PLATFORM_GUID = 5a9e7754-d81b-49ea-85ad-69eaa7b1539b
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/LearnUefiPkg
SUPPORTED_ARCHITECTURES = X64
BUILD_TARGETS = NOOPT|DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = LearnUefiPkg/LearnUefiPkg.fdf
#
# Defines for default states. These can be changed on the command line.
# -D FLAG=VALUE
#
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE NETWORK_IP6_ENABLE = FALSE
DEFINE HTTP_BOOT_ENABLE = FALSE
DEFINE SMM_REQUIRE = FALSE
其中有一些值比較重要,在這裡說明:OUTPUT_DIRECTORY定義了編譯生成的檔案的輸出目錄,FLASH_DEFINITION定義了對應的fdf檔案。
[BuildOptions]
這個Section用來指定編譯選項。EDK可以在Windows、Linux和Mac上編譯,所以這裡的巨集也可以指定不同的系統,且EDK包含很多的語言,所以也可以指定。此外,比較特別的一點是,BIOS包含的模組有不同的型別,不同型別會對應不同的體系架構,比如PEIM需要的是32位的編譯,DXE之後需要64位的編譯,等等。所以這個Section還有一些變種:
[BuildOptions]
[BuildOptions.common]
[BuildOptions.$(ARCH)]
[BuildOptions.common.CodeBase]
[BuildOptions.$(ARCH).CodeBase]
[BuildOptions.$(ARCH).CodeBase.$(MODULE_TYPE)]
這裡其實是一個從通用到特定型別的範圍縮小的過程,後者可以覆蓋前者的定義。ARCH的值可以是X86、IA32等值。CodeBase對於我們想在的程式碼就是EDKII;MODULE_TYPE對應到的型別如下:
下面是一個例子:
[BuildOptions]
GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG
GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
#
# Disable deprecated APIs.
#
MSFT:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
INTEL:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
XCODE:*_*_*_DLINK_FLAGS =
這裡的[BuildOptions]相當於一個通用的配置,而之後的[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]是對一些特性的覆蓋。
關於[BuildOptions]中的語句,格式如下:編譯器:編譯選項名=編譯選項。其它的兩個部分沒有什麼好多說的,重點是中間的編譯選項名,它的一個例子:
RELEASE_UNIXGCC_IA32_CC_FLAGS
這裡第一個值表示是Release還是Debug版本;第二個值是具體的編譯工具,它在tools_def中的Supported Tool Chains中說明;第三個引數是架構型別;第四個是表示用於編譯過程還是連結過程。
[SkuIds]
這個Section是可選的,實際上用處不大,這裡不做說明。
[LibraryClasses]
這個Section定義了所以使用到的庫函式。由於庫可以使用在不同的階段和架構,所以它也分為不同的子類,如下所示:
[LibraryClasses]
[LibraryClasses.common]
[LibraryClasses.$(ARCH)]
[LibraryClasses.common.$(MODULE_TYPE)]
[LibraryClasses.$(ARCH).$(MODULE_TYPE) ]
同樣,這裡也是越精細的範圍覆蓋越通用的範圍。下面是一個例子:
[LibraryClasses]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
關於[LibraryClasses] 中的語句,格式如下:庫名稱|庫路徑。庫名稱跟對應在inf中的一樣,路徑從程式碼根目錄開始。
[PcdsXXX]
PCD的Section有不同的種類,對應不同的PCD型別,如下所示:
[PcdsFeatureFlag]
[PcdsFixedAtBuild]
[PcdsDynamicDefault]
[PcdsPatchableInModule]
實際上PCD是在dec檔案中定義和初始化的,在dsc檔案中實際上是重新賦值,如果沒有這麼做,那該PCD就使用dec中的預設值。下面是一個例子:
[PcdsFeatureFlag]
gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE
關於PCD這類Section中的語句,格式如下:GUID名.PCD名|PCD值。
[Components]
該Section中包含所以需要編譯的模組,同樣由於模組的不同,這裡也會對應不同的變種:
[Components]
[Components.common]
[Components.$(ARCH)]
這裡的ARCH可以有IA32、X64、ARM等值。下面是一個例子:
[Components]
OvmfPkg/ResetVector/ResetVector.inf
#
# SEC Phase modules
#
OvmfPkg/Sec/SecMain.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
}
這裡的語句可以直接是一個路徑,還可以在路徑之後加上對庫的覆蓋,當然不止是庫的覆蓋,PCD和編譯選項等也是可以覆蓋的。
相關文章
- BIOS、UEFI、Boot Loader都是些什麼iOSboot
- Linux基礎學習——檔案基礎Linux
- python 基礎之檔案Python
- Python基礎——檔案操作Python
- PHP基礎---檔案包含PHP
- 檔案系統基礎
- Unity基礎——.meta檔案Unity
- 最新Linux系統將用UEFI替代傳統 BIOSLinuxiOS
- 華碩uefi bios中怎麼設定隨身碟啟動?華碩uefi bios設定u盤啟動方法步驟iOS
- Linux基礎之檔案管理Linux
- 檔案IO中基礎操作
- 檔案管理基礎命令一
- Linux系統檔案系統及檔案基礎篇Linux
- Linux基礎命令---lp列印檔案Linux
- Linux基礎命令---lpr列印檔案Linux
- 29-檔案物件基礎操作物件
- [基礎知識] Redis 配置檔案Redis
- 檔案管理基礎命令之二
- LinuxDay01 檔案&程式基礎Linux
- iOS逆向之旅(基礎篇) — Macho檔案iOSMac
- c#(解析xml檔案基礎方法)C#XML
- python 檔案操作的基礎總結Python
- Linux 基礎-檔案及目錄管理Linux
- 【0基礎學爬蟲】爬蟲基礎之檔案儲存爬蟲
- shell基礎教程二十四: shell基礎教程: Shell檔案包含
- 如何檢查你的計算機使用的是 UEFI 還是 BIOS計算機iOS
- 零基礎學習 Python 之檔案Python
- Linux基礎命令---驗證組檔案grpckLinuxRPC
- Linux 基礎教程 38-檔案下載Linux
- 【C++基礎】檔案流讀寫操作C++
- Jumpserver基礎運維-02檔案傳輸Server運維
- Linux基礎命令---htpasswd建立密碼檔案Linux密碼
- Linux基礎命令---mget獲取ftp檔案LinuxFTP
- Linux基礎命令---get獲取ftp檔案LinuxFTP
- Linux基礎命令---mput上傳ftp檔案LinuxFTP
- Linux基礎之瀏覽和建立檔案Linux
- Python基礎入門(9)- Python檔案操作Python
- FastAPI基礎之 表單和檔案操作ASTAPI