Friday, May 17, 2013

UEFI – Phrase SEC

 

SEC是UEFI最早啟動的階段,也就是當按下Power-on後的第一件工作,

其中有三個主要的工作,分別為

1)與其他硬體確認開機BIOS的安全性,Core Root of Trust Module(CRTM)。

這必須要透過第三方硬體支援來確認BIOS本身的安全性,接者BIOS本身還會有機制繼續驗證下去,就有如一環接者一環,chain of trust。

2)決定CPU Operation Mode。

CPU因為相容性的問題,都會先用16bit width做處理,此階段可以先將16bit轉換成可支援的32bit, 64bit…,來提升開機速度。

3)暫時記憶體的設立。

在這項工作中,SEC會找尋適合的記憶體,來取代位於南僑所控制的ROM記憶體,來增加執行速度。因此,會利用SRAM, CPU Cache等等來載入初始的BFV,其容量都必須大於4KB<1><2>。

Reference

<1>http://www.techbang.com/posts/4359

<2>http://en.wikipedia.org/wiki/Real_mode

Thursday, May 9, 2013

State Machine ? Function Point !!!

不管中文或是英文都有很多文章在介紹這兩個理論的概念,在這裡是想用這兩種概念將程式寫的更容易維護和設計。

State Machine(SM)第一次看到這個名詞是我在研讀HMM的時後(有機會將這有趣的數學分享給大家),簡單來說就是狀態之間的轉移,數學上是以"機率"作為轉移依據,而在程式上是以"條件式"來決定。條件式在C語言裡不外乎使用 if / switch,

先來簡單的狀態序列<2>,配上常見的寫法我想會是~~

image

if (S=1) S = 2; do event S1

elseif (S=2) x = 3; do evnet S2

elseif (S=3) do event S3

或是用switch case…,想要讓狀態機多活一下,很直覺得就給它加個do while。這樣就大功告成了!?

小小狀態機或許這樣應該足夠了,但現在隨著硬體技術隨著<1>Moore定律的規範下不斷進步,其實軟體這裡也不會閒著,狀態機也是龐大的可怕,那這樣的寫法好maintain嗎? 我想這部分可以等到各位在工作時可以驗證一下,這裡是討論程式概念。

要怎麼做才直接且容易維護呢? 首先我們仔細想想,上述概念的寫法應該是這樣的SM。

image

首先,我想引用<3><4>來解釋SM table的設計,這方法可以用來紀錄下一個狀態位置。

CurrentState = SMTable[CurrentState ] ;

很好,有了這個機制我們的架構就變成這樣了!

image

這是俗稱的多此一舉,脫褲子放屁? 問題出在哪呢? 因為每個狀態有屬於自己的函式要處理,如果能跟著CurrentState這index改變,那就兩全其美了。所以就有function point<5-7>存在的必要性。

此外,要寫好貼切的function point,我想宣告的問題可是非常重要,如#define, typedef, 宣告型態<8>...

這是我簡單寫一個上面所形容的狀態機(source code)分享給各位,希望能讓各位產生一絲絲的共鳴。

<Reference>

<1>http://en.wikipedia.org/wiki/Moore's_law

<2>http://www.swarthmore.edu/NatSci/echeeve1/Class/e15/E15Lab2/CStateMachines/CStateMachines.html

<3>http://www.conman.org/projects/essays/states.html

<4>http://johnsantic.com/comp/state.html

<5>http://stackoverflow.com/questions/1591361/understanding-typedefs-for-function-pointers-in-c-examples-hints-and-tips-ple

<6>http://stackoverflow.com/questions/133214/is-there-a-typical-state-machine-implementation-pattern

<7>http://www.newty.de/fpt/intro.html#what

<8>http://www.devx.com/tips/Tip/13829

Monday, May 6, 2013

UEFI Coding Tips in SourceInsight

 

我想有在寫大型程式的工程師應該是有聽過SourceInsight(SI)這套軟體吧!!

今天我遇到一個小小問題,也找到問題點就分享給大家~~

使用SI的優勢是在於UEFI定義了很多的結構,我們在使用結構SI都會動態跑出關鍵的變數名稱,這方便設計者不用特地去記一些變數名稱。

不過,在我們設一個程式時會傳入EFI_SYSTEM_TABLE變數,

EFI_STATUS
sample(
  IN EFI_HANDLE                                 ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )

在之前都會先宣告EFI_APPLICATION_ENTRY_POINT(sample)或EFI DRIVER ENTRY POINT(sample),然而此次的宣告就導致SI無法判別此變數,原因是在於這兩個宣告是指向空集合。

此時,我會將宣告暫時註解起來以方便使用變數*SystemTable,其實<1>中也提到,這宣告對於模擬機器有很大的影響,但對於實際的硬體上並無差別,只是為了可讀性及好的習慣所以才多了這一行指令。

<Reference>

<1>http://biosengineer.blogspot.tw/2010/07/efidriverentrypoint.html

“Hello World” in UEFI (2)

 

"哈囉"時間就這樣愉快的過去了嗎?

雖然常常聽到一句俗語"好奇心害死一隻貓"。

