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和編譯選項等也是可以覆蓋的。
相關文章
- UEFI BIOS Rootkit AnalysisiOS
- UEFI BIOS模式下Windows系統啟動過程以及引導檔案修復方法iOS模式Windows
- UEFI是高階的BIOS嘛?什麼是GPT,什麼是UEFI?iOSGPT
- BIOS、UEFI、Boot Loader都是些什麼iOSboot
- 取代BIOS:Vista Beta 2預覽UEFIiOS
- Linux基礎學習——檔案基礎Linux
- 華碩uefi bios中怎麼設定隨身碟啟動?華碩uefi bios設定u盤啟動方法步驟iOS
- PHP基礎---檔案包含PHP
- Oracle控制檔案基礎Oracle
- Unity基礎——.meta檔案Unity
- 檔案系統基礎
- 檔案管理基礎命令一
- python 基礎之檔案Python
- Python基礎——檔案操作Python
- Spark基礎-Scala檔案操作Spark
- Oracle引數檔案基礎Oracle
- 【Java基礎】--上傳檔案Java
- C++基礎::檔案流C++
- 檔案IO中基礎操作
- 最新Linux系統將用UEFI替代傳統 BIOSLinuxiOS
- 29-檔案物件基礎操作物件
- 檔案管理基礎命令之二
- mysql基礎概念之socket檔案MySql
- Oracle重做日誌檔案基礎Oracle
- Oracle基礎 09 概要檔案 profileOracle
- Python基礎 - 檔案拷貝Python
- linux檔案系統基礎Linux
- Python基礎 - 檔案和流Python
- Linux基礎之檔案管理Linux
- Linux系統檔案系統及檔案基礎篇Linux
- Linux基礎命令---lp列印檔案Linux
- Linux基礎命令---lpr列印檔案Linux
- iOS逆向之旅(基礎篇) — Macho檔案iOSMac
- c#(解析xml檔案基礎方法)C#XML
- Linux基礎:檔案查詢findLinux
- linux檔案系統基礎(轉)Linux
- 【0基礎學爬蟲】爬蟲基礎之檔案儲存爬蟲
- shell基礎教程二十四: shell基礎教程: Shell檔案包含