搜尋此網誌

2012年12月22日 星期六

sed指令介紹---(1)

雖然Sed不是很多人用,不過個人覺得它是一套很好用的軟體。
在Linux上,已經大部分都內建了。
在Windows上,請參閱此網站:
http://gnuwin32.sourceforge.net/packages/sed.htm

範例:
1. delete blank lines((刪除此行,當行為空白行)
sed -e /^$/d file

2. delete lines beginning with a tab(刪除此行,當行的開頭與一個tab字元)
/^  /d

3. delete lines beginning w/ any alpha characters,〈, or % (刪除此行,當行的開頭與一個任何一個字元)
/^[a-zA-Z\〈\%]/d

4. find lines beginning w/ one or more blanks, then print only the blanks(找到此行,當它的行開頭是一個或多個空白,然後只印出空白)
/^  */ {
        s/^\(  *\).*/\1/
}

5. delete all lines that just have ^M (need to do ^V ^M trick here)(刪除所有行,當它有 ^M)
/^^M$/d

2012年11月19日 星期一

部署安全啟動影像檔與憑證方針(Deploying Secure Boot Image and Certificate Policy)

1.10 部署安全啟動影像檔與憑證方針

此章節描述如何部署影像檔與憑證方針,使用使用安全啟動自訂模式設定功能。

注意:此功能是不包含在UDK2010.SR1釋放,但加入了在EDK2的r13146記錄,還有它將被加入在未來的UDK版本。
本文件中沒有討論其他的方法來展開安全啟動策略利用BIOS供應商或作業系統供應商的特定的工具。
值得注意的,再UEFI2.3.1A規範中,安全啟動自訂模式安裝設定不是必須的,但是被要求通過Windows硬體認證規定,在2011的十二月。
http://msdn.microsoft.com/library/windows/hardware/hh748188
安全啟動影像檔和憑證策略規定是由指定的PK與KEK,還有加入授權憑證和影像檔簽章到授權簽章資料庫變數(DB)和禁用證書和圖像憑證與影像檔簽章到禁用簽章資料庫變數(DBX)。安全啟動自訂模式提供設定畫面用於此目的。

1.10.1 安全啟動安裝設定與使用者模式

UEFI 2.3.1A規格書的27.5章節定義安裝設定與使用者模式。
•     安裝設定模式(Setup Mode) - 當沒有平台密鑰(PK)被記錄發生時,在這個模式,PK、KEK、DB、還有DBX變數能被寫入,且無需授權。
•     使用者模式(User Mode) - 在一個平台密鑰(PK)被登錄與持續直到這個平台密鑰(PK)被清除時,在使用者模式期間,這安全啟動方針是強制執行的。

當前的模式可以被得到,藉由讀取SetupMode變數同樣描述在UEFI 2.3.1A的3.2章節。那裡的值如果為"1"就是SetupMode,若是為"0"就是指示為User Mode。
這片段的程式碼如下範例所顯示,它檢查這SetupMode值經由GetEfiGlobalVariable()函式,它使用EFI_GLOBAL_VARIABLE GUID。此函式被定義在MdePkg\Library\UefiLib\UefiLib.c.
#include〈Uefi.h
#include〈Library/UefiLib.h
UINT8 *SetupMode;
SetupMode = GetEfiGlobalVariable (L”SetupMode”);
If (SetupMode == NULL) {
//
// Null SetupMode  means no Authenticated Variable
// driver was dispatched. Secure Boot is not supported.
//

} else if (*SetupMode == 1 ) {
// platform is in SETUP MODE

} else if (*SetupMode == 0 ) {
// platform is in USER MODE



} else {

// handle undefined value


}

圖6 SetupMode架構變數的檢查值

1.10.2 安全啟動設定標準與自訂模式
安全啟動自訂模式設定功能允許使用者去修改一個實際存在的PK,、KEK,、DB,與DBX變數。此功能被定義在Windows硬體認證需求十二月,2011:
系統主要的UEFI安全啟動韌體,被實現在EDK2的r13146。它延伸使用者模式與兩個附加的模式(標準模式與自訂模式)。

•     標準模式 - 標準模式設定被顯示如圖7。如果一個實際存在使用者被偵測到, 然後轉換到自訂模式已啟動。Nt32Pkg與OvmfPkg,總是允許從標準模式進入到自訂模式。其他平台藉由平台特殊的方式去偵測到物理的存在,例如一個跳線器的存在。
•     自訂模式 - 在這模式PK,、KEK,、DB,與DBX變數能被更新。自訂模式設定被顯示如下面圖8到圖20。
這意味著實際存在的使用者能執行接下來的動作:

•     關閉安全啟動藉由刪除PK。
•     更新PK去開啟安全啟動。
•     記下KEK’s.
•     刪除KEK’s.
•     加入DB或DBX憑證,還是影像檔簽章。
•     從DB或DBX刪除憑證或是影像檔簽章。
這些活動被執行利用安裝設定畫面,顯示在1.10.5章節。

1.10.3  使用安全啟動自訂模式
在開啟UEFI安全啟動(藉由設定PK)以前,在KEK中的白與黑列表,DB與DBX必須被設定經授權的與禁用憑證,還有簽章。

1. 配置經授權的簽章憑證與影像檔的簽章。當安全啟動被開啟時,這裡有兩個方法授權給影像檔去執行:

  • 所有影像檔簽章經由一個簽章憑證,它能被授權藉由登入這簽章憑證:(在範例中,它是KekRoot.cer)在KEK(請看圖17與圖18)。
  • 個人影像檔簽章藉由另一個簽章憑證,它能被授權無須登入。那簽章憑證藉由登入各個影像檔簽章在DB中(請看圖17與圖18)。

2. 下個配置禁用簽章憑證與影像檔的簽章。

  • 如果特定的簽章憑證或影像檔的簽章已經被列入黑名單,登入它們到DBX(請看圖20)。

3. 最後,登入PK(PkRoot.cer在這範例中)重新開啟安全啟動(請看圖13)。

1.10.4 安全啟動自訂ModeSetup畫面
此章節顯示提供這個功能,依據安全啟動自訂模式的實行在EDK2 r13146。其他的實現可能使用不同的選單。

1.10.4.1 標準模式 – 安全啟動配置
安全啟動被配置從設定經由選擇裝置管理員,然後安全啟動配置從裝置列表。
這呈獻安全啟動配置畫面,顯示在圖7,這顯示系統是一個標準模式(如在1.10.3節所描述)與那試圖安全啟動被開啟。

注意:   此“嘗試安全啟動” 項目顯示目前安全啟動UEFI變數狀態與無關安全啟動配置模式。換言之,安全啟動可以被開啟或關閉,在任意標準安全啟動配置模式或自訂安全啟動配置模式。

Figure 7 Standard Mode Screen


1.10.4.2 自訂模式 – 安全啟動配置
如果一個實際存在使用者被偵測到,(這是總是都在OVMF或Nt32Pkg實例下)選擇安全啟動模式範圍允許自訂模式被挑選,它呈現在自訂模式顯示在圖8,它允許安全啟動影像檔與簽章策略被改變(請看圖11自訂安全開機模式選項顯示)。


圖9 安全啟動配置 - 關閉
在這實例中,自安全啟動模式沒有被開啟以來,這試圖安全啟動是空白的。

1.10.4.3 開啟安全啟動
開啟安全啟動利用自訂模式設定畫面,接著這些步驟:
•     配置KEK。請看圖14。
•     隨意地, 配置DB。請看圖17。
•     隨意地, 配置DBX。請看圖20。
•     配置PK去開啟安全啟動。請看圖13。
一個安全啟動配置畫面範例,接著這些步驟被顯示在圖9之後。

圖9 安全啟動配置 - 開啟
這個例子,企圖安全啟動被開啟(X) ,安全啟動模式從未被配置。


圖10 關閉安全啟動畫面

1.10.4.4 關閉安全啟動
安全啟動被關閉,藉由移除PK如圖10所示,這會造成準備安全啟動區域還原成空白,如圖8中所示。

1.10.4.5 自訂安全啟動模式選項
這自訂安全啟動模式項目畫面顯示在圖11。圖11自訂安全啟動模式項目畫面提供存取的畫面,如
•     記錄或刪除PK (請看圖12)
•     記錄或刪除KEK密鑰與憑證(請看圖14)
•     記錄或刪除DB憑證與簽章(請看圖17)
•     記錄或刪除DBX憑證與簽章(請看圖20)

圖11 自訂安全開機模式項目畫面


1.10.4.6 PK項目
此PK選項項目鏈結到圖12的PK選項畫面,它允許PK被登入(請參閱圖13)或刪除。


圖12 PK項目畫面


1.10.4.7 記錄PK使用檔案
圖13登入PK畫面,允許PK被載入從一個檔案,例如從一個隨身碟。

圖13 記錄PK畫面



1.10.4.8 KEK項目
圖14 KEK選項鏈結到登入KEK畫面(圖15)或刪除KEK畫面(圖16)。

圖14 KEK項目畫面
1.10.4.9 記錄KEK
圖15登入KEK畫面允許KEK被載入從一個檔案,例如從一個隨身碟。

圖15 記錄KEK畫面

選擇登入KEK利用檔案與使KEK檔案通過。
選擇GUID簽章與進入此GUID對應到的KEK。
KEK GUID是一個GUID值,來識別KEK。此值必須是以下格式:
11111111-2222-3333-4444-1234567890ab.

1.10.4.10 刪除KEK
圖16 刪除KEK畫面顯示,每個KEK項目憑著GUID與簽章型態,所以對於刪除要求KEK能被識別。

圖16 刪除KEK畫面
圖17 DB項目畫面鏈結到登入簽章(圖18)或刪除簽章(圖19)畫面。


圖17 DB項目畫面


1.10.4.12 記錄簽章
圖18登入簽章畫面允許影像檔簽章或憑證被載入從一個隨身碟。
圖18 記錄簽章畫面

選擇登入KEK利用檔案與使KEK檔案通過。
選擇GUID簽章與進入此GUID對應到的DB項目。
簽章GUID是一個GUID值,來識別此簽章的擁有者。此值必須是以下格式:
11111111-2222-3333-4444-1234567890ab.


1.10.4.13 刪除簽章
圖19 刪除簽章畫面顯示每個項目,所以對於刪除它們能被識別。


圖19 刪除簽章畫面

1.10.4.14 DBX項目
圖20 DBX項目顯示,模仿DB項目畫面...


圖20 DBX項目畫面

1.11 UEFI安全啟動方案
下面的UEFI的安全啟動情況,證明如下:

  1. 一個擁有的簽章的UEFI影像檔,它的簽章憑證或簽名被登入。
  2. 一個沒有的簽章的UEFI影像檔,它的簽名不被登入。
  3. "一個擁有的簽章的驅動程式,它的簽名被登入"與"一個沒有的簽章的驅動程式,它的簽名不被登入"。
  4. 啟動一個OS使用一個簽章與登入的驅動程式。

這些範例使用OVMF,如參考平台被描述在1.12章節中。其他的實現可能呈現不同的訊息。

1.11.1 一個擁有簽章的UEFI影像檔,它的簽章憑證或簽章被記錄
在這個實例中,恰好地擁有的簽章的影像檔被執行。如果一個違反安全被偵測到(例如影像檔恰好沒有簽章與影像檔鑑定失敗),這行為取決於影像檔驗證策略,對於那影像檔型態(例如OptionRom,移動式媒體或固定媒體)。請看圖21與章節1.3。

圖21 正確簽章的應用程式被執行

1.11.2 一個沒有簽章的影像檔,它的簽章沒有被登入
在這個實例中,影像檔鑑定失敗與此影像檔不被執行。請看圖22。
圖22 未簽章的影像檔不備執行

1.11.3 一個擁有簽章的驅動程式(它的簽章被記錄)與一個沒有簽章的驅動程式(它的簽章沒有被記錄)
在這個實例中,有簽章的驅動程式被載入,而沒有簽章的驅動程式則沒有被載入。


圖23 載入簽章與未簽的驅動程式

1.11.4 啟動一個作業系統使用一個擁有簽章與登記的驅動程式
目前正在開發一個在QEMU上可被安全啟動的Linux核心。

1.12 使用OVMF與UEFI安全啟動
1.12.1 概述
OVMF (Open Virtual Machine Firmware)開放式虛擬機韌體能夠被使用如參考平台,對於測試包括UEFI安全開機在內。OVMF執行如同韌體在QEMU( www.qemu.org ),一個開放式來源處理器的模擬。
以QEMU,你能啟動UEFI Shell,執行UEFI 應用程式,開啟UEFI安全啟動與甚至啟動一個作業系統。

關於更多資訊在OVMF,請參閱:
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=OVMF

注意:SVN修正r13186被要求Nt32Pkg ,在UDK2010.SR1釋放中,不提供安全啟動的建立選項。

1.12.2 取得QEMU
QEMU是被包含在許多Linux發行版。
在編寫此文件時,在Windows7 *是無效的。請檢查更新在:
http://wiki.qemu.org/Links.

QEMU二進位檔的Windows XP版本能夠在下列鏈結下載:
http://wiki.qemu.org/Links 非正式的QEMU二進位檔的部分。

預先編譯的Windows版本(≥ 0.9.1),提供經由TAKEDA Toshiya QEMU在Windows版本0.13.0 (10/16/2010)上。
http://homepage3.nifty.com/takeda-toshiya/qemu/index.html
注意:這是一個QEMU的舊版本,它可能漏掉一些更新在2010以後。

1.12.3 建立OVMF
EDK2來源程式碼,它包含OVMF:
https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2 .

如何編譯OVMF的指令,請參考:
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=How_to_build_OVMF.

OVMF可以被編譯在X64、IA32或IA32X64架構上。
概述,編譯OvmfX64Pkg修改Conf/target.txt如下顯示:
•     ACTIVE_PLATFORM = OvmfPkg/OvmfX64Pkg.dsc or
•     TARGET_ARCH = X64
或OvmfIa32X64Pkg:
•     ACTIVE_PLATFORM = OvmfPkg/OvmfIa32X64Pkg.dsc
•     TARGET_ARCH = IA32 X64
或OvmfIa32Pkg:
•     ACTIVE_PLATFORM = OvmfPkg/OvmfIa32Pkg.dsc
•     TARGET_ARCH = IA32

1.12.4 CryptoPkg的OpenSslLib附屬功能

這安全軟體套件的鑑定變數與安全啟動特徵要求保密圖像提供支援,藉由OpenSslLib 在CryptoPkg中。

OpensslLib不被整合到CryptoPkg中,但包含在EDK2中,在來源編造上。詳細資訊如何下載與安裝OpenSSL對於使用在CryptoPkg的OpenSslLib,在CryptoPkg\Library\OpensslLib\ Patch-HOWTO.txt能夠找到相關資訊。


1.12.5 在OVMF中,開啟UEFI安全啟動
在OVMF,開啟UEFI安全啟動,接下來是編譯指令:
〉build –D SECURE_BOOT_ENABLE

當編譯完成時,OVMF影像檔在編譯的目錄中。例如,如果使用UNIXGCC跟X64工具,這ovmf.fd影像檔會座落於:
Build/OvmfX64/DEBUG_UNIXGCC/FV/OVMF.fd


1.12.6 來源層除錯器
如何使用UDK2010Source Level Debugger的指令,包括OVMF有用的在內:
http://www.intel.com/content/www/us/en/architecture-and-
technology/unified-extensible-firmware-interface/uefi-dev-kit-debugger-tool-
manual.html.

1.12.7 執行OVMF與QEMU
QEMU預期這BIOS是在bios.bin檔案與視訊Rom在vgabios-cirrus.bin。兩者的檔案應該是來自相同OVMF平台。

如在1.12.2章節上描述,QEMU能被執行在任一方的Linux或微軟視窗作業系統。無論如何,系統主機QEMU型態沒有關係到此系統,它主機的簽章工具描述在1.6章節上。那是一個影像檔簽章及Linux主機簽章工具應該辨識到這個影像檔擁有微軟視窗作業系統的簽章反之亦然。再者任一的影像檔可以被執行在任一QEMU環境上。

執行OVMF及QEMU,執行接下來的步驟:
1.   建立一個‘run-ovmf’目錄,在你的編輯樹下去執行OVMF及QEMU
bash$ mkdir run-ovmf
2.   複製或鏈結BIOS與Video Rom 影像檔,如下顯示:
對於Linux主機的QEMU:
bash$ cd run-ovmf
bash$ ln -s ../Build/OvmfX64/DEBUG_UNIXGCC/FV/OVMF.fv bios.bin
bash$ ln -s
../Build/OvmfX64/DEBUG_UNIXGCC/FV/CirrusLogic5446.rom \ vgabios-
cirrus.bin
對於微軟視窗XP主機的QEMU:
〉cd run-ovmf
〉copy  ../Build/OvmfX64/DEBUG_UNIXGCC/FV/OVMF.fv bios.bin
〉copy  ../Build/OvmfX64/DEBUG_UNIXGCC/FV/CirrusLogic5446.rom \
vgabios-cirrus.bin
3.   也複製每個影像檔、憑證、或密鑰, 它們需要被登入在 PK、KEK、
DB或DBX,如1.10.4章節上所描述。
4.   開始QEMU及接下來的指令與等待OVMF去啟動UEFIsshell如圖24下所顯示。
bash$ qemu-system-x86_64 -L . -hda fat:.

注意:這命令製作這當前的目錄 (run-ovmf在此實例中)硬碟利用經由QEMU。無論如何,QEMU處理此磁碟同唯讀,所以檔案產生在QEMU內部;在QEMU離開後,它們不被看見在run-ovmf中。


圖24 QEMU執行OVMF
下一步選擇檔案系統:
Shell〉fs0:
此檔案複製在步驟2與3上,現在它們將可被看見當輸入"ls"命令。

1.12.8 在OVMF中,開啟或修改UEFI安全啟動
UEFI安全啟動被開啟或修改如同1.10.4章節上所描述。

注意:因為UEFI安全啟動關閉,OVMF初始化。那安全開機的變數值為0x00。所以即使顯示選項的ROM有被簽章過,當OVMF開機它將失效。

注意:自變數不是目前持續的橫越OVMF祈願,UEFI安全啟動必須配置對於每個OVMF的祈願。

注意:如果使用UDK2010.SR1,關於此PcdOptionRomImageVerificationPolicy的系統預設值請看記錄在1.4章節。

1.12.9 QEMU註釋
在QEMU中:
•     輸入Ctl-Alt去釋放滑鼠。
•     輸入Ctl-Alt-3去看序列阜的訊息輸出。
關於更多資訊請瀏覽www.qemu.org。

1.13 使用Nt32PKG與UEFI安全啟動
1.13.1 概要
Nt32Pkg能被利用如同一個IA32提及的平台,對於測試包含UEFI安全開機在內。
以Nt32Pkg,你能啟動UEFI Shell,開啟UEFI安全啟動,與執行簽章的UEFI應用程式。

注意:Nt32Pkg不涵蓋一個視訊選項ROM的模擬,如OvmfPkg做的。所以它不能去驗證簽章選項的ROM對於Nt32Pkg。

注意:SVN修正r13186被要求Nt32Pkg ,在UDK2010.SR1釋放中,不提供安全啟動的建立選項。

1.13.2 建立Nt32Pkg
EDK2原始碼包含Nt32Pkg ,可以在此鏈結取得:
https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2 .

修改Conf/target.txt如顯示再去編譯Nt32Pkg:
•     ACTIVE_PLATFORM = Nt32Pkg /Nt32Pkg.dsc
•     TARGET_ARCH = IA32

1.13.3 CryptoPkg的OpenSslLib附屬功能
注意那安全軟體套件的鑑定變數與安全啟動特徵要求保密圖像提供支援,藉由OpenSslLib 在CryptoPkg中。

OpensslLib不被整合到CryptoPkg中,但包含在EDK2中,在來源編造上。詳細資訊如何下載與安裝OpenSSL對於使用在CryptoPkg的OpenSslLib,在CryptoPkg\Library\OpensslLib\ Patch-HOWTO.txt能夠找到相關資訊。

1.13.4 在Nt32Pkg中,開啟UEFI安全啟動
在Nt32Pkg中,去開啟UEFI安全啟動,接下來的是需求的建構指令:
〉edksetup --nt32
〉build –D SECURE_BOOT_ENABLE
Nt32Pkg將啟動,偕同它的檔案系統指在其生成目錄。
…\Build\NT32\DEBUG_VS2008x86\IA32
這裡建立一個子目錄去含蓋影像檔,憑證或密鑰,它們需要被登入在PK中、KEK、DB或DBX,如同在1.10.4章節上所描述。

1.13.5 進行Nt32Pkg
開始進行Nt32Pkg,輸入
〉build run


圖25 執行Nt32Pkg中
接下來選擇檔案系統:
Shell〉fs0:

在1.13.4節上描述的影像檔憑證,密鑰或複製的腳本到該目錄中,當輸入“ls”,將馬上被顯示。

1.13.6 開啟或修改UEFI安全啟動在Nt32Pkg

UEFI安全啟動被開啟或修改如在1.10.4節上所述。方案1, 2 還有3 描述在1.11節上,它也能被執行在Nt32Pkg。方案4中,其中涉及啟動一個OS,那是不被允許。

2012年10月22日 星期一

How to translate a main() function to ShellAppMain()?


  • Please generate the four files(test.info, teststrings.uni, test.h, test.c).
  • They will teach you how to translate your main() function to ShellAppMain(). 

/*****************************test.info***********************************/

[defines]
BASE_NAME            = test
FILE_GUID            = 8DF752F2-87B5-4c7b-AA4F-EDDA99DD3058
COMPONENT_TYPE       = APPLICATION

[sources.common]
   ..\ShCommonStrings.uni   
   testStrings.uni
   test.c
   test.h 
                                          
[includes.common]
  .
  ..\Inc
  ..\Library
  $(EDK_SOURCE)\Foundation
  $(EDK_SOURCE)\Foundation\Include
  $(EDK_SOURCE)\Foundation\Include\IndustryStandard
  $(EDK_SOURCE)\Foundation\Efi
  $(EDK_SOURCE)\Foundation\Efi\Include
  $(EDK_SOURCE)\Foundation\FrameWork
  $(EDK_SOURCE)\Foundation\FrameWork\Include
  $(EDK_SOURCE)\Foundation\Core\Dxe
  $(DEST_DIR)\

[libraries.common]  
  EfiShellLib
  EdkProtocolLib
  EdkFrameworkProtocolLib
  EfiProtocolLib
  ArchProtocolLib
  EdkGuidLib
  EdkFrameworkGuidLib
  EfiGuidLib


/*****************************teststrings.uni***********************************/
#langdef   eng "English"
#langdef   fra "Français"

#string STR_TEST_TOO_MANY_ARGS          #language eng  "%hs: Too many arguments\n"

#string STR_TEST_INVALID_ARG            #language eng  "%hs: Invalid argument - '%hs'\n"

#string STR_TEST_LINE_HELP              #language eng  "Test Function"

#string STR_TEST_VERBOSE_HELP           #language eng  "Test Function() print test string.\n"  
                                                      "\n"
                                                      "\n"
                                                      "\n"
                                                      "                 0.\n"
                                                      "                 1.\n"
                                                      "                 2.\n"
                                                      "                 3.\n"
                                                      "                 4.\n"
                                                      "                 5.\n"
                                                      "                 6.\n"
                                                      "                 7.\n"
                                                      "\n"

/*****************************test.h***********************************/
#ifndef _TEST_H
#define _TEST_H

//
//
//
#define EFI_TEST_GUID \
  { \
    0x8df752f2, 0x87b5, 0x4c7b, \
    { \
      0xaa, 0x4f, 0xed, 0xda, 0x99, 0xdd, 0x30, 0x58 \
    } \
  }

#endif

/*****************************test.c***********************************/
#include "EfiShellLib.h"
#include "test.h"

extern UINT8    STRING_ARRAY_NAME[];

#include STRING_DEFINES_FILE

EFI_HII_HANDLE  HiiHandle;
EFI_GUID        EfiTestGuid = EFI_TEST_GUID;

/*
typedef struct {
  CHAR16                    *FlagStr;
  UINT32                    FlagID;
  UINT32                    ConflictMask; //Conflict Flag ID
  SHELL_VAR_CHECK_FLAG_TYPE FlagType;
} SHELL_VAR_CHECK_ITEM;

typedef enum {
  FlagTypeSingle      = 0,
  FlagTypeNeedVar,
  FlagTypeNeedSet,    //Characters will be replaced by the blank.
  FlagTypeSkipUnknown //This set will cause the system hang.
} SHELL_VAR_CHECK_FLAG_TYPE;

typedef struct _SHELL_ARG_LIST {
  CHAR16                  *FlagStr;
  CHAR16                  *VarStr;
  UINTN                   Index;
  struct _SHELL_ARG_LIST  *Next;
} SHELL_ARG_LIST;

#define GetNextArg(a)   ((a)->Next)
#define GetFirstArg(a)  ((a)->VarList)
#define GetFirstFlag(a) ((a)->FlagList)

typedef struct {
  SHELL_ARG_LIST  *FlagList;
  SHELL_ARG_LIST  *VarList;
  UINTN           FlagCount;
  UINTN           ValueCount;
} SHELL_VAR_CHECK_PACKAGE;
*/

SHELL_VAR_CHECK_ITEM    TestCheckList[] = {
  {
    L"+a",
    0x01,
    0x02,
    FlagTypeSingle
  },
  {
    L"-a",
    0x02,
    0x01,
    FlagTypeSingle
  },
  {
    L"-b",
    0x03,
    0,
    FlagTypeNeedVar
  },
  {
    L"-c",
    0x04,
    0,
    FlagTypeNeedSet
  },
  {
    L"-z",
    0x05,
    0,
    FlagTypeSkipUnknown
  },
  {
    L"-?",
    0x02,
    0,
    FlagTypeSingle
  },
  {
    NULL,
    0,
    0,
    0
  }
};

CHAR8 *
test_unicode_str_to_ascii_str (
  IN  CHAR16   *Source,
  OUT  CHAR8  *Destination
  )
{
  ASSERT (Destination != NULL);
  ASSERT (Source != NULL);

  while (*Source != '\0') {
    *(Destination++) = (CHAR8) *(Source++);
  }

  *Destination = '\0';

  return Destination;
}

INTN 
unicode_strlen(
IN const CHAR16 *s
) {
const CHAR16 *sc;

for (sc = s; *sc != 0x00; ++sc)
/* nothing */;
return (INTN)((unsigned long long)sc - (unsigned long long)s);
}


EFI_STATUS
EFIAPI
InitializeTest (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  );

EFI_BOOTSHELL_CODE(
  EFI_DRIVER_ENTRY_POINT (InitializeTest)
)

EFI_STATUS
EFIAPI
InitializeTest (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++

Routine Description:

  Clear the sreen

Arguments:

  ImageHandle - The image handle
  SystemTable - The system table

Returns:

  EFI_SUCCESS - Success

--*/
{
  EFI_STATUS              Status;
//  UINTN                   Background;
//  UINTN                   ForeColor;
  CHAR16                  *Useful;
  SHELL_VAR_CHECK_CODE    RetCode;
  SHELL_VAR_CHECK_PACKAGE ChkPck;
  SHELL_ARG_LIST          *Item;

  ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));

  //
  // We are no being installed as an internal command driver, initialize
  // as an nshell app and run
  //
  EFI_SHELL_APP_INIT (ImageHandle, SystemTable);

  //
  // Enable tab key which can pause the output
  //
  EnableOutputTabPause();
  
  Status = LibInitializeStrings (&HiiHandle, STRING_ARRAY_NAME, &EfiTestGuid);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  RetCode = LibCheckVariables (SI, TestCheckList, &ChkPck, &Useful);
  if (VarCheckOk != RetCode) {
    switch (RetCode) {
    case VarCheckUnknown:
      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"test", Useful);
      break;

    case VarCheckDuplicate:
      PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"test", Useful);
      break;

    default:
      break;
    }

    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

  Print(L"test.c:main called with %d parameters\n", ChkPck.FlagCount);
  {
  int _Argc = (int)ChkPck.FlagCount, i;
  char buffer[1024], *str;
  int length, argc;
  char *argv[20];
 
  if (_Argc > 20)
  _Argc = 20;

   Item = GetFirstFlag (&ChkPck);
   for (i = 0; i < _Argc; i ++) {
   Print(L"[%d]=> FlagStr:%s VarStr:%s\n", Item->Index, Item->FlagStr, Item->VarStr);
   Item = GetNextArg (Item);
   }
 
  str = buffer;
  length = 0;
  argc = 0;
   Item = GetFirstFlag (&ChkPck);
   for (i = 0; i < _Argc; i++) {
  if (Item->FlagStr != NULL) {
  argv[argc] = str + length;
   length += (int)unicode_strlen(Item->FlagStr);
  if (length > 1024)
  break;
   test_unicode_str_to_ascii_str(Item->FlagStr, argv[argc]);
   argc ++;
  if (Item->VarStr != NULL) {
  argv[argc] = str + length;
   length += (int)unicode_strlen(Item->VarStr);
  if (length > 1024)
  break;
   test_unicode_str_to_ascii_str(Item->VarStr, argv[argc]);
   argc ++;
   }
   }
   Item = GetNextArg (Item);
   }

//   main( argc, argv ); /*Call your main() function here.*/
  }

  Status = EFI_SUCCESS;
