UNIQLOCK

2010年9月16日 星期四

整理有關PEI

EFI架構中分SECPEIDXEBDS等幾個階段。
PPI
PEIM to PEIM interface)是PEI階段的概念,就是一個PEIMPEI moduleA 如果想用另外一個PEIM
  B中定義的函數,就可以在B中將這個函數組織成一個介面,然後安裝一下(就是存到 PPI database中),之後A中要用的時候,再從PPI databaselocate出來,就可以用了。

Protocol
就是DXE階段的類似PPI的東西,只不過要比PPI複雜一些,不過本質差不多。

driver
的概念比較廣,PEI階段的PEIMDXE階段的每一個模組都可以叫做driver。具體還分很多類。

首先解決為什麼需要PPI或者Protocol
這裡拿PEI Phase作例子。比如有兩個PEIM,分別為A PEIMB PEIMA PEIM實現了一個Function,比如R/W SMBus, B PEIM要用這個Function,怎麼辦?B PEIM也自己實現一個?

1:
不太符合軟體思想
2:
假如B PEIMSMBus不沾邊,這樣的話也與模組化不相符。倘若C PEIM以及N PEIM都要用,是不是都要實現?

這個時候PPI就登場了,A PEIM實現某個Function,並以PPI的形式install出來,這樣B PEIM也想使用這個Function,只需通過GUID(身份證)找到這個Function就可以使用了,不用自己再次實現。

DXE phase driver protocol 有點雷同,一樣是有個產生,有個消費。用這種觀念下去追幾組 PEI phase code 很容易明白的。


1.PEI Service Table 是如何實現對所有PEIM都可見的?
2.
我看的幾個PPIinstall的時候都是通過函數體裡面定義的
EFI_PEI_SERVICE 定義的變數調用InstallPpi函數指標來install這個PPI,這樣如何讓這個PPI對所有的PEIM都可見呢,進而locate到他?

EFI的框架有關,他的框架想儘量的減小代碼的size,但是又要有可擴展和容易維護的特性等等,這問題基本上就是一個PEI階段全局的包含大量service data database,這樣就可以增強代碼的可重用性。
example
: 如果某個完成特定功能的 service已經被 installPPI database,而你正好想用這樣一個功能,這種情況要做的就是locatePpi,在全局database找到這個函數的指標,下面就可以調用它了,就不必自己動手寫這樣一個service,減少了代碼的重複。

1. 每個PEIMEntryPoint入口參數中都有這個:
          IN EFI_PEI_SERVICES  **PeiServices;

2. PEI core
維護了一個私有資料結構中有一項為:
          PEI_PPI_DATABASE      PpiData;   所有安裝的PPI都儲存在那裡。安裝新的PPI時就往那添加,要locate一個PPI時就去那裡翻就是了。


整理自BIOSREN

Handle

作者: Gilvin


個人理解 handle 像竹竿,竹竿本身沒屬性的,下面掛衣服,他就是個曬衣架;下面掛箏幹,它就是烘食物的,什麼都不掛,竹竿橫躺在那就沒作用,就得收回箱子裡。

UEFI
  的角度來談,handle 本身並無屬性,他就是個指針,有個識別符 (Handle Key)。它下面掛著 image ,他就是個 image handle ,他掛條 device path ,他就是個 device handle,什麼都沒有,他就會被 handle database 回收。
由此可知,handle 下至少要有一個以上的 protocol 存在。所以一般建 protocol ,如果 install Protocol Interface 了,就會要求程式員指派給 handle 掛載,如果沒指派,就會創個新 handle。同理,要讓 handle 不存在,就得把他下面所有的 protocol uninstall
這是比較初步的概念,要再深入,請參照 Intel UEFI Driver Writers Guide(DWG 0.9 Draft) 關於 handle 的章節。

2010年9月7日 星期二

指標

什麼是指標?

    int *ptr;

上面的"ptr"他是一個指標型態變數,代表一個位址(address),"*ptr"代表此位址內的資料,他的資料型態是int.

做個比喻:

      有一列按照順序排列編號的櫃子從0~10由管理員管理.假設你想知道哪個 櫃子是空的,你問管理員,他便給了你一個號碼,你就按照號碼去找櫃子,或者你想直接拿你自己的東西便告訴管理員要從哪個櫃子拿給你.


上面的"管理員=ptr",他給的號碼就是"已經有地址的ptr",而拿直接拿給你的東西就是"*ptr".

這樣大概就很清楚了.說到這還要介紹"&".


     int num = 10 ;
     int *ptr ;
     ptr = &num ;
     
上面的"&"就是"把ptr的位址變成num的位址",所以*ptr的資料就是10.

還有很多指標的運用有空再補充.

2010年9月2日 星期四

EFI模組化


以下簡單整理目前對EFI模組化的了解:
  1. FD (Firmware Device):這是整個 EFI 儲存資料的地方,可以看成你電腦上那顆 HDD 也就是一個 Device.
  2. FV (Firmware Volume):在 FD 當中可以有很多個 FV , 這裡可以把 FV 看成 HDD 上你分割以後的磁碟 C:\ ; D:\ 等,這樣比較好理解.分別儲存了相關的code資料,避免不相關的code混亂.每一個FV必須遵循 FFS(Firmware File System) 的規定.

  3. FFS (Firmware File System):儲存於 FV 當中,每個 FFS 命名都有唯一性絕不重複並且以 GUID 做為名稱固定格式.每個 FFS 都有定義好的格式(Header)以便提供定義好的 Firmware Service 使用.
  4. Section:在 FFS 中分為許多段(Section),而且分為許多種不同類型,甚至可以包含一個壓縮過的FV.
這裡可以畫成一張簡圖:




了解模組化的結構後再來就是看懂 Protocol!

C 模組化


看到EFI code時發現以前學校所學得實在是太少又不夠扎實了!無法理解他的架構為何是這樣寫,有什麼含意. 
所以查了許多資料,了解到這就是對物件導向不熟悉,再來就是所謂的"模組化"! EFI就是模組化以後的產物,所以先了解什麼是模組化再去研讀EFI模組化架構,發現再去看code的時候更有感覺了!
現在要加強的就是物件導向和模組化的概念,把基礎打穩再去看code會更好更快!

以下是找到不錯的資料網址,可以連結去看看!