但我的好奇心時常作祟,就會很想了解萬事的根本。

於是,開始反問自己一些問題。

“Hello World” 是怎麼秀出來的呢?

Print (L"Hello World\r\n");

這段指令就好像我們C語言常見的printf一樣,只是UEFI提供了print這個函式,而放在(protocol\print)的資料夾內。

但我卻想要用UEFI的概念寫出一樣的功能,該如何做呢?

因為我想這會是一個好時機更了解整個UEFI的概念。其實,UEFI提供了一個protocol handle服務Console Support,它可以幫助我們簡單的完成這項功能,概念顯得更貼近UEFI的架構。這指令為

SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Hello World\n\r");

protocol handle的名字為Txtout,可能會因為定義不同而有不同的名子。不過也可以從公定的GUID確切的找到這個protocol。

#define EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID \
  { 0x387477c2, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b }

Shell>guid –b

image

image

至於這protocol怎麼去控制硬體,這就會是一個很大的工程,這之中會跟組語有些關聯。遇到大問題這時還是要學會取捨,把大方向抓住,了解目前我們需要了解的就夠了。

Thursday, May 2, 2013

UEFI Build Code Tips

 

我們在Build Code的時候會產生幾個檔案,這些檔案會被壓縮到UEFI系統裡去。

  1. xxx.efi (EFI系統內的執行檔)
  2. xxx.dll (Dynamic-Link Library(如果觀念和win系統一樣的話,這應該就是動態連結庫)
  3. xxx.lib (Library)
  4. xxx.pdb (Program DeBug(我猜,這應該是Debug所需要的資料庫)
  5. xxx.exp

它們都存放在下方路徑中,當然這跟Compiler的路徑設定有關。

  • D:\Firmware\Platform\IntelSsg\Nt32\Build\IA32

[Tips]若程式之間並無關聯性,若不需要某項程式就來這砍掉,也不用大費周章的使用nmake clear。

Reference

<1>http://bbs.dianyuan.com/bbs/u/39/1141988403.pdf

<2>http://en.wikipedia.org/wiki/Dynamic-link_library

<3>http://en.wikipedia.org/wiki/Library_(computer_science)

UEFI Boot Services vs Runtime Services

 

      在之前的文章中有提到UEFI的系統大概可以區分兩個階段,起初是Boot Service再來就是Runtime Service(RS)如紅框所涵蓋的程序都可以稱為RS。

image

區分這兩個Service最重要的一項轉類點函數為

  • ExitBootServices()

讓我們稍微的Trace一下Code來感覺一下。

%%% In My Case (Maybe Different source code has signification procedure for costumer) %%%

發現ExitBootServices()會處在universal\acpi\acpifpdtsupport\acpifpdtsupport.c檔案中,

acpifpdtsupport(ACPI Firmware Performance Data Table Support)

經過一番波折後發現,acpifpdtsupport.inf檔案會發現有inclulde AcpiFPDTSupport.dxs

透過.dxs(Dependency eXpreSsion)找出了觸發的條件為

  1. EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID
  2. EFI_ACPI_SUPPORT_GUID
  3. EFI_CPU_ARCH_PROTOCOL_GUID

以上三項Protocols啟動後便會觸發

  • InitailizeAcpiFPDTSupport()

 

透過上敘的過程中會發現.inf和.dxs對於UEFI的重要性。

The relationship of the devices and drivers in UEFI

Shell> devices

透過這個指令可以觀察目前UEFI內有幾個硬體被控制著。也提供不少的訊息給設計者,如

TYPE是說明此設備是

[R] Root Controller

[B] Bus Controller

[D] Device Controller

image

#P(Parent) 和#C(Child)為繼承關係,我們也可以用下一個指令來觀察。

Shell>devtree

很清楚發現若

#P = - 為主要的設備起始端。

#C = Number 代表此設備將會給其他設備所使用。

image

再來我們把重點放在驅動程式上面,一個Device可以備好幾個Drivers所使用,我們可從

#D(Driver)來觀察,但重點來了~~~我們要如何得知是哪些Drivers所使用。

image

Shell> dh –d <CTRL>

這指令就可以好好觀察每個控制元的內容。

image

Wednesday, May 1, 2013

UEFI Handle Database

 

Handle的類型主要可以區分為這三種

  • executable image (drivers, application) – Agent Handles
  • devices (network controller, hard drive partitions) – Controller Handles
  • services (decompression, EBC virtual machine) – Service Handles

image

一個完整的Handle Database可以是很多個Handles所組成。

image

而一個Handle的架構為GUID,Protocol Interface,Private Data。

image

在Shelll中我們可以觀察handles的狀況。

Shell> dh –b

image

Reference

<1> Beyond BIOS Second Version

<2> Shell Command Menual

Register Transfer Level Design with Verilog (1) [ebook]

設計程式之所以有趣不外乎是它的千變萬化,同樣的結果卻有不同的寫法。 但這些不同寫法當中也並沒有分誰對誰錯,也沒有制定標準來規範何事該用何解。 這也就是我們設計者的珍貴!! [1] Primitive Instantiations 在Verilog中最基本的邏輯...