DXR165の備忘録

自分用の備忘録です。

Windows API GetFirmwareEnvironmentVariableでUEFI BootOrder変数にアクセス  

UEFI BootOrder変数はUEFI Shell コマンドのDmpstore やBCFGで参照・メンテが可能ですが、ブートしなおして、USBメモリ挿して等操作が少々面倒です。Windows からアクセスする方法は以下があります。

BCDEdit 
標準コマンドですが、BCDがからんで使いずらい。また、その情報も抽象化され不十分。

EASYUEFI
GUIツールです。機能限定でフリーで使えますが、仕様が不明。

そこで、ネットを探索していると以下の記事がありました。
powershellからNVRAMよむやつ
yomi322.hateblo.jp/entry/2016/05/01/205936

Windows API(GetFirmwareEnvironmentVariable)とPowerShellでアクセスできるようです。

実際にやってみました。
実証環境 
ASUS H270-PLUS BIOS Ver 0311 UEFI Spec Ver 2.50
Intel Celeron G3900 
Win 10 Home 64bit Ver 1607(Redstone 1)


手順
・まず、PowerShell ISEを管理者権限で使えるようにする。
Win 7以降では標準で入ってる。

・コマンドが実行できるように以下を実行
Set-ExecutionPolicy RemoteSigned(実行ポリシーの変更?→はい)

・スクリプトをコピペし、ファイルに保存し実行する。


すると

実行結果↓
PS C:\windows\system32> C:\Users\XXX\Documents\bootorder.ps1
00 00 01 00 
BootOrderのダンプが吐き出さられる。

UEFIの仕様ではBootOrdeは2バイト整数の配列となっています。
また、バイトオーダーはx64マシンなのでリトルエンディアンになります。
なので、2番目の01 00は00 01の並びになります。
解析すると
BootOrder Priority
1番目はBoot0000
2番目はBoot0001
となります。


コード解説
AdjustPrivileges()関数は
アクセス権等をチェックしている模様。管理者権限であれば通過する。

BootOrder()関数は
これが肝心の本体です。ここをいじくればよいようです。
GetFirmwareEnvironmentVariableでBootOrderを読み込みバッファにためます。バッファサイズは0x100で決め打ち。
GUIDはUEFI Global VariableのGUIDをセット


応用ーBootOption####を読んでみる!


BootOption####を読むには、すでに####が判明しているので簡単です。BootOption####はEFI_LOAD_OPTION descriptorを含みます。読めますが、しかし、その構造はちょっと難しい作りです。

EFI_LOAD_OPTION descriptor
typedef struct _EFI_LOAD_OPTION {
UINT32 Attributes ;
UINT16 FilePathListLength;
CHAR16 Description[];
EFI_DEVICE_PATH_PROTOCOL FilePathList[];
UINT8 OptionalData[];
} EFI_LOAD_OPTION;
(出典:UEFI Specification 2.5 / 3 Boot Manager 3.1.3 Load Options)

FilePathList[]のバイト長がFilePathListLengthにセットされています。

今日はここまでで力尽きました。続きはのちほど。

2017/02/17 やっと更新できます。

それでは、WIndows 10を起動するBootOption0000を実際に読んでみます。
上記の構造の解説ですが、まず基本のところから。
DescriptionはこのBootOptionの名前です。 Windows Boot Managerがセットされていました。
FilePathListは不定繰返し配列のようです。そのパスの表現はEFI_DEVICE_PATH_PROTOCOLで定められています。そのバイト長はFilePathListLengthに格納されています。
OptionalDataにセットされたデータは起動するアプリケーション(例 Windows Boot Manager)に渡されるようです。このOptionalDataについては詳細はよくわかりません。
Attributesは基本的にLOAD_OPTION_ACTIVE 0x00000001がセットされているようです。


EFI_DEVICE_PATH_PROTOCOL
いろいろ細かい仕様があるようですが、ブートローダー起動用Pathは以下の3つでよいようです。

1.Hard Drive Media Device Path
Type 4 – Media Device Path 0x04
Sub-Type 1 – Hard Drive 0x01
Length  0x2A 0x00 (LE)固定
Partition Number 
Partition Start
Partition Size 
Partition Signature ここに該当パーティションのUniquePartitionGUIDがはいっています。
Partition Format  – GUID Partition Table 0x02
Signature Type  – GUID signature 0x02
(出典:UEFI 2.5 / 9 Protocols - Device Path Protocol 9.3.6 Media Device Path)

ポイント! このUniquePartitionGUIDにより複数のパーティションがある場合でも、該当デバイスを特定できる。

UniquePartitionGUIDとは
GUID Partition Table (GPT) DiskのPartition TableはGPT HeaderとGPT Partition Entry Arrayで構成される。
GPT Partition Entry Arrayは
PartitionTypeGUID ESPはxxxといった決まりがある。
UniquePartitionGUID パーティションを作成したときにUEFI GUIDを生成し格納
StartingLBA
EndingLBA
Attributes
PartitionName
で構成される。
(出典:UEFI 2.5 / 5 GUID Partition Table (GPT) Disk Layout 5.3.3 GPT Partition Entry Array)

UEFIのGUID(Globally Unique Identifiers)はRFC 4122のタイムスタンプとMACアドレスを使うタイプの仕様を使うようです。 注意{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}緑の部分のバイトオーダーはリトルエンディアンです。
(出典:UEFI 2.5 / Appendix A GUID and Time Formats)


2.File Path Media Device Path
Type 4 – Media Device Path 0x04
Sub-Type 4 – File Path 0x04
Length 
Path Name ここに起動するブートローダーのパスが入る。
今回は\EFI\MICROSOFT\BOOT\BOOTMGFW.EFI が入っていました。
(出典:UEFI 2.5 / 9 Protocols - Device Path Protocol 9.3.6 Media Device Path)


3.Device Path End Structure
Type 0x7F –  End of Hardware Device Path
Sub-Type 0xFF – End Entire Device Path
Length 
(出典:UEFI 2.5 / 9 Protocols - Device Path Protocol 9.3.1 Generic Device Path Structures)

以上、BootOptionの保持する情報をおぼろげながら知ることができました。GPTパーティションの効用はシステムドライブに2Tバイト以上のディスクを使えること以上に、OSブート時にシステムドライブをUniquePartitionGUIDにより簡易に識別できることにあるようです。これを知ることができたの今回の収穫です。


参考URL
日経Linux Linuxキーワード UUID
http://itpro.nikkeibp.co.jp/article/Keyword/20090206/324330/
GUIDの簡単な仕組みとディスクの識別にUUIDを使うメリットなどが解説されている。


関連記事

category: PC-HW

tb: 0   cm: 0

コメント

コメントの投稿

Secret

トラックバック

トラックバックURL
→http://dxr165.blog.fc2.com/tb.php/365-984fe5e6
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

最新コメント

カウンター(2012/3/10以降)