Archive for 2011/08/02

レジストリの永続化~RAM-Based の場合

2011/02/21 に書いたエントリ(「レジストリ変更内容の永続化(2/2)」では、Hive-Based と RAM-Based の二種類があるレジストリのうち、Hive-Based のレジストリを永続化する仕組みについて説明しました。今回は、RAM-Based のレジストリの永続化について、Hive-Based のレジストリとの比較を交えて書きます。

まず、RAM-Based のレジストリを永続化する方法については、リファレンスの次のページに記載されています:

 http://msdn.microsoft.com/en-us/library/ee489958(v=WinEmbedded.60).aspx (Persisting Data with the RAM-Based Registry)
 http://msdn.microsoft.com/en-US/library/ee490769(v=WinEmbedded.60).aspx (Data Persistence with the RAM-based Registry Using the OAL)

実は、RAM-Based のレジストリを永続化する方法は二つあり、上の二つのページで、その各々について説明されています。それぞれの概要は、次の通りです。

(1) Oemregistry.dll という DLL を組み込む。この DLL で、ReadRegData(), WriteRegData(), RegistryOperation() を実装する。

(2) OAL (OEM Adaptation Layer) に、WriteRegistryToOEM() と ReadRegistryFromOEM() の実装を追加する。

これら二つの方法のうち、(1) は、永続記憶域としてファイルシステムを使う場合に適しています。一方、(2) は、NOR Flash の特定領域を割り当てるなどして、ファイルシステムを介さず、生の(raw)ストレージメディアにレジストリ内容を保存する場合に適しています。

どちらの場合も、レジストリの変更内容を永続記憶域に保存するためには、RegFlushKey() の呼び出しが必要です。Hive-Based のレジストリとは異なり、RAM-Based のレジストリでは、RegFlushKey() を呼び出さない限り、レジストリの変更内容は保存されません。

さて、上記 (1) と (2) のどちらも、WinCE 6.0 ではサンプル実装が提供されています。(1) は、リファレンスのページでも紹介されているように、%_WINCEROOT%/Public/Common/Oak/Drivers/FSD/Oemfs/ がサンプル実装です。このサンプル(Oemfs)では、永続記憶域として、リリースディレクトリファイルシステムを使用します。つまり、開発ホスト機の Flat Release Directory に、RAM-Based レジストリの内容がファイルとして保存されます。当然ですが、使用する場合は、OS Design のカタログ項目で、「リリースディレクトリファイルシステム」を選択して OS イメージをビルドしなければいけません。また、サンプルのままでは、ビルドの target name が Oemfs になっており、’Oemregistry’ とは違います。さらに、他の Public/ ディレクトリ配下のコンポーネントと同様、target type が LIBRARY になっていて、一旦 static library (.lib) としてビルドされた後、sysgen 変数でビルド対象に設定された場合にのみ、DLL (.dll) が生成されるように sources ファイルが記述されています。従って、sources ファイルを作り直し、target name を Oemregistry、target type を DYNLINK にする必要があります。

(2) のサンプル実装は、%_WINCEROOT%/Platform/Common/Src/Common/PerReg/ です。このソースから、oal_perreg.lib という static lilbrary がビルドされます。NOR Flash を搭載したボードの BSP で、NOR Flash に対する OALFlashErase() と OALFlashWrite() が実装されている場合には、oal_perreg.lib を oal.exe のリンクライブラリに追加して、PerReg の初期化関数を OAL の初期化時に呼び出せば(※OEMInit() の末尾がよいでしょう)、そのまま使用することができます。そのようにして oal_perreg.lib を組み込むだけで、NOR Flash の特定領域を使った永続化が、RAM-Based レジストリに対して可能になります。PerReg の初期化関数は、%_WINCEROOT%/Platform/Common/Src/INC/oal_perreg.h で宣言されている OALPerRegInit() です。

ところで、ここまで見てきて、レジストリを永続化する方法には、次の三つがあることが分かりました:

(a) Hive-Based のレジストリを組込み、永続化の設定を行う。

(b) RAM-Based のレジストリと Oemregistry.dll を組み込む(※配置先ファイルシステムは、適切に変更する必要あり)。

(c) RAM-Based のレジストリを組込み、OAL に WriteRegistryToOEM() と ReadRegistryFromOEM() の実装を追加する。

どれが最も良いのでしょうか?結論としては、WinCE 6.0 を動かすハードウェア次第であり、ケースバイケースだと言えます。ただし、NOR Flash を搭載したハードウェアであり、かつ、レジストリの書き換えが頻繁には起こらず、あらかじめ意図した変更内容だけを永続記憶域に保存したい場合には、(c) の方法が最も良いのではないかと思います。

なお、WinCE 6.0 のリファレンスを見ると、次のように書かれています:

 ”The preferred method for persisting registry data is to use the hive-based registry.”
 (Persisting Data with the RAM-Based Registry

 ”The preferred method for persisting data with the RAM-based registry is to include the OEMRegistry.dll sample file in your OS image.”
 (Data Persistence with the RAM-based Registry Using the OAL

これを見ると、最も preferred なのが (a)、その次が (b) で、最後が (c) という順番です。しかし、ここで言う “preferred” の順番は、堅牢性の観点から推奨されるものではなく、より一般的に使える方策の順、および、OS のカスタマイズが必要な度合いが小さい順であると思います。以下に、(a)~(b) の各々について、長所・短所を述べます。

 (a) Hive-Based のレジストリ
  長所:OS のカスタマイズは最小限。「レジストリ変更内容の永続化(2/2)」 で説明したように、OS イメージに組み込むレジストリの設定だけで対応できる。

  短所:レジストリの Hive を配置するファイルシステムを Bootable に設定しなければならないため、そのファイルシステムが破損するなどしてマウントできなくなった場合、ブートの第2フェーズへ遷移できず、第1フェーズの完了待ちで WinCE カーネルの起動が停止してしまう。

  その他:レジストリの Hive ファイルが、WinCE によってオープンされたままとなる。このため、WinCE の起動後にバックアップファイルで上書きするといったことができない。また、RegFlushKey() を呼び出さなくても、暗黙裡に Hive ファイルが更新されるため(※試してみたところでは、起動のたびに、ファイルが更新されます)、レジストリ内容の永続記憶域への書き出しを、意図したタイミングでしか行いたくない場合には、不向き。

 (b) RAM-Based のレジストリ + Oemregistry.dll
  長所:Oemregistry.dll を組み込むだけで対応でき、OAL の改変が不要。レジストリ内容を、ファイルシステム上にファイルとして保存するが、そのファイルシステムは Bootable に設定する必要がない。そのため、保存先のファイルシステムが破損しても、WinCE は起動する。

  短所:レジストリ内容をファイルとして保存するため、レジストリ内容を隠したい場合には不向き。

 (c) RAM-Based のレジストリ + OAL に WriteRegistryToOEM() と ReadRegistryFromOEM() を追加
  長所:レジストリ内容は、ファイルシステムを介さずに保存できるため、ユーザから隠して保護するのが容易。また、NOR Flash を搭載したハードウェアであれば、NOR Flash 用のサンプル実装(PerReg)をそのまま使える。

  短所:OAL の改変が必要。NOR Flash を搭載していないハードウェアの場合には、WriteRegistryToOEM() と ReadRegistryFromOEM() の実装は、それなりに手間がかかる。

どうでしょうか?それぞれの長所と短所は、相対的なものですから、どれかが絶対的に優れているとはいえず、ケースバイケースだと思います。

たとえば、ハードディスク(や SSD)を搭載し、そこに OS イメージも配置する設計のデバイス(ハードウェア)であれば、(a) が最も適しているでしょう。あるいは、上述したように、NOR Flash を搭載していて、レジストリの更新内容を特定の場合にしか保存しなくてよい仕様のデバイスであれば、最も適しているのは (c) だと思います。また、CF カードなどのストレージメディアに Bootable なファイルシステムを置くデバイスで、Bootable なファイルシステムへの書き込みを極力抑えたい、という場合には、(b) が適しているのではないかと思います。

※2011/08/13 追記
RAM-Based のレジストリを永続化した場合、OS イメージを書き換える際に問題となることがあります。新しい OS イメージで、レジストリ項目の追加や削除など、レジストリ内容の変更を行っていても、OS イメージを書き換えた際に、その変更が反映されない、という問題です。これについて、「RAM-Based レジストリの永続化に関する補足」に書きました。

2 comments 2011/08/02 koga


Categories

Links

Posts by Authors

Recent Posts

Calendar

2011年8月
« 2月   9月 »
 123456
78910111213
14151617181920
21222324252627
28293031  

Posts by Month

Posts by Category

Meta