eSOL Marketing Official Blog

メモリ属性の設定ミスによる厄介な症状を回避するために

2023/01/30 11:00:00

本記事では、Armv8-Aアーキテクチャのプロセッサを例にとり、メモリ属性の設定ミスによる厄介な症状を回避するために必要な知識をご紹介します。
(※本内容は、イーソルの英語版Blogで1月に投稿した記事の日本語版です。)



Armv8-Aアーキテクチャのプロセッサを例にとり、組込みプログラミングで時間のかかるデバッグを回避するためのガイド

あるターゲットボードで動作しているOSを別のターゲットボードに移植する際に行う作業の1つに「トランスレーションテーブル」の設定があります。トランスレーションテーブルは、論理アドレスと物理アドレスを結びつけるものです。MMU(Memory Management Unit)は、この設定に従って動作します。ターゲットボードによって、メモリのサイズや物理アドレスの割り当ては異なるため、このテーブルの作成は移植のたびに行う必要があります。

コンフィギュレーション

Armv8-Aアーキテクチャでは、「トランスレーションテーブル」で論理アドレスと物理アドレスの関連付けだけでなく、アクセス権やメモリ属性も設定します。メモリ属性には大きく2種類あります。NormalとDeviceです。一般に、通常のRAMやROMにはNormal属性を、またメモリマップド周辺レジスタにはDevice属性を設定します(図1)。
img_blog_20230123_1


図1:Armv8-A環境でのメモリ属性設定例

この属性設定を行った場合は、机上で十分に確認する必要があります。というのも、属性の設定を誤った場合、発生する症状からその原因にたどりつくことが非常に困難だからです。以下に、メモリ属性が正しく設定されていない場合に起こる可能性のある3つの症状をご紹介しましょう。

ROMやRAMの属性設定を間違えた場合

メモリアクセスには、境界アクセスと非境界アクセスがあります。コンパイラは、非境界アクセスを利用することでより効率的なコードを出力することがあります(例えば、ビットサイズの小さいデータをRAMに格納する場合など)。通常、ROMやRAMに対しては、非境界アクセスが可能です。 しかし、組み込みチップの中には、メモリマップドレジスタのように、ハードウェア仕様上、非境界アクセスができないメモリも存在します。そのため、トランスレーションテーブルには実際のメモリと整合するように属性設定する必要があります。

トランスレーションテーブルで Normal 属性を設定した領域は非境界アクセスが可能です。いっぽう、Device 属性を設定した領域は境界アクセスのみが可能です。そのため、通常のRAMやROMに対して誤ってDevice属性を指定した場合、コンパイラが最適化によって出力した非境界アクセスの命令があると、プログラム上は正しい処理を行っているにもかかわらず、CPU例外が発生します。

img_blog_20230123_2
図2:ステータスレジスタDFSR

Armv8-Aアーキテクチャに精通したエンジニアであれば、例外発生後にDFSR(Data Fault Status Register、図2)を見て、FSビット(Fault Status Bit)がアライメントエラーを示していることを確認すれば、原因を特定することができるかもしれません。しかし、症状が根本原因を指し示す他の直接的なものではないため、事前に知識がなければ例外の原因を特定することは難しいです。

Normal属性の設定範囲を間違えた場合

2つ目の例は、物理メモリが存在しないアドレスにNormal属性を設定した場合に発生する問題です。 Armv8-Aアーキテクチャのトランスレーションテーブルでは、4KB、16KB、64KBなどの粒度でメモリ設定を行うことができます。特にOS移植の初期段階において、一時的に一つの粒度のトランスレーションテーブルのみを用意している場合など、以下のような状況が発生することがあります(図3)

img_blog_20230123_3

図3:通常属性の粒度設定の誤り

例えば、4KBの小さなオンチップSRAMを16KB単位のトランスレーションテーブルでNormal属性に設定した場合、SRAMの前後12KBについて、物理メモリがアサインされていない物理アドレスがNormal属性に設定されることになります。

プログラムが誤ってメモリが割り当てられていないアドレスにアクセスした場合、期待される動作は、CPU例外が発生してOSがプログラムの異常動作を検出することです。しかし、そのアドレスがトランスレーションテーブルで通常アクセスできるように設定されていると、CPU例外は発生せず、実際にメモリアクセスが行われます。この場合、動作は不定となります。多くの場合、CPUがハングアップしたような状態になり、以降、ログ情報の読みだしやJTAGを使ったデバッグができなくなります。このため、問題が発生する直前の動作を捉えることができず、問題の原因に迫ることが難しくなります。

誤ったNormal属性設定と投機的アクセスの組み合わせ

最後の例は、 2番目の例と似ていますが、「投機的アクセス」によってより複雑になったものです。投機的アクセスは、Armv8-A CPUによるプリフェッチメカニズムで、命令実行を先取りしてメモリアクセスを開始するというものです。低速なメモリアクセスをCPUによる命令実行に先行して開始しておくことで、性能を向上させることができます。

しかし、この先読みは投機的なものであり、実際には先読みでアクセスしたメモリアドレスはCPUによって使用されない可能性もあります。言い換えると、プログラム的には実際にアクセスが発生しないアドレスへの投機的なアクセスが発生する可能性があります。

投機的なメモリアクセスは、Normal属性が指定されたメモリ領域に対してのみ行われます。そのため、予測が外れても、事前にフェッチされたデータがプログラムで使用されないだけで大きな問題はありません。(プログラムとしての投機的読み出しの対象となるメモリはこれとは異なります。これについては別の機会に詳しく説明したいと思います)

しかし、メモリが割り当てられていない物理アドレスをNormal属性に設定した場合、投機的なアクセスが発生する可能性があります。この場合も、2番目の例と同様に、CPUのハングアップが発生します。しかし今度は、デバッグ可能なプログラムの実行とは関係なく、ハードウェアのメカニズムによってバックグラウンドで発生するメモリアクセスによってハングアップが発生するため、原因を特定することがさらに困難になります。

結論

このように、トランスレーションテーブルの設定は、OSを移植する際に特に注意して行わなければならない作業の1つです。トランスレーションテーブルの設定ミスによって引き起こされる問題は、症状から原因を特定することが難しいからです。

OSの移植担当者だけでなく、 アプリケーション開発者も、上記のような現象に留意する必要があります。原因不明のハングアップや例外が発生している場合、それはトランスレーションテーブルの設定に起因している場合もあります。そのようなことが疑われる場合は、 OSの移植担当者に相談するといいでしょう。

 

Blog_2301_Kubi-san エンジニアリング本部 プロダクトサポート部
テクノロジーディレクター 久保 裕介

2000年にイーソルに入社し、以来、20年以上にわたり組込みエンジニアとしてイーソルのRTOSプラットフォーム製品の開発、サービス提供に携わる。現在は、ソフトウェア製品のサポート部門を担当。


OSの移植を含むプロフェッショナルサービスの詳細はイーソルまでお問合せください。

お問い合わせはこちら


最近の記事

ブログの更新通知を受け取る