bloggerads

2015年7月6日 星期一

UEFI : DXE Driver


● 何謂Protocol:  
typedef的結構。在UEFI下會綁定GUID,並且透過Driver來安裝Protocol instancehandle. 上層若要控制device,必須透過呼叫Protocol instance來達成。
● Bus Driver Vs. Device Driver: 
Bus Driver會Create Child handle 但Device Driver不會。如果Bus Driver Create的 Child handle是Physical device, Bus Driver 必須安裝Device Path Protocol instance到Child handle
● Driver Initialization:

Driver Image會從儲存裝置(Rom, flash,...)中載入,也就是說,一旦在儲存裝置中找到Driver Image, 就會使用Boot ServiceLoadImage(), Driver Image載入到System Memory. 同時該driver會生成自己的Handle,並且在該Handle下安裝EFI_LOADED_IMAGE_PROTOCOL

typedef
EFI_STATUS
LoadImage (
  IN BOOLEAN BootPolicy,
  IN EFI_HANDLE ParentImageHandle,
  IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, // The DeviceHandle specific file path from which the image is loaded.
  IN VOID *SourceBuffer OPTIONAL,
  IN UINTN SourceSize,
  OUT EFI_HANDLE *ImageHandle // Pointer to the returned image handle that is created when the image is successfully loaded.
  );


裝了EFI_LOADED_IMAGE_PROTOCOL Handle稱之為Image Handle

接著,透過Boot ServiceStartImage()來啟動driverdriver會在Image Handle上安裝其它的Protocol,如果是EFI Driver Modeldriver,那麼會安裝EFI_DRIVER_BINDING_PROTOCOL, 如下,這時Driver Image才真正被當作Driver來處理

//
// Interface structure for the ControllerHandle Driver Protocol
//
typedef struct _EFI_DRIVER_BINDING_PROTOCOL {
  EFI_DRIVER_BINDING_SUPPORTED  Supported;
  EFI_DRIVER_BINDING_START      Start;
  EFI_DRIVER_BINDING_STOP       Stop;
  UINT32                        Version;
  EFI_HANDLE                    ImageHandle;
  EFI_HANDLE                    DriverBindingHandle;
} EFI_DRIVER_BINDING_PROTOCOL;

LoadImage()StartImage()做完之後driver會等待被Boot ServiceConnectController()調用(invoked)去連接到某個Controller。這時在System Memory中已經Load了很多的Driver都在等待被connect到Controller,這時ConnectController()會以Polling的方式去調用每個Driver Handle中的EFI_DRIVER_BINDING_PROTOCOL.Supported(),如果回EFI_SUCCESS,那麼該driver就會被connectcontroller上。之後會透過EFI_DRIVER_BINDING_PROTOCOL.Start()來初始化以及安裝特定的Protocol到此Controller。

2015年6月19日 星期五

UEFI : PEI Phase Code Trace

$ PEI (Pre Efi Initialization)的概述:

● Small, tight startup code
• Startup with transitory memory store for call-stack (I.e., cache)       
• XIP from ROM
● Core locates, validates, and dispatches PEIMs

● Publishes own protocol and call-abstraction with PPI
• Silicon/platform abstractions
● Primary goals
• Discover boot mode       
• Launch modules that initialize main memory       
• Discovery & launch DXE core- Convey platform info into DXE

2015年6月16日 星期二

UEFI : SEC Phase Code Trace

UEFI 架構只有SEC這個phase因為是machine dependent而且cache/memory尚未初始化,所以剛開始是組合語言寫的,最主要就是做以下這幾件事:
  1. 切32位元(或64位元)flat mode
  2. Cache As Ram (在Flat32.asm中jump到CacheAsRam函數的位址)
  3. 找BFV(Boot Firmware Volume), BFV指的是存放PEI Foundation/PEIMs的FV
  4. 找到以C寫的SEC phase entry point
  5. 跳到以C code寫的SEC point (SecStartup),最後Transfer the control to the PEI core
VOID
EFIAPI
SecStartup (
  IN UINT32    SizeOfRam,
  IN UINT32    TempRamBase,
  IN VOID      *BootFirmwareVolume
  )
{
   ...
}


從上電的reset vector, trace Code如下:

進入點為 UefiCpuPkg\ResetVector\Vtf0\Ia16\ResetVectorVtf0.asm


;; Reset Vector
;
; This is where the processor will begin execution
;
    nop
    nop
    jmp     short EarlyBspInitReal16

2015年5月8日 星期五

Git client 安裝和指令教學

1. 安裝Git軟體

