bloggerads

2015年7月26日 星期日

UEFI 各階段資料的傳遞方式

  將bios 選單變數(ex: SetupData.my_var)傳遞到PEI及DXE的方法


  //
  // PEI 接收資料
  //
  Status = (*PeiServices)->LocatePpi (
                          PeiServices,
                          &gEfiPeiReadOnlyVariablePpiGuid,
                          0,
                          NULL,
                          &ReadOnlyVariable
                          );
                          
  ASSERT_PEI_ERROR (PeiServices, Status);
  VariableSize = sizeof (SETUP_DATA);
  
  Status = ReadOnlyVariable->GetVariable (
                            PeiServices,
                            L"Setup",
                            &gEfiSetupGuid,
                            NULL,
                            &VariableSize,
                            &SetupData
                            );
                            
  if (EFI_ERROR (Status)) 
      return;

SMBios (System Management Bios)

使用者可以透過SMBios知道這台電腦的詳細規格,RW everything / RW這些tool都有提供SMBios data查詢。

SMBios是一份軟體的spec, 他定義了兩個table, 即EPS ( Entry Point structure) 和 Structure Table

EPS位於記憶體1MB以下64K之間,也就是0xF0000 ~ 0xFFFFF之間。透過程式搜尋搜尋_SM_和_DMI_這兩個Keyword可以找到這個table。

以下是 SMBIOS 2.1 (32-bit) Entry Point structure,這邊列出比較重要的部分


Offset
Name
Length
Description
00h
Anchor String
4 BYTEs
_SM_, specified as four ASCII characters (5F 53 4D 5F).
10h
Intermediate Anchor String
5 BYTEs
_DMI_, specified as five ASCII characters (5F 44 4D 49 5F)
16h
Structure Table Length
WORD
Total length of SMBIOS Structure Table, pointed to by the Structure Table Address, in bytes
18h
Structure Table Address
DWORD
32-bit physical starting address of the read-only SMBIOS Structure
1Ch
Number of SMBIOS Structures
WORD
Handle的數量

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