見出し画像

連載2-SOLIDのMMU使いこなしー1

前回は、MMUを使う事によって可能となる、便利なデバッグ機能を少しご紹介しました。

これから、SOLIDの特徴を踏まえ、深堀をしていきます。


1.MMUは怖い?

筆者は、ルネサス製(当時は日立製作所製)SH-4シリーズで、初めてMMUに触れました。

最初は、何が便利なのかよくわからなかったのですが、結局のところ、簡単に言うと、

・アドレス変換テーブルを途中で入れ替えることで、物理メモリリソースを無限に使用できる(理論上は)
・マルチプロセスの実現に便利

という利点があると理解しました。
で、規模の大きなOS向けだな、と。LinuxとかWindowsCE(懐かしい)とか。

当時、リアルタイムOS絡みの仕事が多かったので、まぁ自分には関係ないや、と思っていました。
論理アドレス=物理アドレスの空間で十分足りるし。
スレッドの数もそんなに多くないし。

確かに、MMUには別のメリットがあることも承知していました。
・メモリ空間の属性付加(ライト禁止、等)
・例外処理

まぁでもMMUをあえて積極的に使う、という事は、今まで特にありませんでした。

なにしろ、MMUのテーブルを下手に触ると、CPUがハングアップする!
MMUのテーブルを間違い一つもなく設定しない限り、CPUがハングアップするんですよね。
それって、ICEもハングアップするから、デバッグできない。
ハマりはじめると、終わりが見えない。

開発というものは、大体において、時間的に余裕ないですよね。
なので、そんなリスクは侵したくない。

と、いう事で、実はあまりMMUを積極的に使ったことはありませんでした。
理由は、「怖い」から。。。

2.MMUが怖くないSOLID ①

前回にも書きましたが、SOLID-IDE側でOSと連携して、内部的にMMUを使って実現する機能があります。

・NULLポインタアクセス発生を検出しブレーク
・スタックオーバーフロー発生を検出しブレーク

前回は紹介しませんでしたが、他にもあります。
・アドレスサニタイザ機能
コンパイラと連携し、配列オーバーフロー等、不正なメモリアクセスを検出しブレーク

デバッガを使う側の私たち、これらの機能を使うためにMMUを意識する必要はありません。
「MMUを意識せずに使える」のは有難い。

3.MMUが怖くないSOLID ②

加えて。
メモリ空間にリードオンリ属性を設定したかったり、範囲外のアクセスで例外発生して欲しかったり、します。

コード領域に不正書き込み、発生して欲しくない。
スタック領域、オーバーフローしたくない。

SOLIDでは、MMUのテーブルをGUIで視覚的に構築することができます。
そこまでなら、まぁそういうのもあるだろうね、なのですが。。。
実は、GUIで作成したMMUテーブルの情報をリンカに伝えてくれます。

大事なことなのでもう一度言います。

GUIで作成したMMUテーブルの情報をリンカに伝えてくれます。

めちゃ便利じゃないですか?

4.SOLIDとは

ここで軽く、SOLIDとはどのようなものか、についてご紹介します。

ARM Cortex-Aに特化したリアルタイムOSと開発環境がセットとなった、統合開発環境です。
OS、ビルドシステム、デバッガがセットで作られていることが特徴で、片方だけでは実現し得ない、便利な機能が搭載されています。

すぐに使ってみたい!という場合、前回のRust連載で使用した、Raspberry Pi 4用のSOLIDがあります。

Raspberry Pi 4用のSOLID は、OSとIDEが完全に無料です。
そのため、機能には制限があります。例えばMMUのテーブルを設定するGUIはサポートされていません。
ですが、SOLIDがどのようなものなのか、使ってみようという「導入用」には、非常に便利です。

SOLIDを導入するため費用等、詳しい事は、以下URLをご参照ください

5.GUIでMMUアドレス変換テーブル設定

前置きが長くなりました。
実際、見てみましょう!

前回のRust連載で、さんざん使用した、Raspberry Pi 4用のSOLIDではなく、今回は別のCortex-A9搭載ボード×PARTNER Jet2の組み合わせで見てみます。

まず、サンプルのプログラムを実行し、ルートタスクの先頭でブレークしてみました。

逆アセンブルウインドウから、このブレークポイントが設定されている命令の実行アドレスは0x800104D4だそうです。

早速MMUの変換テーブルをGUIで見てみましょう。

ソリューションエクスプローラにある、memory_map.smmファイルをダブルクリックします。

すると、MMUの変換テーブルを示す[メモリマップデザイナ]ウインドウが開きます。

この赤で囲ったところが、論理アドレス0x80000000の領域です。
これが現在ブレークポイントで止まっているエリアですね。

ちなにみ、テーブルだけでなく、メモリマップの形でも表示されます。
使われていない領域は「NOT USED AREA」と表示されています。

じゃ、次は、対応する論理アドレスを変更してみましょう。

0xC0000000のあたりは使われていないようですので、そちらに変更してみましょう。

[メモリマップデザイナ]ウインドウ上で、変更ができます。

変更してみました。

ビルドしてみましょう。

ビルドが通ったので、実行してみましょう。

先程と同じブレークポイントでブレークさせます。

実行アドレスが0xC00104D4に代わりましたね。

実行アドレスが変わっている、という事は、ポイントが二点あります。

・リンカへの反映
[メモリマップデザイナ]ウインドウで書き換えた新論理アドレス値にしたがって、ロードモジュールのアドレスが0x80000000空間から0xC0000000空間に変更してリンクされている。

・MMUアドレス変換テーブルへの反映
新論理アドレス(0xC0000000空間)に対応する物理アドレスが、きちんとMMUの変換テーブルに登録されている。

これら二点、どうやって実現されているのでしょうか。

6.GUIでMMUアドレス変換テーブル設定の仕組み

仕組みを見ていきましょう。

先程、[メモリマップデザイナ]ウインドウを起動するために、memory_map.smmファイルをダブルクリックしました。
このファイルを見てみます。

以下の行に注目しましょう。

<MemoryConfiguration Name="SOLID" Description="SOLID_CORE" PhysicalAddress="0x40000000" Size="0x02000000" Attribute="SOLID_CORE" VirtualAddress="0xc0000000" />

PhysicalAddress="0x40000000" を、
Size="0x02000000" 分、
VirtualAddress="0xc0000000" と対応させる

と、書かれています。
論理アドレス、先程変更した0xC0000000になっていますね。

さて、次。
先程、書き換えた直後にビルドしましたね。
ビルドの際に、memory_map.smmファイル内容をC言語の配列に置き換えています。

一時フォルダの中に、配列を格納したファイルがありました。
これですね。

SOLID-OSは、この配列にしたがって、MMUアドレス変換テーブルを初期化します。

さらに、同じ一時フォルダの中に、リンカ向けに各アドレスを教えていそうなファイルがありました。

リンカはこの定義を使用して、配置すべきアドレスを取得し、リンクを行っています。

この仕組みで、変更したアドレス変換テーブルの値がリンカにまで伝わっているのですね。

詳しくは、以下URLをご参照ください。

https://solid.kmckk.com/SOLID/doc/latest/user_guide/mmu.html

7.まとめ

SOLIDでは、OS、ビルドシステム、デバッガそれぞれにMMUに対する処置がなされています。そしてそれらが完全に連携でき、使う側にとっては非常に助かる機能が実現されている、というわけですね。

この新連載では、そういった機能についてどんどんご紹介していければ、と思っています。

次回も引き続き、SOLIDのMMU使いこなしを深堀していく予定です。


この記事が気に入ったらサポートをしてみませんか?