Done:
  LibCheckVarFreeVarList (&ChkPck);
  LibUnInitializeStrings ();
  return Status;
}

EFI_STATUS
EFIAPI
InitializeTestGetLineHelp (
  OUT CHAR16              **Str
  ) {
  return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiTestGuid, STRING_TOKEN (STR_TEST_LINE_HELP), Str);
}



2012年10月15日 星期一

The definitions is about Hii DriverCallback() function

The description of Hii DriverCallback() is for EDK II.


typedef UINTN EFI_BROWSER_ACTION;

#define EFI_BROWSER_ACTION_CHANGING   0
#define EFI_BROWSER_ACTION_CHANGED    1
#define EFI_BROWSER_ACTION_RETRIEVE   2
#define EFI_BROWSER_ACTION_FORM_OPEN  3
#define EFI_BROWSER_ACTION_FORM_CLOSE 4
#define EFI_BROWSER_ACTION_DEFAULT_STANDARD      0x1000
#define EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING 0x1001
#define EFI_BROWSER_ACTION_DEFAULT_SAFE          0x1002
#define EFI_BROWSER_ACTION_DEFAULT_PLATFORM      0x2000
#define EFI_BROWSER_ACTION_DEFAULT_HARDWARE      0x3000
#define EFI_BROWSER_ACTION_DEFAULT_FIRMWARE      0x4000

