---
# System prepended metadata

title: Unified Extensible Firmware Interface (UEFI) - AHCI
tags: [UEFI]

---

# Unified Extensible Firmware Interface (UEFI) - AHCI

Slide: https://hackmd.io/@QSquirrel/Syl7PhKZF

---
> 本篇記錄編譯 UDK2018 的相關筆記
> [name=Nick Xiao] [time=February 2021] [color=#907bf7]
>  
> Email: s9926004@gmail.com

{%hackmd ryr9Ug6sd %}

---
## 前言
基於公司需求, 修改 UEFI AHCI 及 SATA 相關的部分, 本篇將做紀錄

## Introduction BIOS and UEFI
### 新的主機板只支援UEFI?
- Last Mile  Barriers to Removing Legacy BIOS - Brian Richardson (Intel Corporation)
http://www.uefi.org/sites/default/files/resources/Brian_Richardson_Intel_Final.pdf
- Intel發表UEFI Class 3，將於2020年停止傳統BIOS支援
http://www.pcdiy.com.tw/detail/8121
- Intel 宣布 2020 年完全封閉 UEFI 相容傳統 BIOS 模式
https://technews.tw/2017/11/22/intel-schrapt-bios-compatibiliteit-uefi-in-2020/
    
    ![](https://i.imgur.com/cmYHvjV.png)
    
    ![](https://i.imgur.com/GOrvyx7.png =440x)

### UEFI? BIOS? Legacy?
- UEFI 視為改良後的BIOS, 他們並不相等也不會共有
- 為了使得UEFI 能夠支援舊版, 因此有了CSM 模式(如下圖)

    ![](https://i.imgur.com/riDUnTb.png)

-- 更多說明請參考: UEFI? BIOS? Legacy? 淺談主機板UEFI觀念與迷思([Link](https://forum.gamer.com.tw/Co.php?bsn=60030&sn=2144508))

### 何謂 UEFI? EFI?

UEFI的前身是Intel在1998年開始開發的Intel Boot Initiative，後來被重新命名為可延伸韌體介面（Extensible Firmware Interface，縮寫EFI）。Intel在2005年將其交由統一可延伸韌體介面論壇（Unified EFI Forum）來推廣與發展，為了凸顯這一點，EFI也更名為UEFI（Unified EFI）。

- UEFI 會提供 Boot Services (BS) 以及 Runtime Service (RT) 給 OS Loader 使用.
    - OS Loader : 藉由 BS 取得系統資源, 直到呼叫 ExitBootServices 後釋放 BS 相關記憶體, 而這個過程將稱為 Transient System Load (TSL), 之後OS會進入RT的階段
    - Boot Services : 提供事件服務、記憶體管理、Protocol管理、Protocol使用服務類、驅動管理、Image管理、ExitBootServices
    - Runtime service:  時間服務、讀寫UEFI系統變量等其他服務

- UEFI allows the extension of platform firmware by loading UEFI driver and UEFI application images. When UEFI drivers and UEFI applications are loaded they have access to all UEFI-defined runtime and boot services.

- 由下圖說明 EFI Boot manager 以及 EFI drivers 的溝通方式

    ![](https://i.imgur.com/u8IDs1n.png)
    
- 基於UEFI系統的電腦, 從上電到關機會有7個階段:
	- SEC(Security Phase) 安全驗證
	- PEI(pre-EFI Initialization) EFI前期初始化
	- DXE(Driver Execution Environment) 驅動執行環境
	- BDS(Boot Device Selection) 啟動設備選擇
	- TSL(Transient System Load) 操作系統加載前期
	- RT (Runtime)運作時間
	- AL (After Life)災難恢復      
	
    ![](https://i.imgur.com/YbScn0W.png)

### BIOS VS UEFI 

- BIOS(Basic Input / Output System)
    - 開發效率 : 大部分BIOS使用組語開發, 容易受到硬體變化影響.
    - 效能 : BIOS 執行基本輸入及輸出都是依靠中斷的方式, 並不支援異步工作模式(multi-thread), 需要耗費等待時間.
    - 功能擴充與升級 : BIOS 使用靜態連結, 並未提供動態加載的服務. 當需要增加硬體功能時, 必須要將 16 bit 的程式碼放在 0xc0000~0x0dffff 區間, 並在初始化時將其設置中斷處理程序.
    - 安全性 : BIOS執行程式碼時, 並不會對程式碼有安全性的考量
    - 不支援從硬碟2TB以上的位址引用: 受限於BIOS硬碟的尋址方式, BIOS 採用 32 bit, therefore, the maximum of LAB address =  2^32 * 512(byte) = 2TB
    
- UEFI(Unified Extensible Firmware Interface)
    - 開發效率 : 使用C語言開發, 而 UEFI application 以及 UEFI driver 可以使用 C++ 編寫, 開發門檻相對簡易. 有關硬體相關問題則是由 BS 及 RT 服務作為 Interface, 上層可以有效的重複使用.
    - 效能  : 捨棄中斷機制, 支援事件處理以及異步操作.
    - 功能擴充與升級 : 硬體的初始化透過UEFI driver, 並且能從韌體或是裝置上動態加載.
    - 安全性 : 當系統開啟"安全啟動"的功能時, UEFI 執行應用程式與驅動之前, 會先檢查是否有簽章.

## What is EDK-II and UDK?

- TianoCore
The community supporting an open source implementation of the UEFI.
https://www.tianocore.org/
https://github.com/tianocore/tianocore.github.io/wiki

- EDK II
EFI Development Kit. EDK II is a modern, feature-rich, cross-platform firmware development environment for the UEFI and PI(UEFI Platform Initialization) specifications.  EDK II is the open source project for which volunteers (contributors) participate in development.
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II#stable-tags

- UDK
UEFI Development Kit (UDK) releases pre-date the introduction of the stable tag, occur less frequently, and have a longer validation cycle. Each UDK release is a fully validated implementation by Intel for a specific revision of the EDK II source. 
https://github.com/tianocore/tianocore.github.io/wiki/UDK2018
https://github.com/tianocore/tianocore.github.io/wiki/UDK

- Differences between UDK and EDK II
https://github.com/tianocore/tianocore.github.io/wiki/Differences-between-UDK-and-EDK-II



## Build EDK-II or UDK2018
### 開發前須知

- 請準備一個乾淨的OS環境, 以避免相關的 compiler 設定錯誤, 或是花過多時間修改預設
- 開發環境設置好後請做好備份, 個人在開發過程中, 開發碟因各種原因重灌及重新設置環境
- 先確認開發版(主機板)上UEFI的支援狀況
- 推薦透過 sourcetree 管理 edk-II source code
- 使用未知(UEFI 開發商)版本的 Protocol 容易造成崩潰, 實驗測試時務必注意

### EDK II build environment

- 不論版號或指令, 請以Wiki上的說明為主!
https://github.com/tianocore/tianocore.github.io/wiki/UDK2018-How-to-Build

- Download and Install Windows 10 SDK ([Link](https://developer.microsoft.com/zh-tw/windows/downloads/windows-10-sdk/))
- Install C compiler (Visual Studio 2015 pro)
    - 安裝時請勾選"Visual C++“
    - 若未執行第一步, 請勾選"Windows 8.1 and Windows Phone 8.0/8.1 Tools”
	
- Download and Install NASM 2.14.2 or later ([Link](https://www.nasm.us/))
    - 安裝到 C:\Nasm
    - 添加環境變數(PATH): C:\Nasm

- Download and Install Python 2.7.x ([Link](https://www.python.org/downloads/))
    - 安裝到 C:\Python27
    - 添加環境變數(PATH): C:\Python27

- Download and Install OpenSSL ([Link](https://indy.fulgan.com/SSL/))
    - 安裝到 C:\Openssl
    - 添加環境變數(PATH): C:\Openssl 

### Create the full Source Code directory for the UDK2018 release

- Download EDK2- UDK2018 (Link)
- Create a working space directory in the build machine, for example, - <span class="highlight1">C:\MyWorkspace</span> 
- Extract files in [edk2-vUDK2018] to the working space directory C:\MyWorkspace
- Move all files and folders under <span class="highlight1">"vUDK2018"</span>  to <span class="highlight1">"C:\MyWorkspace"</span> 
- Generate OpenSSL* Crypto Library
- Open file <span class="highlight1">"C:\MyWorkspace\CryptoPkg\Library\OpensslLib\OpenSSL-HOWTO.txt"</span> and follow the instruction to install OpenSSL* for UEFI building. For this release, please use OpenSSL-1.1.0g. Download it from Link Extract it to <span class="highlight1">C:\MyWorkspace\CryptoPkg\Library\OpensslLib</span>, and rename its directory name to openssl
- Compile the BaseTools See:  (Link)
    - Open a <span class="highlight1">Microsoft Visual Studio* command prompt</span>, type <span class="highlight1">cd C:\MyWorkspace</span> to enter the workspace directory
    - Compile the BaseTools C source tools
        - <span class="highlight1">set PYTHON_HOME=C:\Python27</span>
        - <span class="highlight1">edksetup.bat Rebuild</span>
    ![](https://i.imgur.com/tmp8ZXu.png)
- Build Steps *** NT32 X64 ***
    - Open a Microsoft Visual Studio* command prompt, type <span class="highlight1"> cd C:\MyWorkspace</span> to enter the workspace directory
    - Use edksetup.bat command to initialize the working environment.
      <span class="highlight1">edksetup --nt32 X64</span>
    - Type following command to build Nt32 platform. <span class="highlight1">build -t VS2015x86 -a X64</span>
    - Upon the build completing successfully there should be the UEFI Application <span class="highlight1">"HelloWorld.efi"</span> in the <span class="highlight1">C:\ MyWorkspace\Build\NT32X64\RELEASE_VS2015x86\X64 directory</span>
    - 預設的設定: <span class="highlight1">C:\MyWorkspace\Conf\target.txt</span>
    - 編譯成功後可以透過UEFI Shell 模擬的方式查看, 執行 <span class="highlight1">C:\MyWorkspace\Build\NT32X64\DEBUG_VS2015x86\X64\SecMain.exe</span>
    - UEFI Shell 輸入 <span class="highlight1">HelloWorld.efi</span>, 之後會看到"UEFI Hello World!”

### /Workspace/Conf/target.txt

- 預設的設定如下:
    - ACTIVE_PLATFORM       = Nt32Pkg/Nt32Pkg.dsc
    - TARGET                            = DEBUG
    - TARGET_ARCH                = IA32
    - TOOL_CHAIN_CONF      = Conf/tools_def.txt
    - TOOL_CHAIN_TAG         = MYTOOLS
    - BUILD_RULE_CONF        = Conf/build_rule.txt
- 可以透過指令 <span class="highlight1">edksetup.bat ReConfig</span> 還原預設值
- 有關設定值的詳細說明請查看 target.txt (附錄A)
- 預設值也可透過 build 指令修改當前參數, 例如:
    ```
    build -t VS2015x86 -a X64 -b RELEASE
    ```
    即可編出64bit  release 的版本, 更多說明請下help指令(附錄B)

### edksetup --nt32 X64

![](https://i.imgur.com/gytNgy4.png)

### SecMain.exe

![](https://i.imgur.com/IAiFcjt.png)

### HellowWorld.efi

![](https://i.imgur.com/8AYELCy.png)

## UEFI Application 

- 可以分為以下三類:
    - UefiMain 
    - ShellAppMain
    - Main
- 其中 ShellAppMain 及 Main 需要 Shell 相關的Protocol, 因此只能在 UEFI Shell 底下執行

## UEFI Option ROM
### 透過 EfiRom Utility 建立Option ROM

- EfiRom 為 EDK-II 專案中標準的工具, 可以在BaseTools\Bin\Win32 中找到執行檔.
- EfiRom 有幾特點:
    - 支援多個 UEFI binary file
    - 支援一個 Legacy option ROM binary file
    - 支援UEFI壓縮演算法
    - 支援設定 vendor id 、device id、class code …
- 範例:
```shell
EfiRom -o -f 0x197B -i 0x0585 -l 0x010601 -r 1 -ec 
IdeController.efi AtaAtapiPassThruDxe.efi  AtaBusDxe.efi -b jmb585.com -v 
```
### EfiRom 主要參數說明

根據 PCI and UEFI specification 必填及主要參數如下:
```shell
-o FileName, --output FileName
	File will be created to store the output content.
-e EfiFileName
	EFI PE32 image files.
-ec EfiFileName
	EFI PE32 image files and will be compressed.
-b BinFileName
	Legacy binary files.
-l ClassCode
	Hex ClassCode in the PCI data structure header.
-f VendorId
	Hex PCI Vendor ID for the device OpROM, must be specified
-i DeviceId
	Hex PCI Device ID for the device OpROM, must be specified
```

## UEFI Shell 
### UEFI Shell Environment

- execute UEFI applications 
- getting the memory map
- modifying boot manager variables 
- loading UEFI drivers 
- Support lots of commands

![](https://i.imgur.com/LisE9NJ.png =500x)


- 將目標隨身碟格式化成FAT32 或是其他FAT格式(部分主機板有NTFS的driver)

- UDK2018 下載下來後, 會放幾個不同平台已編好的版本, 我們需要對應的 Shell.efi (C:\MyWorkspace\ShellBinPkg\UefiShell\X64\Shell.efi)
- 在目標隨身碟上建立資料夾 X:\EFI\BOOT (Windows上不用在意大小寫)
- 將下載下來的檔案解壓縮後放到 X:\EFI\BOOT 
    - 64 bit: Bootx64.efi or Shellx64.efi
    - 32 bit: Bootia32.efi or Shell.efi
- BIOS設定: Security-->Secure Boot = Disable
- BIOS設定: Boot-->CMS = Disable
- <span class="highlight1">BIOS設定(MSI): Setting -> Advanced -> Windows OS Configuration -> Windows 10 WHQL Support  = UEFI</span>
    :::info
    各家在BIOS設定頁面的顯示與表達略有不同, 設定提供參考
    :::

### UEFI Shell - 常用指令

- **Help** : Displays the UEFI Shell command list or verbose command help.
- **Devices** : Displays the list of devices managed by UEFI drivers.
- **Drivers** : Display the UEFI driver list.
- **Dh** : Display the device handles in the UEFI environment.
- **Pci** : Display PCI device list or PCI function configuration space and PCIe extended configuration space.
- **Load** : Loads a UEFI driver into memory.
- **Loadpcirom** : Load a PCI Option ROM.
- **Map** : Displays or defines file system mappings.
- **OpenInfo** : Displays the protocols and agents associated with a handle.

### UEFI Shell Q&A

- **命令是否區分大小寫?**
    - 否, 支援 Windows 的 CMD 規則
    
- **如何查看 UEFI Shell 支援的指令?**
    - 執行命令 “help –b”, 其中 “–b“ 表示每次顯示一頁
- **如何查看UEFI Shell 使用說明 ?**
    - 以 “dh” 為例, 執行命令 “dh -? –b”
- **如何查看當前主機板是否支援 UEFI Shell 版本?**
    - 透過 “dh” 及 “drivers” 查看有關 Protocol 的說明等等是否有正確解析
- **是否能選任一版UEFI Shell, 主機板都能支援?**
    - 否, 根據 PI spec 的修改或是UEFI BIOS 廠商的版本, 有可能因不同版本的相容性問題, 造成無法進入 UFEI Shell 或是執行命令後當機
- **32位元的 UEFI Shell、UEFI Application、UEFI driver 等是否能在64位元下執行?**
    - 否, 不支援相容

## Option ROM development
### Handle與Protocol的關聯
- Handle: 
    - 每個 driver 會產生一個 HANDLE, 並加入 IHANDLE 做管理, 也就是所謂的 - handle database
    - 每個 Handle 上會 link 到 protocol interface
- Protocol:
    - 每個 protocol 都有唯一一組 EFI_GUID 用於識別
    - 將功能用 protocol 的方式包裝起來, 做為使用者與提供者共同的介面
    - UEFI driver 在start()宣告的變數, 會記錄在 protocol上, 然後在 stop() 中透過 openProtocol() 取出並釋放記憶體
- 程式結構可參考 :
    - \MdeModulePkg\Core\Dxe\Hand\Handle.h

### Boot Manager透過什麼Protocol來找bootable device
![](https://i.imgur.com/M33JZ4x.png)

### AHCI Option ROM的使命?
- 讓 PCIe to SATA 轉板可以正常運作(認碟、開機)
- 修復 Hardware 的 BUG
- 以 edk2 上的範本做說明, 須提供以下 PROTOCOL 

    | Protocol Interface  |      Implement    | device type|
    | --------            | --------          | --------   |
    | IdeControllerInit   | SataController    | HDD + ODD  |
    | AtaPassThru         | AtaAtapiPassThru  | HDD        |
    | ExtScsiPassThru     | AtaAtapiPassThru  | ODD        |
    | ScsiIo              | ScsiBus           | ODD        |
    | BlockIo             | AtaBus or ScsiDisk| HDD or ODD |
    | BlockIo2            | AtaBus or ScsiDisk| HDD or ODD |
    | DiskInfo            | AtaBus or ScsiDisk| HDD or ODD |

### DriverBindingSupported的注意事項
- 印字需要注意, 否則可能造成問題
- 盡可以將是否支援的判斷列在此處
- 不在 support() 中操作硬體
- 注意 openProtocol() 屬性的選擇

### DriverBindingStart() 的注意事項
- 某些主機板有可能會同一個 handle 進入兩次 Start(), 因此需要再判斷一次是否已安裝目標 protocol 再繼續執行
- 由於宣告實體Data struture 在這個 function, 因此要注意 return 是否釋放

### 合併多個Dxe的注意事項
- 合併原因:
    - 降低 Code Size: 雖然UEFI spec 2.8 有說明PCI Option ROM 的大小可以到 16MiB (14.4.2 PCI Option ROMs), 但某些主機板只有 64 KiB 的空間, 且包含 Legacy option ROM
    - 讓 ImageLoad() 只做一次: 某些主機板不支援OptionROM 中有多個 uefi drivers, 只會 Load 第一個
- 注意事項:
    - 移除 IDE 的相關程式碼
    - 移除絕不會使用的流程
    - 在EfiLibInstallDriverBindingComponentName2()中, DriverBindingHandle 除了第一個以外要填NULL, 代表建立新的 handle

### 其他 – 如何逐步執行?

- 可參考 #define PAUSE_DOWN 透過 key press even 的方式達到逐步執行

    ![](https://i.imgur.com/JNlXZe5.png =550x)

### 其他 – OpenProtocol() 
有關 OpenProtocol() 的屬性

![](https://i.imgur.com/QCMANJU.png)

- EFI_OPEN_PROTOCOL_BY_DRIVER 及 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 才需要呼叫 CloseProtocol
- EFI_OPEN_PROTOCOL_BY_DRIVER 只允許一個占用
:::info
更多說明請參考 UEFIDriverWriterGuideV1.0.1120308
:::

### 其他 – 主機板行為假設思路

:::info
當有假設時，應找尋推翻假設例子並建立新的假說，以此反覆實驗及對照文件找出特性，下面紀錄其中一段過程
:::

- <span class="highlight1">假說</span>: 主機板會優先 Load BIOS 廠商(AMI) 的 AHCI driver 並非 Option ROM
- <span class="highlight1">原因</span>: 進到 UEFI SHELL 底下查看，發現主機板沒有正確 Load
- <span class="highlight1">推翻</span>: 部分主機板還是會 Load UEFI Option ROM，並且根據 Spec 說明應以 Option ROM 優先 Load ( 根據 support() 判斷是否 install)
- <span class="highlight3">正確結果</span>:
       由於最開始開發時，Option ROM 大小超過 64 KiB 並且為多個 UEFI driver (image)，因此會有不正常行為．

### 其他 – 驗證時的注意事項(1)
- BIOS 設定
    - 先將BIOS設定還原到預設狀態
    - 將 CSM 設定為 Disable
    - 如果有 Fast Boot 必須關閉
    - 確認系統碟為 Legacy 還是 UEFI 的 OS Loader
    - 驗證光碟機時除了設定開機順序以外，可能啟用的行為會與 Legacy 模式下不同 (需要按任意鍵啟用)
- 某些 BIOS 需要更新後才可正常運作，請到官網下載最新的BIOS版本並更新主機板狀態不正常時，完全斷電後重新設定環境


### 其他 – 驗證時的注意事項(2) 　
- 注意Option ROM (Legacy + UEFI) 大小不可超過 64KiB
- header (3K) 不算進 64 KiB
- 開啟 debug 印字後需要注意大小
- Debug 時可以先將 Legacy 移除
- 編譯時以 Release 編譯
- 開發時也可以在 windows底下透過模擬器 Debug，但有關硬體的實際行為，還是必須以實際在主機板上跑過一次


## Debug methods

- **SecMain.exe**: 
前面 How to build 中有提到的模擬環境, 適用 32bit 及 64bit, 硬體部分是模擬的, 因此行為未必正確.

- **UEFI Shell 隨身碟開機**: 
可以在 UEFI Shell 平台下, 觀察實際 Protocol 的使用狀況, 以及硬體在 setup 結束後的狀態等等, 可搭配 serial port印字, 或是用event 的方式做到單步執行

- **Intel® UEFI Development Kit Debugger Tool**:
搭配模擬器及工具, 可以做到 Source 級別的除錯, 想了解Setup 過程可以使用此方式逐步執行.

### Intel® UEFI Development Kit Debugger Tool

- 需要安裝以下:
    - QEMU:  一款 open source 的 CPU模擬器
    - OVMF: EDK2 裡的一個專案,  讓UEFI BIOS可以跑在虛擬機器上面
    - WinDbg: Microsoft Windows上的多用途除錯器
    - Intel® UEFI Development Kit Debugger Tool:  
    - 由 Intel 所開發的 Source Level Debugger, 需搭配 WinDbg 一起運作
    - com0com: 建立虛擬COM port

- Step1. 安裝 QEMU
    - 下載網址: http://lassauge.free.fr/qemu/QEMU_on_Windows-v19.html
    - 解壓縮後將路徑加入系統環境變數, 或在使用時指定絕對路徑

        :::warning
        目前成功的組合是用 qemu-0.13.0版, 其他版本只能用於一般模擬, 無法與目標工具連動.
        ::: 

- Step2. 編譯 OVMF
    - 編譯環境請參考 EDK-II 說明
    - 編譯可選 32 位元或是 64 位元, 但 qemu-0.13.0 只支援 32 位元
    - 編譯時需要額外加入以下兩個參數
        ```
        -DDEBUG_ON_SERIAL_PORT=TRUE 
        -DSOURCE_DEBUG_ENABLE
        ```
    - 如果遇到遇到缺少 ASL 請參考並安裝
    https://github.com/tianocore/tianocore.github.io/wiki/Asl-Setup
    - 最後目標得到 OVMF.FD 檔
    
        :::info
        build -t VS2015x86 -a IA32 -p C:\MyWorkspace\OvmfPkg\OvmfPkgia32.dsc -DDEBUG_ON_SERIAL_PORT=TRUE -DSOURCE_DEBUG_ENABLE 
        :::
        
- Step3. 安裝 WinDbg
    - 下載網址: 透過 Windows SDK (Kit)
https://developer.microsoft.com/zh-tw/windows/downloads/windows-10-sdk
    - 這邊只要注意不要修改安裝路徑即可

- Step4. 安裝 Intel UEFI Development Kit Debugger Tool
    - 下載網址: https://firmware.intel.com/develop/intel-uefi-tools-and-utilities/intel-uefi-development-kit-debugger-tool#overlay-context=develop
    - 安裝過程會自動搜尋 WinDbg路徑, 或自行指定,  請指定 x86 的版本
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe
需要注意的是, 在設定 “Debug Port Channel”的步驟, 我們選擇 Serial 並設定 COM6
    - 設定也可以在之後修改, 參考路徑:
"C:\Program Files (x86)\Intel\Intel(R) UEFI Development Kit Debugger Tool\SoftDebugger.ini

    - 根據版本不同, 可能要在 SoftDebugger.ini  加上
        ```
        [Debug]
        Debug=1
        ```
        
- Step5. 安裝 Com0Com
    - 下載網址: http://com0com.sourceforge.net/
        安裝完後透過 CMD 執行 
        C:\Program Files (x86)\com0com\setupc.exe
        輸入指令
        Command > Install PortName=COM6 PortName=COM7
    - 最後由裝置管理員確認 driver 是否安裝成功
    
        ![](https://i.imgur.com/0rHpnAe.png)

- 執行階段
    - **Step1**. 
執行 “Start WinDbg with Intel UDK Debugger Tool”, 如果前面沒有設定錯誤, 他會自動開啟 WinDbg 
    - **Step2**.
執行 qemu 並指定模擬的BIOS檔案路徑及serial port

        ```
        C:\Qemu_0.13.0\Qemu-windows-0.13.0\qemu.exe -L     
            C:\UEFI\Build\OvmfX64\DEBUG_VS2015x86\FV -bios 
            C:\UEFI\Build\OvmfX64\DEBUG_VS2015x86\FV\OVMF.fd -serial COM7
        ```
- 成功畫面

    ![](https://i.imgur.com/jW74Ip0.png)

## Reference
UEFI spec
https://uefi.org/specifications
EDK-II
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II
Intel® UEFI Development Kit Debugger Tool
https://tinyurl.com/rmz5t27
https://tinyurl.com/tgzuf4u

## 附錄A
### /Conf/target 
```
#  PROPERTY              Type       Use         Description
#  ----------------      --------   --------    -----------------------------------------------------------
#  ACTIVE_PLATFORM       Filename   Recommended Specify the WORKSPACE relative Path and Filename
#                                               of the platform description file that will be used for the
#                                               build. This line is required if and only if the current
#                                               working directory does not contain one or more description
#                                               files.
ACTIVE_PLATFORM       = Nt32Pkg/Nt32Pkg.dsc

#  TARGET                List       Optional    Zero or more of the following: DEBUG, RELEASE, NOOPT
#                                               UserDefined; separated by a space character.
#                                               If the line is missing or no value is specified, all
#                                               valid targets specified in the platform description file 
#                                               will attempt to be built. The following line will build 
#                                               DEBUG platform target.
TARGET                = DEBUG

#  PROPERTY              Type       Use         Description
#  ----------------      --------   --------    -----------------------------------------------------------
#  TARGET_ARCH           List       Optional    What kind of architecture is the binary being target for.
#                                               One, or more, of the following, IA32, IPF, X64, EBC, ARM
#                                               or AArch64.
#                                               Multiple values can be specified on a single line, using
#                                               space charaters to separate the values.  These are used
#                                               during the parsing of a platform description file, 
#                                               restricting the build output target(s.)
#                                               The Build Target ARCH is determined by (precedence high to low):
#                                                 Command-line: -a ARCH option
#                                                 target.txt: TARGET_ARCH values
#                                                 DSC file: [Defines] SUPPORTED_ARCHITECTURES tag
#                                               If not specified, then all valid architectures specified
#                                               in the platform file, for which tools are available, will be
#                                               built.
TARGET_ARCH           = IA32

#  PROPERTY              Type       Use         Description
#  ----------------      --------   --------    -----------------------------------------------------------
#  TOOL_DEFINITION_FILE  Filename  Optional   Specify the name of the filename to use for specifying
#                                             the tools to use for the build.  If not specified,
#                                             WORKSPACE/Conf/tools_def.txt will be used for the build.
TOOL_CHAIN_CONF       = Conf/tools_def.txt

#  TAGNAME               List      Optional   Specify the name(s) of the tools_def.txt TagName to use.
#                                             If not specified, all applicable TagName tools will be
#                                             used for the build.  The list uses space character separation.
TOOL_CHAIN_TAG        = MYTOOLS

# MAX_CONCURRENT_THREAD_NUMBER  NUMBER  Optional  The number of concurrent threads. If not specified or set
#                                                 to zero, tool automatically detect number of processor
#                                                 threads. Recommend to set this value to one less than the
#                                                 number of your computer cores or CPUs. When value set to 1,
#                                                 means disable multi-thread build, value set to more than 1,
#                                                 means user specify the thread number to build. Not specify
#                                                 the default value in this file.
# MAX_CONCURRENT_THREAD_NUMBER = 1

#  PROPERTY              Type       Use         Description
#  ----------------      --------   --------    -----------------------------------------------------------
# BUILD_RULE_CONF  Filename Optional  Specify the file name to use for the build rules that are followed
#                                     when generating Makefiles. If not specified, the file: 
#                                     WORKSPACE/Conf/build_rule.txt will be used
BUILD_RULE_CONF = Conf/build_rule.txt

```

## 附錄B

```
Usage: build.exe [options] [all|fds|genc|genmake|clean|cleanall|cleanlib|modules|libraries|run]

Copyright (c) 2007 - 2017, Intel Corporation  All rights reserved.

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -a TARGETARCH, --arch=TARGETARCH
                        ARCHS is one of list: IA32, X64, IPF, ARM, AARCH64 or
                        EBC, which overrides target.txt's TARGET_ARCH
                        definition. To specify more archs, please repeat this
                        option.
  -p PLATFORMFILE, --platform=PLATFORMFILE
                        Build the platform specified by the DSC file name
                        argument, overriding target.txt's ACTIVE_PLATFORM
                        definition.
  -m MODULEFILE, --module=MODULEFILE
                        Build the module specified by the INF file name
                        argument.
  -b BUILDTARGET, --buildtarget=BUILDTARGET
                        Using the TARGET to build the platform, overriding
                        target.txt's TARGET definition.
  -t TOOLCHAIN, --tagname=TOOLCHAIN
                        Using the Tool Chain Tagname to build the platform,
                        overriding target.txt's TOOL_CHAIN_TAG definition.
  -x SKUID, --sku-id=SKUID
                        Using this name of SKU ID to build the platform,
                        overriding SKUID_IDENTIFIER in DSC file.
  -n THREADNUMBER       Build the platform using multi-threaded compiler. The
                        value overrides target.txt's
                        MAX_CONCURRENT_THREAD_NUMBER. When value is set to 0,
                        tool automatically detect number of processor threads,
                        set value to 1 means disable multi-thread build, and
                        set value to more than 1 means user specify the
                        threads number to build.

-f FDFFILE, --fdf=FDFFILE
                        The name of the FDF file to use, which overrides the
                        setting in the DSC file.
  -r ROMIMAGE, --rom-image=ROMIMAGE
                        The name of FD to be generated. The name must be from
                        [FD] section in FDF file.
  -i FVIMAGE, --fv-image=FVIMAGE
                        The name of FV to be generated. The name must be from
                        [FV] section in FDF file.
  -C CAPNAME, --capsule-image=CAPNAME
                        The name of Capsule to be generated. The name must be
                        from [Capsule] section in FDF file.
  -u, --skip-autogen    Skip AutoGen step.
  -e, --re-parse        Re-parse all meta-data files.
  -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.
  -q, --quiet           Disable all messages except FATAL ERRORS.
  -v, --verbose         Turn on verbose output with informational messages
                        printed, including library instances selected, final
                        dependency expression, and warning messages, etc.
  -d DEBUG, --debug=DEBUG
                        Enable debug messages at specified level.
  -D MACROS, --define=MACROS
                        Macro: "Name [= Value]".
  -y REPORTFILE, --report-file=REPORTFILE
                        Create/overwrite the report to the specified filename.

-Y REPORTTYPE, --report-type=REPORTTYPE
                        Flags that control the type of build report to
                        generate.  Must be one of: [PCD, LIBRARY, FLASH,
                        DEPEX, BUILD_FLAGS, FIXED_ADDRESS, HASH,
                        EXECUTION_ORDER].  To specify more than one flag,
                        repeat this option on the command line and the default
                        flag set is [PCD, LIBRARY, FLASH, DEPEX, HASH,
                        BUILD_FLAGS, FIXED_ADDRESS]
  -F FLAG, --flag=FLAG  Specify the specific option to parse EDK UNI file.
                        Must be one of: [-c, -s]. -c is for EDK framework UNI
                        file, and -s is for EDK UEFI UNI file. This option can
                        also be specified by setting *_*_*_BUILD_FLAGS in
                        [BuildOptions] section of platform DSC. If they are
                        both specified, this value will override the setting
                        in [BuildOptions] section of platform DSC.
  -N, --no-cache        Disable build cache mechanism
  --conf=CONFDIRECTORY  Specify the customized Conf directory.
  --check-usage         Check usage content of entries listed in INF file.
  --ignore-sources      Focus to a binary build and ignore all source files
  --pcd=OPTIONPCD       Set PCD value by command line. Format: "PcdName=Value"
  -l COMMANDLENGTH, --cmd-len=COMMANDLENGTH
                        Specify the maximum line length of build command.
                        Default is 4096.
 --hash                Enable hash-based caching during build process.
  --binary-destination=BINCACHEDEST
                        Generate a cache of binary files in the specified
                        directory.
  --binary-source=BINCACHESOURCE
                        Consume a cache of binary files from the specified
                        directory.
  --genfds-multi-thread
                        Enable GenFds multi thread to generate ffs file.

```

###### tags: `UEFI` 


