撰寫更新驅動程式套件
您必須將 ESRT 中所述之每個韌體資源的更新承載組合在一起並散發在其自己的 驅動程式套件 中,以便讓它維持自己的版本設定配置,而不需系結至可能以相同步調更新的其他韌體資源更新。
下列範例提供韌體資源更新的範例驅動程式套件 INF 檔案定義,該更新目標為表 2 中 ESRT 範例中的 {SYSTEM_FIRMWARE} 資源,並將它從第 1 版更新為第 2 版。 為了方便參考,假設為SYSTEM_FIRMWARE資源指派的 GUID 是 6bd4efb9-23cc-4b4a-ac37-016517413e9a。
[Version]
Signature = "$WINDOWS NT$"
Provider = %Provider%
Class = Firmware
ClassGuid = {f2e7dd72-6468-4e36-b6f1-6488f42c1b52}
DriverVer = 01/01/2012,2.0.0.0
CatalogFile = catalog.cat
PnpLockdown = 1
[Manufacturer]
%MfgName% = Firmware,NTarm64.10.0...17134
; Prior to Windows 10, version 1803, the above should instead be:
; %MfgName% = Firmware,NTarm64
[Firmware.NTarm64.10.0...17134]
; Prior to Windows 10, version 1803, the above should instead be:
; [Firmware.NTarm64]
%FirmwareDesc% = Firmware_Install,UEFI\RES_{6bd4efb9-23cc-4b4a-ac37-016517413e9a}
[Firmware_Install.NT]
CopyFiles = Firmware_CopyFiles
[Firmware_CopyFiles]
firmware.bin
[Firmware_Install.NT.Hw]
AddReg = Firmware_AddReg
[Firmware_AddReg]
HKR,,FirmwareId,,{6bd4efb9-23cc-4b4a-ac37-016517413e9a}
HKR,,FirmwareVersion,%REG_DWORD%,0x00000002
HKR,,FirmwareFilename,,%13%\firmware.bin
; Prior to Windows 10, version 1803, the above should instead be:
; HKR,,FirmwareFilename,,{6bd4efb9-23cc-4b4a-ac37-016517413e9a}\firmware.bin
[SourceDisksNames]
1 = %DiskName%
[SourceDisksFiles]
firmware.bin = 1
[DestinationDirs]
DefaultDestDir = 13
; Prior to Windows 10, version 1803, the above should be:
; DefaultDestDir = 10,Firmware\{6bd4efb9-23cc-4b4a-ac37-016517413e9a}
[Strings]
; localizable
Provider = "Contoso Ltd."
MfgName = "Fabrikam Inc."
FirmwareDesc = "Fabrikam System Firmware 2.0"
DiskName = "Firmware Update"
; non-localizable
REG_DWORD = 0x00010001
變更下列各節以自定義您的設定。
[Version]
DriverVer --> The date on which this driver package was authored and the driver version of this driver package. Driver version in this driver package must be greater than the current driver version
CatalogFile --> Name of the catalog file
firmware.bin --> Change all instances of firmware.bin with the name of the firmware image name
[Manufacturer]
%MfgName% = Firmware,NTarm64.10.0...17134
[Firmware.NTarm64.10.0...17134] --> Change the architecture.
For x86, it should be NTx86
For AMD64, it should be NTamd64
[Firmware.NTarm64.10.0...17134]
%FirmwareDesc% = Firmware_Install,UEFI\RES_{6bd4efb9-23cc-4b4a-ac37-016517413e9a} --> The GUID of the firmware resource
[Firmware_AddReg]
HKR,,FirmwareId,,{6bd4efb9-23cc-4b4a-ac37-016517413e9a} --> The GUID of the firmware resource
HKR,,FirmwareVersion,%REG_DWORD%,0x00000002 --> Version of the firmware for the update
HKR,,FirmwareFilename,,%13%\firmware.bin --> firmware.bin should be replaced with the firmware image name
; Prior to Windows 10, version 1803, the above should instead be:
HKR,,FirmwareFilename,,{6bd4efb9-23cc-4b4a-ac37-016517413e9a}\firmware.bin --> The subdirectory named after the GUID of the firmware resource and the firmware image name
[DestinationDirs]
DefaultDestDir = 13 --> The full destination path as a 'run from Driver Store' binary
; Prior to Windows 10, version 1803, the above should be:
; DefaultDestDir = 10,Firmware\{6bd4efb9-23cc-4b4a-ac37-016517413e9a} --> The full destination path for the firmware image file based under a subdirectory named after the GUID of the firmware resource within the %SystemRoot%\Firmware directory
[Strings]
; localizable
Modify any strings here [optional]
下表描述各種驅動程式套件 INF 區段和欄位,並參考上述範例驅動程式套件 INF 檔案定義。
區段/欄位 | 值 | 註解 |
---|---|---|
[版本] | 定義驅動程式套件版本設定資訊。 | |
提供者 | %Provider% = Contoso Inc. (在 [Strings] 區段中本地化) |
識別整個韌體資源更新驅動程式套件的提供者/廠商。 |
Class/ClassGuid | 韌體/ {f2e7dd72-6468-4e36-b6f1-6488f42c1b52} |
指定驅動程式套件的日期。 日期與版本應盡可能反映實際韌體資源更新的日期與版本,以確保 PnP 裝置安裝系統能夠精確地選取系統上可用的最佳驅動程式套件。 |
CatalogFile | catalog.cat | 指定簽署驅動程式套件 INF 檔案和所有相關聯韌體資源更新二進位檔的相關聯類別目錄檔案。 |
PnpLockdown | 1 | 啟用 PnP 驅動程式檔案鎖定機制,以保護已安裝的驅動程式檔案不受不相關的應用程式外部修改。 針對韌體資源更新,應該一律啟用此設定,以確保韌體資源映像檔案無法竄改 PnP 系統控制外部 |
[製造商] | 列出定義韌體資源更新的所有相異驅動程式製造商/廠商。 每個製造商行都會指定 [<Models>] 區段,並識別其支援的目標平臺。 | |
%設定名稱% | Fabrikam Inc. (在 [Strings] 區段中本地化) |
識別韌體資源更新的製造商/廠商。 這可能與 [提供者] 欄位相同。 |
固件 NTarm64.10.0...17134 |
識別定義此驅動程式套件所支援的韌體資源裝置的 [<Models>] 區段,包括其目標驅動程序平臺。 在此範例中,驅動程式只會以適用於 Windows 10 組建 17134 和更新版本的 Arm64 型 NT 平臺為目標,而 [<Models>] 區段是 [Firmware.NTarm64.10.0...17134]. | |
[Firmware.NTarm64.10.0...17134] | 適用於 Windows 10 組建 17134 和更新版本的 Arm64 型 NT 平臺的 [<模型>] 區段,其中列出已定義更新的所有韌體資源裝置。 每個硬體模型行都會指定 [<DDInstall>] 區段及其相關聯的硬體標識符相符專案。 | |
%FirmwareDesc% | Fabrikam 系統韌體 2.0 (在 [Strings] 區段中本地化) |
描述韌體資源更新。 這是用來在 裝置管理員 和其他裝置相關 UI 中呈現相關聯韌體資源裝置實例的主要描述字串。 因此,描述可能包含韌體廠商和版本。 |
Firmware_Install, UEFI\RES_{RESOURCE_GUID} |
識別 [<DDInstall] 區段,其中包含以 UEFI\RES_{RESOURCE_GUID} 硬體標識碼所識別之裝置實例為目標的韌體資源更新安裝步驟。 其中 RESOURCE_GUID 是要更新之韌體資源的 GUID。 | |
[Firmware_Install.NT] CopyFiles = Firmware_CopyFiles [Firmware_CopyFiles] ... |
[<DDInstall>] 區段,其中包含韌體資源更新的安裝步驟。 針對韌體資源更新,這隻會定義韌體資源映像檔,以就地複製韌體資源更新。 在此範例中,[<DDInstall>] 區段是 [Firmware_Install.NT]。 | |
firmware.bin | 指定要複製的韌體資源更新映像檔。 如需複製此檔案的詳細數據,請參閱下方的 [DestinationDirs] 一節。 | |
[Firmware_Install.NT.Hw] AddReg = Firmware_AddReg [Firmware_AddReg] ... |
[<DDInstall>.Hw] 區段,其中包含韌體資源更新的硬體特定安裝步驟。 針對韌體資源更新,這會以目標裝置實例裝置硬體機碼底下設定的登錄值形式定義韌體資源更新組態資訊。 | |
FirmwareId | {RESOURCE_GUID} | 韌體資源更新的韌體 GUID。 請注意,這是內嵌在 UEFI\RES_{RESOURCE_GUID} 硬體識別碼中的相同韌體資源 GUID,不過它必須在此指定為獨立值,因為 PnP 系統會將所有硬體識別碼視為嚴格用於裝置/驅動程式比對用途的不透明字符串。 |
FirmwareVersion | 0x00000002 | 韌體資源更新的韌體版本,指定為REG_DWORD值。 |
FirmwareFilename | %13%\firmware.bin | 在 Windows 10 版本 1803 和更新版本上,這應該是「從驅動程式存放區執行」檔案,並提供範例中二進位檔的完整路徑,例如 。 在 Windows 10 1803 版之前,這應該是韌體資源更新之更新更新的更新頭檔映像檔名在 %SystemRoot%\Firmware 目錄下的相對路徑和韌體檔檔名,如此 {RESOURCE_GUID} 代表用來組織特定韌體資源之所有韌體映射檔的子目錄。 例如,{RESOURCE_GUID}\firmware.bin。 |
[SourceDisksNames] | 列出所有不同的驅動程式套件來源磁碟位置,其中包含相關聯的驅動程式檔案,例如韌體更新資源映像檔。 | |
1 | %DiskName% = 韌體更新 (在 [Strings] 區段中本地化) |
指定任意編號的驅動程式套件來源磁碟識別碼及其描述名稱。 未指定選擇性驅動程式套件相對子目錄,因此任何與此磁碟標識符相關聯的驅動程式檔案,例如韌體資源更新映像檔,應該會直接在 INF 檔案旁邊。 |
[SourceDisksFiles] | 列出驅動程式套件參考的所有驅動程式檔案,並將其連結至 [SourceDisksNames] 區段中的磁碟標識符。 | |
firmware.bin | 1 | 建立 firmware.bin 韌體資源更新映射檔作為驅動程式套件的一部分,方法是將它與主要磁碟標識符連結。 未指定選擇性檔案特定子目錄,因此此驅動程式檔案預期會與其磁碟標識碼的子目錄相對上線,在此案例中位於 INF 檔案旁邊。 |
[DestinationDirs] | 列出驅動程式套件所參考之所有驅動程式檔案的目標目的地目錄。 | |
DefaultDestDir | 13 | 指定此驅動程式套件所複製之所有驅動程式檔案的預設目的地目錄。 在 Windows 10 版本 1803 和更新版本上,這應該是 DIRID 13,讓檔案「從驅動程式存放區執行」。 在 Windows 10 版本 1803 之前,這應該是 10,Firmware\{RESOURCE_GUID} 指定所有檔案的目的地位於 %SystemRoot%\Firmware 之下,其中 10 個 (DIRID_WINDOWS) 代表基底 %SystemRoot% 目錄,而 {RESOURCE_GUID} 代表以韌體資源 GUID 命名的子目錄。 |
[字串] | 定義驅動程式套件 INF 檔案中所有間接字串標記的索引鍵/值對應, (%token%) 。 使用字串標記可藉由引進地區設定特定的 [Strings],輕鬆地當地語系化驅動程式套件 INF 檔案。<LanguageID>] 區段。 您也可以使用字串令牌替代來定義常數值,例如REG_DWORD。 | |
提供者 | “Contoso Ltd.” | 字串令牌索引鍵/值對應的範例。 |
請務必針對每個韌體資源更新映像檔版本使用唯一的名稱,以避免與其他韌體映像檔發生任何潛在衝突,包括您自己的和來自其他韌體廠商的檔案。 例如,應將上述 的 firmware.bin 指派為符合廠商名稱和版本條件約束的下列名稱: Fabrikam-System-Firmware-2.0.bin。
為了確保特定韌體資源更新映像的變體可能用於 OEM/IHV 自定義用途,請勿在部署到相同的 Windows 系統映射時發生衝突,建議每個不同的韌體資源更新映像都是在 %SystemRoot%\Firmware 目錄中的子目錄中執行 (Windows 10 版本 1803 和更新版本) 或維護。 此子目錄應該以目標韌體資源 GUID 命名。 例如,下列韌體資源更新映射路徑符合部署條件約束: %SystemRoot%\\Firmware\\{6bd4efb9-23cc-4b4a-ac37-016517413e9a}\\Fabrikam-System-Firmware-2.0.bin
。
測試簽署韌體驅動程式套件
驅動程式套件 INF 檔案和韌體承載二進位檔就緒之後,必須簽署整個驅動程式套件,才能產生類別目錄檔案。 此類別目錄檔案必須保證驅動程式套件內所含 INF 檔案和韌體承載二進位檔的有效性和真確性,才能讓 Windows 安全地起始韌體資源更新。
以下列舉了自我簽署驅動程式套件以供測試之用的步驟。 請注意,這些步驟僅供測試之用。 在生產環境中,韌體更新驅動程式套件必須提交至合作夥伴中心進行簽署。 如需簽署生產環境的韌體驅動程式套件的步驟,請參閱 認證和簽署更新套件。
安裝最新的 Windows SDK 和 Windows 驅動程式套件。 這會在 底下
%systemdir%\Program Files (x86)\Windows Kits\<*version*>\bin\x86
安裝 makecert、pvk2pfx inf2cat 和 signtool 工具。執行下列命令以建立測試證書。
makecert.exe -r -pe -a sha256 -eku 1.3.6.1.5.5.7.3.3 -n CN=Foo -sv fwu.pvk fwu.cer pvk2pfx.exe -pvk fwu.pvk -spc fwu.cer -pi <Password entered during makecert prompt> -spc fwu.cer -pfx fwu.pfx
如需詳細資訊,請參閱 MakeCert。
執行下列命令以建立類別目錄檔案。
Inf2Cat.exe /driver:"." /os:8_x64
/driver 自變數會指向 INF 所在的位置。 根據韌體驅動程式套件所適用的OS,變更 /os 自變數的值。 如需詳細資訊,請參閱 Inf2Cat。
如需安全性類別目錄和驅動程式的詳細資訊,請參閱類別目錄 檔案和數位簽名 和 建立 PnP 驅動程式套件的類別目錄檔案。
執行下列命令來簽署類別目錄檔案。
signtool sign /fd sha256 /f fwu.pfx /p <Password entered during makecert prompt> delta.cat
如需詳細資訊,請參閱 SignTool。
在測試系統上安裝測試憑證:
按兩下 fwu.cer 檔案,然後選擇 [ 安裝憑證 ] 選項。
在憑證安裝期間選擇下列選項:
針對 [市集位置],選擇 [ 本機計算機]。
針對 [證書存儲],流覽並選取 [ 受信任的跟證書授權單位]。
停用韌體/BIOS 選項中的安全開機。
啟用 BCD 選項中的測試簽署,讓 OS 載入器可以在開機期間載入韌體映像檔 (firmware.bin) ,即使目錄未經過生產簽署也一樣。 使用系統管理員權限執行下列命令:
bcdedit /set testsigning on
簽署驅動程式套件之後,可以使用下列其中一種機制進行安裝:
裝置管理員。 針對手動測試,裝置管理員 提供易記的介面,可用來尋找韌體資源裝置並更新其驅動程式,以起始韌體資源更新。
依類型檢視裝置時,或在依連線檢視裝置時,在 [Microsoft UEFI-Compliant 系統] 裝置下,於 [韌體] 類別下找出所需的韌體資源裝置。
以滑鼠右鍵按兩下韌體資源裝置,然後選取 [更新驅動程式軟體...]選項。
使用 [流覽我的計算機以取得驅動程式軟體] 選項,在韌體資源裝置上尋找並安裝較新的韌體資源更新驅動程式套件。 這項作業可確保指定的韌體資源更新驅動程式套件實際上比任何可能已在韌體資源裝置上的現有韌體資源更新驅動程式套件還要新,再將其新增至 Windows 驅動程式市集並起始安裝。
pnputil。 針對自動化測試, PnpUtil 命令行公用程式可從系統管理員提升許可權的命令提示字元使用,將韌體資源更新驅動程式套件匯入 Windows 驅動程式存放區,並在目前使用舊版韌體資源版本的任何/所有適用的韌體資源裝置上起始裝置安裝,如目前已安裝驅動程式套件 INF 檔案的 DriverVer 所建立,或缺少第三方提供的驅動程式套件 INF 檔案完全。 例如,使用下列命令行來新增並安裝 X:\firmware.inf:
pnputil -i -a X:\firmware.inf
如果韌體資源更新已成功安裝在韌體資源裝置上,並且提供比目前韌體版本更高版本的韌體資源更新,則裝置會等候系統重新啟動才能完成更新作業。 處於此狀態的裝置會藉由維護裝置問題來指出系統重新啟動的需求,這可防止裝置啟動並還原到穩定狀態,直到執行重新啟動為止。
驗證韌體更新的狀態
成功安裝韌體驅動程式套件時,PnP 會要求系統重新啟動以套用更新。 重新啟動后,可以驗證更新的狀態。 更新的狀態會保留在下列登錄機碼之下: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FirmwareResources\{RESOURCE_GUID}
。
RESOURCE_GUID是從 ESRT) 更新的資源 (GUID。
“LastAttemptStatus” 登錄值表示韌體更新的狀態,其中值為 0 表示成功,而任何非零值都代表失敗。 此登錄機碼的值是根據ESRT中LastAttemptStatus的值,由OS Loader 填入NTSTATUS代碼。 下表會將 LastAttemptStatus 程式代碼對應至其對應的 NTSTATUS 程式代碼。
LastAttemptStatus | 程式碼 | NTSTATUS | 程式碼 |
---|---|---|---|
Success | 0 | STATUS_SUCCESS | 0x00000000 |
錯誤:失敗 | 1 | STATUS_UNSUCCESSFUL | 0xC0000001 |
錯誤:資源不足 | 2 | STATUS_INSUFFICIENT_RESOURCES | 0xC000009A |
錯誤:版本不正確 | 3 | STATUS_REVISION_MISMATCH | 0xC0000059 |
錯誤:無效的影像格式 | 4 | STATUS_INVALID_IMAGE_FORMAT | 0xC000007B |
錯誤:驗證錯誤 | 5 | STATUS_ACCESS_DENIED | 0xC0000022 |
錯誤:電源事件、AC 未連線 | 6 | STATUS_POWER_STATE_INVALID | 0xC00002D3 |
錯誤:電源事件、電池不足 | 7 | STATUS_INSUFFICIENT_POWER | 0xC00002DE |
韌體資源裝置節點的硬體標識碼屬性也應該反映韌體版本的變更,其中 XXX 是新的韌體版本。
- UEFI\RES_{RESOURCE_GUID}&REV_XXX
如果韌體更新失敗,您可以重試失敗的韌體更新:
在 [裝置管理員] 中,展開 [韌體] 節點,以滑鼠右鍵按兩下韌體資源裝置,然後按兩下 [更新驅動程序軟體]。
按兩下 [瀏覽我的電腦以取得驅動程式軟體],然後在下一頁按兩下 [ 讓我從電腦上的設備驅動器清單挑選]。
選取您先前安裝的相同驅動程式,然後按兩下 [確定]。
下次重新啟動之後,OS Loader 會呼叫具有韌體驅動程式套件承載的 UpdateCapsule () 。