//
// Types of the option's value.
//
#define EFI_IFR_TYPE_NUM_SIZE_8        0x00
#define EFI_IFR_TYPE_NUM_SIZE_16       0x01
#define EFI_IFR_TYPE_NUM_SIZE_32       0x02
#define EFI_IFR_TYPE_NUM_SIZE_64       0x03
#define EFI_IFR_TYPE_BOOLEAN           0x04
#define EFI_IFR_TYPE_TIME              0x05
#define EFI_IFR_TYPE_DATE              0x06
#define EFI_IFR_TYPE_STRING            0x07
#define EFI_IFR_TYPE_OTHER             0x08
#define EFI_IFR_TYPE_UNDEFINED         0x09
#define EFI_IFR_TYPE_ACTION            0x0A
#define EFI_IFR_TYPE_BUFFER            0x0B
#define EFI_IFR_TYPE_REF               0x0C

#define EFI_IFR_OPTION_DEFAULT         0x10
#define EFI_IFR_OPTION_DEFAULT_MFG     0x20


typedef struct {
  UINT8 Hour;
  UINT8 Minute;
  UINT8 Second;
} EFI_HII_TIME;

typedef struct {
  UINT16 Year;
  UINT8  Month;
  UINT8  Day;
} EFI_HII_DATE;

