Archive for 2014/09/23

OS の起動時間短縮(1/2)~RAM レジストリの初期化時間を短縮する

■はじめに
今回と次回は、WEC の起動時間を短縮する方策を、二つ紹介します。WEC 2013 では、Snapshot Boot が導入され、適切に実装・チューニングすれば、OS の起動時間を数秒以内に抑えることも可能になりました。しかし、WEC 2013 よりも前の版では、Snapshot Boot を行うことができません。そこで、WEC 7 でも対応可能な起動時間短縮の方策を紹介してみることにしました。なお、Snapshot Boot については、MSDN の次のページをご覧ください。

 Snapshot Boot Development (Compact 2013)
 http://msdn.microsoft.com/en-us/library/dn169259.aspx

日本国内の Windows Embedded MVP 有志が主催して不定期に開催している、「Windows Embedded Community Day」の第1回で僕が担当したプレゼンでも、Snapshot Boot について簡単に紹介しています:

 組み込みでもマルチコア。WEC2013 での対応
 http://www.slideshare.net/ShinyaKoga/2013-0719wemvp-kansai

 Windows Embedded Community Day 第 1 回 – 真夏の組み込み Windows 技術セミナー2013
 http://msdn.microsoft.com/ja-jp/dn521045

■RAM レジストリの初期化
2011/08/02 に書いたエントリ(「レジストリの永続化~RAM-Based の場合」)では、レジストリの永続化対応を行う場合、Hive-Based のレジストリよりも、RAM-Based のレジストリの方が、より堅牢だと述べました。しかし、RAM-Based のレジストリには、起動時間が長くなるという短所があります。これは、レジストリの初期化に要する時間が、RAM-Based のレジストリの方が長いことが要因のようです。

Hive-Based のレジストリは、レジストリの Hive ファイルを filesys.dll が memory mapped file としてオープンして内容にアクセスします。つまり、Hive ファイルの内容は、filesys.dll が RAM 上に構築するレジストリ(一種のオンメモリデータベース)と同じではないかと思われます。従って、OS の起動時にレジストリを初期化する動作というのは、OS イメージに収録されている Hive ファイルや、内容更新されて永続化記憶域(ストレージ)に配置された Hive ファイルを、単に memory mapped file としてオープンするだけなのでしょう。

一方、RAM-Based のレジストリは、filesys.dll が RAM 上に構築するレジストリとは内容(フォーマット)が異なるようです。このため、OS の起動時にレジストリを初期化する際、ストレージからレジストリデータを読み出し、その内容を解析して RAM 上にレジストリを構築する、という処理が必要になります。このため、レジストリの初期化に要する時間が長くなるのです。この時間は、レジストリ全体のサイズに依存しますから、一般的には、OS イメージに組み込む機能が多いほど、つまり、OS Design のカタログ項目の選択が多いほど長くなります。10秒以上に達することがあることを確認していますし、永続化した場合は、レジストリの初期化時間の合計で20秒を超える場合もあります。

■永続化された場合の RAM レジストリの初期化
上で、「永続化した場合は」と書きました。そうです。RAM レジストリを永続化した場合、永続化しない場合よりも、レジストリの初期化に要する時間が長くなるのです。これについては、2011/08/02 に書いたエントリでも紹介した、WinCE 6.0 のリファレンスにある、次のページの説明にヒントがあります。

 File System Initialization of RAM-based Registry (Windows Embedded CE 6.0)
 http://msdn.microsoft.com/en-US/library/ee490364(v=winembedded.60).aspx

このページには、RAM-based レジストリの初期化の流れが説明されているのですが、1から8まであるステップのうち、5と6は、次の通りです:

  1. Filesys.dll initializes the registry by checking for a registry in RAM.
    If Filesys.dll does not find a registry in RAM, it restores the registry from ROM. Filesys.dll loads \Windows\Default.fdf, which was created using Makeimg.exe.
  2. Filesys.dll checks for the ReadRegistryFromOEM OEM adaptation layer (OAL) function. If Filesys.dll does not find ReadRegistryFromOEM, it keeps the registry restored from ROM.

つまり、OS イメージ(ROM イメージ)に収録されている Default.fdf というファイル内容をロードして初期化した後、OAL の ReadRegistryFromOEM() を(それが実装されていれば)呼び出し、ストレージに保存されたレジストリデータをロードして初期化し直す、というわけです。つまり、RAM-Based のレジストリを永続化した場合、レジストリの初期化処理が実質二回行われるのです。

■永続化された RAM レジストリの初期化時間を短縮
RAM-Based のレジストリを永続化した場合に、永続化しない場合よりもレジストリの初期化に要する時間が長くなるのは、レジストリの初期化処理が二回行われるからなのです。これを、一回にすることができれば、そのぶん起動時間を短縮できることになります。何かよい方法はないでしょうか?

あります。それは、2012/01/13 に書いたエントリ(「OS の部分アップデート方策~その2(2/2)」)で述べた、ROM イメージを複数に分割することです。このエントリで、ROM イメージを複数の region に分割した場合、同じ名前(パス)のファイルに対して、region 間で shadowing が作用すると書きました(※「Region ごとの部分アップデート」という項をご覧ください)。この shadowing を利用するのです。

方策は、次の通りです:

1.) OSDesign.reg において、最小限の内容(たとえば、[HKLM\init] キーだけ)が有効になるように設定して OS イメージをビルドして、生成された Default.fdf ファイルを採取する。

2.) (1) で採取した Default.fdf ファイルのみを収録する ROM イメージの region を作成する。
 これは、config.bib によるメモリマップの設定と、ブートローダによる複数 region のロード、および、OAL による複数 region の連結処理(OEMRomChain のリスト構築処理)が必要です。

3.) 通常のビルド時は、(1) の設定を解除して OS イメージをビルドする。
 この結果、本来のレジストリ設定内容は、OS 本体を収録した region(NK region)に Default.fdf という内容で収録され、(1) で作成した(最少サイズの)Default.fdf は、それ専用の region に収録されます。

4.) OAL における OEMRomChain のリスト構築処理を実行する前に、ストレージ上にレジストリデータが存在するかどうかをチェックし、存在しない場合は、OEMRomChain のリスト構築処理において、Default.fdf のみを収録した region を無視する。ストレージ上にレジストリデータが存在する場合は、Default.fdf のみを収録した region を、OEMRomChain のリストにおいて、OS 本体を収録した region よりも前に配置する。

この方策により、ストレージ上にレジストリデータが存在する場合は、(1) で作成した最小限の Default.fdf ファイルの内容で一回目のレジストリ初期化が実行され、その時間を最小限(相対的に 0)にできます。その後、ストレージに保存されたレジストリデータがロードされ、レジストリが初期化される、というわけです。

ストレージ上にレジストリデータが存在しない場合は、(1) で作成した最小限の Default.fdf ファイルを収録した region は OEMRomChain のリストには挿入されませんから、shadowing が行われず、OS 本体を収録した region(NK region)に収録された、通常の Default.fdf がロードされてレジストリが初期化されます。従って、レジストリを一度もストレージに保存していない場合や、ストレージに保存したレジストリデータを無効化した場合にも、問題なく動作します。上記方策を適用しない場合の動作と比べて、起動時間が短縮される以外は、見た目の動作は変わりません。

Add comment 2014/09/23 koga


Categories

Links

Posts by Authors

Recent Posts

Calendar

2014年9月
« 8月   2月 »
 123456
78910111213
14151617181920
21222324252627
282930  

Posts by Month

Posts by Category

Meta