使用Windows系統需先安裝Git這個軟體才能Access Git server,安裝好後在任意資料夾內點右鍵會看到這個Git的相關功能








2. 設定Git server

點Git Bash後會看到一個類似命令字元的視窗,key入ssh-keygen, 會生成兩個檔 (這兩個是一對的),將其放入c:\users\$username\.ssh\





這兩個檔案一個是public key (.pub), 一個是private key,到Git server下載code時會用這兩個檔案來檢查使用者的身分。

2015年5月1日 星期五

UEFI : Overview

// SEC Phase
  • Made by Assembly code (before CAR,Cache As Ram), C code (After CAR)
  • 進入protect mode
  • CPU Microcode patch
// PEI Phase
  • Made by C code
  • 在ROM上執行沒有壓縮的Code
  • Initialize chipset & Memory
  • S3 resume
  • Bios recovery (ex: Bios更新失敗的救援)
  • Disable Cache As Ram And Enable L1 L2 Cache 
  • 使用一小部分的memory,這個memory之後可能會被reallocate
  • 啟動DXE Initial Program Loader; DxeIPL
  1. 名詞解釋:
  • PEIM: PEI Module
  • PEI Service: PEI Core提供PEIM使用的的一些函式
  • PEI Core: 提供PEIM一些service和負責執行PEIM
  • PPI: PEI和PEI的介面, 讓其他PEIM透過locate PPI使用已安裝好的服務(簡單的說就是提供函式讓其他PEIM使用)
// DXE phase
  • 在RAM上執行Code,已可正常使用memory resource
  1. 名詞解釋:
  • Protocol: 如同PEI的PPI只是換地方換個名稱
  • Driver: 在DXE叫做driver, 如同PEI module code

2015年4月10日 星期五

UEFI : Build EDK2 module (UDK2014 / UDK2015) and a Demo code

EDK2最近 release 穩定的版本為UDK2014 和 UDK2015

首先, 到sourceforges下載TianoCore code: https://sourceforge.net/p/tianocore/edk2/ci/UDK2015/tree/
我是下載UDK20014

如果是下載UDK2015, 請先將資料夾放到對應的位置

1. Unzip UDK2015.MyWorkSpace.zip & BaseTools(Windows).zip
2. Put BaseTools, Conf, edkstup.bat to MyWorkSpace

如果是使用Linux則可以直接透過git 取得,
bash$:   sudo apt-get install git
bash$:   git clone http://github.com/tianocore/edk2

2015年4月7日 星期二

What do BIOS engineer do?

Bios工作內容以Q&A的方式來說明,提供有志於x86韌體發展的朋友了解

1. Bios RD工作是寫x86組合語言嗎? 
A: 是C語言。 現在IC高度競爭的年代,也是Time to Market的年代。大家求的就是快、跟易於維護的程式。 所以晶片廠商提供 C 的Compiler環境是必要的, 如果連C都不支援,相信這樣的晶片應該沒人會用。因此在2002年Intel release EFI這個以C為架構的Open source系統後,現在幾乎所有的個人電腦或手機(Iphone)的firmware interface都已經是UEFI (Unified Extensible Firmware Interface)了。下圖是傳統Bios和UEFI Bios比較,UEFI他有現代作業系統的架構,所有控制硬體的方法都是透過呼叫protocol(driver), 而非透過軟體中斷



2. 既然是UEFI 那為什麼舊有的裝置(PCI 卡)還可以使用,連DOS這個作業系統都還能用?
A: 為了要相容過去舊有的架構,UEFI 有CSM這個模組。基本上就是靠它來模擬 Legacy Bios的行為。

3.  Bios只是個OS的boot loader嗎? boot loader為什麼需要這麼多工程師
A: Bios主要是OS的boot loader沒錯, 但是x86是個非雜龐大的系統,硬體管理/初始化/設定中斷向量表以及和OS溝通跟硬體錯誤處理都是大學問。再加上x86是採用PCI架構所以有相當彈性的硬體擴充能力,因此有大量的外部裝置,內部也相當複雜,需要很多人來維護這個系統和debug。

4. 當Bios工程師需要從哪裡入門?
A: Bios RD要讀的spec相當多,入門課就是PCI spec, 再來就是搭配UEFI code來看UEFI架構Spec,以及Intel Architectures
Software Developer’s Manual,這些大致上看過後,可以依照自己的興趣去study 南橋晶片上的控制器如 AHCI / XHCI/ LAN...等等,最後還有一份spec比較進階的就是 ACPI spec,用來定義OS和Hardware之間的介面。這些Spec需要反覆的熟讀,我自己也是只了解一部分。