typedef union {
  UINT8           u8;
  UINT16          u16;
  UINT32          u32;
  UINT64          u64;
  BOOLEAN         b;
  EFI_HII_TIME    time;
  EFI_HII_DATE    date;
  EFI_STRING_ID   string;
} EFI_IFR_TYPE_VALUE;

// The operand (first byte) of this Statement or Question
#define EFI_IFR_FORM_OP                0x01
#define EFI_IFR_SUBTITLE_OP            0x02
#define EFI_IFR_TEXT_OP                0x03
#define EFI_IFR_IMAGE_OP               0x04
#define EFI_IFR_ONE_OF_OP              0x05
#define EFI_IFR_CHECKBOX_OP            0x06
#define EFI_IFR_NUMERIC_OP             0x07
#define EFI_IFR_PASSWORD_OP            0x08
#define EFI_IFR_ONE_OF_OPTION_OP       0x09
#define EFI_IFR_SUPPRESS_IF_OP         0x0A
#define EFI_IFR_LOCKED_OP              0x0B
#define EFI_IFR_ACTION_OP              0x0C
#define EFI_IFR_RESET_BUTTON_OP        0x0D
#define EFI_IFR_FORM_SET_OP            0x0E
#define EFI_IFR_REF_OP                 0x0F
#define EFI_IFR_NO_SUBMIT_IF_OP        0x10
#define EFI_IFR_INCONSISTENT_IF_OP     0x11
#define EFI_IFR_EQ_ID_VAL_OP           0x12
#define EFI_IFR_EQ_ID_ID_OP            0x13
#define EFI_IFR_EQ_ID_LIST_OP          0x14
#define EFI_IFR_AND_OP                 0x15
#define EFI_IFR_OR_OP                  0x16
#define EFI_IFR_NOT_OP                 0x17
#define EFI_IFR_RULE_OP                0x18
#define EFI_IFR_GRAY_OUT_IF_OP         0x19
#define EFI_IFR_DATE_OP                0x1A
#define EFI_IFR_TIME_OP                0x1B
#define EFI_IFR_STRING_OP              0x1C
#define EFI_IFR_REFRESH_OP             0x1D
#define EFI_IFR_DISABLE_IF_OP          0x1E
#define EFI_IFR_TO_LOWER_OP            0x20
#define EFI_IFR_TO_UPPER_OP            0x21
#define EFI_IFR_ORDERED_LIST_OP        0x23
#define EFI_IFR_VARSTORE_OP            0x24
#define EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25
#define EFI_IFR_VARSTORE_EFI_OP        0x26
#define EFI_IFR_VARSTORE_DEVICE_OP     0x27
#define EFI_IFR_VERSION_OP             0x28
#define EFI_IFR_END_OP                 0x29
#define EFI_IFR_MATCH_OP               0x2A
#define EFI_IFR_EQUAL_OP               0x2F
#define EFI_IFR_NOT_EQUAL_OP           0x30
#define EFI_IFR_GREATER_THAN_OP        0x31
#define EFI_IFR_GREATER_EQUAL_OP       0x32
#define EFI_IFR_LESS_THAN_OP           0x33
#define EFI_IFR_LESS_EQUAL_OP          0x34
#define EFI_IFR_BITWISE_AND_OP         0x35
#define EFI_IFR_BITWISE_OR_OP          0x36
#define EFI_IFR_BITWISE_NOT_OP         0x37
#define EFI_IFR_SHIFT_LEFT_OP          0x38
#define EFI_IFR_SHIFT_RIGHT_OP         0x39
#define EFI_IFR_ADD_OP                 0x3A
#define EFI_IFR_SUBTRACT_OP            0x3B
#define EFI_IFR_MULTIPLY_OP            0x3C
#define EFI_IFR_DIVIDE_OP              0x3D
#define EFI_IFR_MODULO_OP              0x3E
#define EFI_IFR_RULE_REF_OP            0x3F
#define EFI_IFR_QUESTION_REF1_OP       0x40
#define EFI_IFR_QUESTION_REF2_OP       0x41
#define EFI_IFR_UINT8_OP               0x42
#define EFI_IFR_UINT16_OP              0x43
#define EFI_IFR_UINT32_OP              0x44
#define EFI_IFR_UINT64_OP              0x45
#define EFI_IFR_TRUE_OP                0x46
#define EFI_IFR_FALSE_OP               0x47
#define EFI_IFR_TO_UINT_OP             0x48
#define EFI_IFR_TO_STRING_OP           0x49
#define EFI_IFR_TO_BOOLEAN_OP          0x4A
#define EFI_IFR_MID_OP                 0x4B
#define EFI_IFR_FIND_OP                0x4C
#define EFI_IFR_TOKEN_OP               0x4D
#define EFI_IFR_STRING_REF1_OP         0x4E
#define EFI_IFR_STRING_REF2_OP         0x4F
#define EFI_IFR_CONDITIONAL_OP         0x50
#define EFI_IFR_QUESTION_REF3_OP       0x51
#define EFI_IFR_ZERO_OP                0x52
#define EFI_IFR_ONE_OP                 0x53
#define EFI_IFR_ONES_OP                0x54
#define EFI_IFR_UNDEFINED_OP           0x55
#define EFI_IFR_LENGTH_OP              0x56
#define EFI_IFR_DUP_OP                 0x57
#define EFI_IFR_THIS_OP                0x58
#define EFI_IFR_SPAN_OP                0x59
#define EFI_IFR_VALUE_OP               0x5A
#define EFI_IFR_DEFAULT_OP             0x5B
#define EFI_IFR_DEFAULTSTORE_OP        0x5C
#define EFI_IFR_CATENATE_OP            0x5E
#define EFI_IFR_GUID_OP                0x5F

