
連載22-QEMUでハードウェアなし開発ー2
前回は、QEMUを使って、ハードウェアがない状態で開発する方法についてご紹介しましたが、書ききれなかった機能がまだまだあります。
今回はその中でも、以下についてご紹介します。
・32ビットCPUのサポート
・SOLID for QEMUのロード機能を試す
1.64ビットand 32ビット
SOLID for QEMUがエミュレートするCPUはARM Cortex-A53です。
ARMv8なので、64ビット命令(AArch64)です。
そしてこのARMv8、ARMv7との互換性もあります。
すなわち32ビット命令(AArch32)も動きます。
過去にAArch32で開発したアプリと互換性を保つため、です。
AArch64には、権限の異なった4つの実行レベルがあります。
EL0,1,2,3(EL=Exception Level:例外レベル)という名称がついています。

権限は、EL3が最強(上位レベル)、EL0が最弱(下位レベル)です。
(図の上下とレベルの上下が逆なので、筆者は頭が混乱します。)
上位レベルに遷移する方法:
専用の命令を使います。(かつ、上位レベルが受け付けることが必要)
EL0⇒EL1:SVC命令
EL1⇒EL2:HVC命令
EL1/EL2⇒EL3:SMC命令
下位レベルに遷移する方法:例外復帰
下位レベルに遷移する際に、64ビットモードなのか32ビットモードなのかを選ぶことができます。
例えば、EL1で動作するカーネルを32ビットモードで動かしたい場合、EL2からEL1に遷移する際に32ビットモードにすることができます。
ですので、逆方向の遷移(下から上)の際はビットモードを選べません。
上位レベルのビットモードは、そのまた上位レベルから遷移した時に既に決まっているものがあるので、そちらのモードで動作します。
ちなみに、実行レベルEL1には、OSとセキュアOSが想定されますが、空間が違うため(ノンセキュア空間、セキュア空間)違うビットモードで動作することができます。
すなわち、32ビットモードでビルドされたSOLID-OSとアプリを、ARM Cortex-A53上で動作させることができます。
これは、QEMU上でも同様です。
1.1 32ビット版を動かしてみる
では実際に32ビットモードでビルドされたSOLID-OSをQEMUで動かしてみましょう。
以下のサンプルソリューションを起動します。

構成マネージャーを見てみると、v7として構成されています。
すなわち、32ビットです。

ビルドし実行し、適当なところで停止してみます。

逆アセンブルウインドウを見ると、32ビットモードになっていますね。
ちなみに、前回試してみた64ビットのデモを再度実行して、逆アセンブルウインドウを見てみましょう。

逆アセンブルウインドウを見ると、確かに64ビットモードですね。
2.SOLID for QEMUのロード機能を試す
第17回から第20回でご紹介したロード機能もまた、SOLID for QEMUで動作します。
実機が完成する前に、事前に開発対象ソフトウェアの大枠を作っておけると便利ですね。
第18回で、ローダブルアプリの作成方法や、メインアプリへの組み込み方法等ご紹介しました。
ターゲットをQEMUにすれば、同じ事ができます。
ローダブルアプリを作成する際、以下のダイアログボックスにより、ソリューションプロパティファイルを選択しましたよね。

ここで、QEMUのメインアプリのワークスペース内にあるpropファイルを選択すればOKです。
その他の流れは、第18回でご紹介した通りです。
したがって、今回は、ローダブルモジュールをもつサンプルワークスペースがあるので、そちらで試してみます。
以下のフォルダのサンプルソリューションを起動します。

Main.cppから、SOLID独自形式ロードモジュールとDLL形式ロードモジュールが、それぞれロードされ関数がコールされています。

上記のように、それぞれのロードモジュール内関数をコールする箇所にブレークを設定してみました。
2.1ロードモジュールのビルド
まずビルドし、ロードモジュールを作らないといけませんね。
一旦SOLID-IDEを閉じ、ここからは各ロードモジュール用ワークスペースから起動します。
各ロードモジュール用ワークスペースは、以下のフォルダに入っています。

まず、DLL形式です。

dll-app.ptslnを実行しSOLID-IDEを起動し、ビルドします。

同様に、SOLID独自形式のロードモジュールについてもビルドします。


これで、必要なロードモジュールファイルが生成されました。
2.2 ローダブルモジュール関数にジャンプ
では再び、メインアプリ側のワークスペースを起動し、実行してみます。
先程設定した、一つ目のブレークポイントで停止しました。

ステップインします。

SOLID独自形式のロードモジュール内に遷移しました。
次に、このまま継続実行してみます。

二つ目のブレークポイントで停止しました。
ステップインします。

DLL形式のロードモジュール内に遷移しました。
SOLID独自形式、DLL形式、それぞれのロードモジュールがロードされ、関数が実行されました。
3.まとめ
今回は、SOLID for QEMUにおいて前回含まれていなかったポイントをご紹介しました。
今回ご紹介した2点とも、事前のソフトウェア開発という視点で有用な機能だと思います。
32ビットモードで動くので、過去のソフトウェア資産を流用して試すことができる。
ロード機能も実装できるので、事前にソフトウェア構造の検討がより進められる。
実際の開発はハードウェアが来てから、となることが多いかと思いますが、それまで事前にいろいろ検討ができると開発期間の短縮にもつながりますね。
さて、SOLIDの便利機能紹介も22回となり、何をご紹介したのかを忘れそうになっています。
という事で、次回はおさらいをしたいと思います。