typedef struct _EFI_IFR_OP_HEADER {
  UINT8                    OpCode;
  UINT8                    Length:7;
  UINT8                    Scope:1;
} EFI_IFR_OP_HEADER;

2012年10月9日 星期二

轉換簽章驅動程式成.rom檔案

1.7 轉換簽章驅動程式成一個.rom檔案
UEFI 2.3驅動程式寫作指南( Drivers Writers Guide for UEFI 2.3 (DWG) )的第32章中介紹的方法去分散UEFI驅動程式。如果簽章的驅動程式將被安裝在一個PCI卡的Option ROM,它必須從.efi檔案轉換到.rom檔案。
這UEFI DWG描述多種方式去做此轉換。然而,"EfiRom"工具將

然而,"EfiRom"工具將適用於最常使用的方法簽署對簽章影像檔,因為簽章的發生在EDK II的建構後與包裝成Option ROM前. 這EDK II的編譯系統沒有能力去自動簽署UEFI驅動程式的章,在包裝它們一個Option ROM之前。這處理過程被描述在DWG的18.7.1章節。

此"EfiRom"二進制的工具可以發現在BaseTools/Bin/Win32的目錄中,在EDK2的工作區中。

這個範例從剛才作簽章的MyDriver.efi,所創建出來的MyDriver.bin:
〉EfiRom -f 0x1013 -i 0x00b8  -e MyDriver.efi
這裡的–f是廠商辨識ID與 –i是裝置ID。
這個範例顯示對於Cirrus Logic的5446設備在OvmfPkg引含的數值。

1.8 安裝簽章的驅動程式
如果簽章的驅動程式將被安裝在一個PCI裝置卡的Option ROM,接下來更新PCI卡的Option ROM方式將由卡供應商提供。
如果簽章的驅動程式將被分散在EFI系統磁碟分區,它已準備好進行佈置。

1.9 添加簽章驅動程式到開機程序
此簽章的驅動程式在開機維護管理員(Boot Maintenance Manager)設定被添加到開機程序,藉由選擇驅動程式選項,然後加入驅動程式選項用途檔案(Add Driver Option Using File)。

2012年10月8日 星期一

SPI Flash Chip - Winbond(W25Q80, W25Q16, W25Q32) Command List


Winbond(W25Q80, W25Q16, W25Q32)

FEATURES
 Family of SpiFlash Memories
 W25Q80: 8M-bit / 1M -byte (1,048,576)
 W25Q16: 16M-bit / 2M-byte (2,097,152)
 W25Q32: 32M-bit / 4M-byte (4,194,304)
 256-bytes per programmable page
 Standard, Dual or Quad SPI
 Standard SPI: CLK, /CS, DI, DO, /WP, /Hold
 Dual SPI: CLK, /CS, IO 0 , IO 1 , /WP, /Hold
 Quad SPI: CLK, /CS, IO 0 , IO 1 , IO 2 , IO 3
 Highest Performance Serial Flash  
 Up to 6X that of ordinary Serial Flash
 80MHz clock operation
 160MHz equivalent Dual SPI
 320MHz equivalent Quad SPI
 40MB/S continuous data transfer rate
 30MB/S random access (32-byte fetch)
 Comparable to X16 Parallel Flash
 Low Power, Wide Temperature Range  
 Single 2.7 to 3.6V supply
 4mA active current, 〈1 data-blogger-escaped-op=“o:p” data-blogger-escaped-power-down=“power-down”data-blogger-escaped-typ.=“typ.”〉
 -40°C to +85°C operating range
 Flexible Architecture with 4KB sectors
 Uniform Sector Erase (4K-bytes)
 Block Erase (32K and 64K-bytes)
 Program one to 256 bytes
 Up to 100,000 erase/write cycles
 20-year data retention
 Advanced Security Features
 Software and Hardware Write-Protect
 Top or Bottom, Sector or Block selection
 Lock-Down and OTP protection
 64-Bit Unique ID for each device
Note 1:
These features are on special order.
Please contact Winbond for details.
 Space Efficient Packaging
 8-pin SOIC 208-mil  
 8-pad WSON 6x5-mm (W25Q80 & W25Q16)
16-pin SOIC 300-mil (W25Q16 & W25Q32)


Instruction Set Table
INSTRUCTION NAME
BYTE 1 CODE
BYTE 2
BYTE 3
BYTE 4
BYTE 5
BYTE 6
N-BYTES
Write Enable
06h
Write Disable 
04h
Read Status Register-1
05h
(S7–S0) (2)
Read Status Register-2
35h
(S15-S8) (2)
Write Status Register
01h
(S7–S0)
(S15-S8)
Page Program
02h
A23–A16
A15–A8
A7–A0
(D7–D0)
(Next byte)
Up to 256 bytes
Quad Page Program
32h
A23–A16
A15–A8
A7–A0
(D7–D0)
Block Erase (64KB)
D8h
A23–A16
A15–A8
A7–A0
Block Erase (32KB)
52h
A23–A16
A15–A8
A7–A0
Sector Erase (4KB)
20h
A23–A16
A15–A8
A7–A0
Chip Erase
C7h/60h
Erase Suspend
75h
Erase Resume
94h
Power-down
B9h
High Performance Mode
A3h
dummy
dummy
dummy
Mode Bit Reset (4)
FFh
FFh
Release Power-down / Device ID
ABh
dummy
dummy
dummy
(ID7-ID0)(5)
Manufacturer/
Device ID
90h
dummy
dummy
00h
(M7-M0)
(ID7-ID0)
Read Unique ID(7)
4Bh
dummy
dummy
dummy
dummy
(ID63-ID0)
JEDEC ID
9Fh
(M7-M0) Manufacturer
(ID15-ID8) Memory Type
(ID7-ID0)
Capacity
Read Data
03h
A23–A16
A15–A8
A7–A0
(D7–D0)
(Next byte)
continuous
Fast Read
0Bh
A23–A16
A15–A8
A7–A0
dummy
(D7–D0)
(Next Byte) continuous
Fast Read Dual Output
3Bh
A23–A16
A15–A8
A7–A0
dummy
I/O = (D6,D4,D2,D0)
O = (D7,D5,D3,D1)
(one byte
per 4 clocks,
continuous)
Fast Read Dual Output
3Bh
A23–A16
A15–A8
A7–A0
dummy
(D7–D0, …)(8)
Fast Read Dual I/O
BBh
A23-A8(2)
A7-A0, M7-M0(9)
(D7–D0, …)(1)
Fast Read Quad Output
6Bh
A23–A16
A15–A8
A7–A0
dummy
(D7–D0, …)(10)
Fast Read Quad I/O
EBh
A23-A0, M7-M0(4)
(x,x,x,x, D7–D0, …)(12)
(D7-D0, …)(10)

Notes:
1. Data bytes are shifted with Most Significant Bit first. Byte fields with data in parenthesis “()” indicate data being read from the device on the DO pin.

2. The Status Register contents will repeat continuously until /CS terminates the instruction.

3. Quad Page Program Input Data
IO0 = (D4, D0, ...)
IO1 = (D5, D1, ...)
IO2 = (D6, D2, ...)
IO3 = (D7, D3, ...)

4. This instruction is recommended when using the Dual or Quad Mode bit feature. See section 10.2.28 for more information.

5. The Device ID will repeat continuously until /CS terminates the instruction.

6. See Manufacturer and Device Identification table for Device ID information.

7. This feature is available upon special order. Please contact Winbond for details.


8. Dual Output data  
IO0 = (D6, D4, D2, D0)
IO1 = (D7, D5, D3, D1)

9. Dual Input Address
IO0 = A22, A20, A18, A16, A14, A12, A10, A8    A6, A4, A2, A0, M6, M4, M2, M0  
IO1 = A23, A21, A19, A17, A15, A13, A11, A9    A7, A5, A3, A1, M7, M5, M3, M1

10. Quad Output Data
IO0 = (D4, D0, ...)
IO1 = (D5, D1, ...)
IO2 = (D6, D2, ...)
IO3 = (D7, D3, ...)

11. Quad Input Address
IO0 = A20, A16, A12, A8 , A4, A0, M4, M0
IO1 = A21, A17, A13, A9 , A5, A1, M5, M1
IO2 = A22, A18, A14, A10, A6, A2, M6, M2
IO3 = A23, A19, A15, A11, A7, A3, M7, M3

12. Fast Read Quad I/O Data  
IO0 = (x, x, x, x, D4, D0, ...)
IO1 = (x, x, x, x, D5, D1, ...)
IO2 = (x, x, x, x, D6, D2, ...)
IO3 = (x, x, x, x, D7, D3, ...)

Status Register-1
Bit
Name
Description
S7
SRP
Status Register Protect(NON-VOLATILE)
S6
SEC
Sector Protect(NON-VOLITILE)
S5
TB
Top/Bottom Block Protect
S4:2
BP2:0
Block Protect Bits (BP2, BP1, BP0)
S1
WEL
Write Enable Latch
S0
BUSY
Busy Status

Status Register-2
Bit
Name
Description
S15
R
Reserved
S14
R
Reserved
S13
R
Reserved
S12
R
Reserved
S11
R
Reserved
S10
R
Reserved
S9
QE
Quad Enable(NON-VOLITILE)
S8
SRP1
Status Register Protect1(NON-VOLITILE)

Manufacturer and Device Identification
MANUFACTURER ID
(M7-M0)
Winbond Serial Flash
EFH
Device ID
(ID7-ID0)
(ID15-ID0)
Instruction
ABh, 90h
9Fh
W25Q80
13h
4014h
W25Q16
14h
4015h
W25Q32
15h
4016h