MMUの設定
Armプロセッサを使用する場合、メモリ領域に合わせてメモリタイプ(第10回参照)を設定します。プログラムやデータを配置する領域は、ノーマルメモリでキャッシュを有効に設定し、ペリフェラルを配置する領域は、デバイスメモリまたはストロングリオーダメモリに設定します。SCTLR(システム制御レジスタ)のIビットとCビットで命令キャッシュとデータキャッシュを有効にできますが、データキャッシュはMMUを有効にしないと使用できません。MMUを搭載するArmプロセッサを使用する場合、メモリタイプ(ノーマルメモリ・デバイスメモリ・ストロングリオーダメモリ)・キャッシュ・アクセス権の設定はMMUで行いますので、設定を理解しなければなりません。
命令キャッシュ設定 SCTLR Iビット | MMU動作設定 SCTLR Mビット | 命令キャッシュ 動作設定 |
---|---|---|
無効 | 無効 | 無効 |
無効 | 有効 | 無効 |
有効 | 無効 | 有効 |
有効 | 有効 | 変換テーブルの設定による |
データキャッシュ設定 SCTLR Cビット | MMU動作設定 SCTLR Mビット | データキャッシュ 動作設定 |
---|---|---|
無効 | 無効 | 無効 |
無効 | 有効 | 無効 |
有効 | 無効 | 無効 |
有効 | 有効 | 変換テーブルの設定による |
MMUの動作概要
仮想アドレスから物理アドレスへのアドレス変換は、MMUとTLB(トランスレーション・ルックアサイド・バッファ)を使用します。アドレス変換は、テーブルウォークユニットで変換テーブルを参照して自動的に変換を行い、TLBのキャッシュも行います。変換テーブルに、メモリタイプ・キャッシュ属性・バッファ属性を設定できます。
変換テーブルは、第1レベルテーブルと第2レベルテーブルで構成します。第1レベルテーブルでは、16Mバイトと1Mバイトの単位で仮想アドレスから物理アドレスに変換を行い、第2レベルテーブルを使用することで、より細かい64Kバイトと4Kバイトの単位で仮想アドレスから物理アドレスに変換できます。仮想アドレスから物理アドレスに変換する単位をページサイズと呼び、16Mバイトを「スーパーセクション」、1Mバイトを「セクション」、64Kバイトを「ラージページ」、4Kバイトを「スモールページ」と呼びます。
仮想アドレスから物理アドレス変換動作
MMUは、次の手順に従って、アドレス変換を行います。
- 仮想アドレス[31:20]ビットから、第1レベルテーブルの該当する1ワード(4バイト)の第1レベル記述子を参照。
- 第1レベル記述子の設定で、物理アドレスを求めるか、第2レベルテーブルを参照するかを決定。
- 第2レベルテーブルを使用する場合、仮想アドレス[19:12]ビットから、第2レベルテーブルの該当する1ワード(4バイト)の第2レベル記述子を参照し物理アドレスを求める。
- 第1レベルテーブルは、物理メモリ空間に16Kバイトのサイズで16Kバイト境界に配置し、第2レベルテーブルは、物理メモリ空間に1Kバイトのサイズで1Kバイト境界に配置。
変換テーブルとページサイズ
第1レベルテーブルの先頭アドレスは、TTBR0(変換テーブルベースレジスタ0)またはTTBT1(変換テーブル ベースレジスタ1)に設定しますので、第1レベルテーブルは2種類使用できます。第1レベルテーブルを1種類使用する場合は、TTBR0を使用します。
ページサイズ | 第1レベルテーブル | 第2レベルテーブル |
---|---|---|
スーパーセクション(*1)(16Mバイト) | ○ | × |
セクション(1Mバイト) | ○ | × |
ラージページ(64Kバイト) | ○ | ○ |
スモールページ(4Kバイト) | ○ | ○ |
(*1)スーパーセクションのサポートはオプションです。
第1レベル記述子の形式
第1レベルテーブルは、1ワード(4バイト)の第1レベル記述子で設定します。[1:0]ビットで、「フォルト」「ページテーブル」「セクション」「スーパーセクション」を選択します。「ページテーブル」の場合、第2レベルテーブルの先頭アドレスを1Kバイト境界で設定し、「セクション」の場合は物理アドレスの[31:20]、「スーパーセクション」の場合は物理アドレスの[31:24]に設定します。他の設定に関しては、下記レベル記述子設定についてを参照ください。
第2レベル記述子の形式
第2ベルテーブルは、1ワード(4バイト)の第2ベル記述子で設定します。[1:0]ビットで、「フォルト」「ラージページ」「スモールページ」を選択します。「ラージページ」の場合は物理アドレスの[31:16]、「スモールページ」の場合は物理アドレスの[31:12]に設定します。他の設定に関しては、下記レベル記述子設定についてを参照ください。
レベル記述子設定について
第1レベル記述子と第2レベル記述子で行う各種設定を説明します。
メモリタイプとキャッシュ設定一覧
メモリタイプとキャッシュ設定および共有設定を行います。共有設定は、メモリタイプの設定によって設定ができない場合があります。TEX[2]=1の場合、キャッシュを内部属性と外部属性を個別に設定します。
TEX[2:0] | C | B | メモリタイプ | 設定内容 | 共有設定 |
---|---|---|---|---|---|
000 | 0 | 0 | ストロングリオーダ | ストロングリオーダ | 共有可能 |
000 | 0 | 1 | デバイス | 共有デバイス | 共有可能 |
000 | 1 | 0 | ノーマル | 外部および内部ライトスルー ライトアロケートなし | Sビット |
000 | 1 | 1 | ノーマル | 外部および内部のライトバック ライトアロケートなし | Sビット |
001 | 0 | 0 | ノーマル | 外部と内部でキャッシュ不可 | Sビット |
001 | 0 | 1 | – | 予約 | – |
001 | 1 | 0 | – | 実装定義 | – |
001 | 1 | 1 | ノーマル | 外部・内部ライトバック ライトアロケートあり | Sビット |
010 | 0 | 0 | デバイス | 非共有デバイス | 共有不可 |
010 | 0 | 1 | – | 予約 | – |
010 | 1 | X | – | 予約 | – |
011 | X | X | – | 予約 | – |
1BB | A | A | ノーマル | キャッシュ可能メモリ BB = 外部属性 AA = 内部属性 | Sビット |
TEX[2]=1設定時の設定一覧
キャッシュの内部属性と外部属性の設定は次の形式で設定します。(内部属性:L1キャッシュ、内部属性:L2キャッシュ)
外部属性 | 内部属性 | キャッシュ属性 | ||
---|---|---|---|---|
TEX[1] | TEX[0] | C | B | |
0 | 0 | 0 | 0 | キャッシュ不可 |
0 | 1 | 0 | 1 | ライトバック・ライトアロケート |
1 | 0 | 1 | 0 | ライトスルー・ライトアロケートなし |
1 | 1 | 1 | 1 | ライトバック・ライトアロケートなし |
アクセス権設定
AP[2:0]で、ページサイズ毎にアクセス権の設定ができます。複数のアクセス属性を変更する場合、第1レベルテーブルの「ドメイン」を利用することで、効率的にアクセス権の設定変更ができます。詳しくは、下記ドメインの使用方法を参照ください。
AP[2:0] | 特権動作設定 | 非特権動作設定 | 内容 |
---|---|---|---|
000 | アクセス不可 | アクセス不可 | アクセス不可 |
001 | 読み出し/書き込み | アクセス不可 | 特権アクセスのみ |
010 | 読み出し/書き込み | 読み出し | ユーザモードの書み込み不可 |
011 | 読み出し/書き込み | 読み出し/書込み | 完全アクセス |
100 | – | – | 予約 |
101 | 読み出し | アクセス不可 | 特権読み出し |
110 | 読み出し | アクセス不可 | 読み出し専用 |
111 | – | – | 予約 |
その他の設定
設定 | 内容 |
---|---|
XN | 実行禁止を設定します。この領域から命令フェッチができるかどうかを示します。 |
S | S=0:ノーマルメモリ領域が共有できません。 S=1:ノーマルメモリ領域が共有できます。 ※エントリがデバイスメモリ・ストロングリオーダメモリの場合、無視されます。 |
nG | 非グローバルを設定します。 nG=0:変換はグローバルです。 nG=1:変換はアドレス空間識別子(ASID)に関連します。 |
NS | “セキュア” アクセスビットを設定します。 「第15回:TrustZone(セキュリティ拡張機能)」で説明します。 |
ドメイン | DACRで定義されるアクセスパーミッションを選択します。 詳しくは、下記「ドメインの使用方法」を参照ください。 |
ドメインの使用方法
第1レベル記述子の「ページテーブル」「セクション」のドメイン([8:5]ビット)設定は、DACR(ドメインアクセス制御レジスタ)のD15からD0を選択します。「スーパーセクション」は、ドメイン設定がないのでD0が選択されます。アクセス設定はページサイズごとに行いますが、複数ページのアクセス権を変更する場合、複数の第1レベル記述子を変更と同時に、TLBメンテナンスを行わなければなりません。DACRのドメイン番号の設定値を書き換えることで、変換テーブルのアクセス許可設定を無視できます。
設定値 | 設定内容 |
---|---|
0b00 | アクセス不可設定 |
0b01 | クライアント設定(変換テーブルのアクセス許可ビット設定になります) |
0b10 | 予約 |
0b11 | マネージャ設定(変換テーブルのアクセス許可ビットはチェックしません) |
テーブルを使用したアドレス変換
第1レベルテーブルを使用したアドレス変換
第1レベルテーブルを使用した「セクション」で、仮想アドレスから物理アドレスに変換する動作を説明します。第1レベルテーブルは、0x000F_0000番地から配置し、仮想アドレス0x0010_0000番地を物理アドレスに変換します。
- 仮想アドレスの[31:20]ビットを使用して、第1レベルテーブルのオフセットアドレスを求める。
- 第1レベルテーブルは、仮想アドレス1Mバイト単位毎に、第1レベル記述子が保存されているので、以下の計算式で第1レベルテーブルのアドレスを求める。
アドレスオフセット = 仮想アドレス[31:20]ビット×4 =0x001×4=0x004
テーブルアドレス
= 第1レベルテーブルアドレス+アドレスオフセット
= 0x000F_0000+0x004 = 0x000F_0004 - 0x000F_0004番地の第1レベル記述子を読み出し、第1レベル記述子の[31:20]ビットが、物理アドレスの[31:20]ビットになり、仮想アドレスの[19:0]ビットは、物理アドレスの[19:0]ビットになります。
セクションのアドレス変換設定例
第1レベルテーブルを使用し、「セクション」で仮想アドレスから物理アドレスに変換する場合の設定例を説明します。連続して配置されていない仮想アドレス3領域を、連続した物理アドレス空間に配置します。
仮想アドレス | メモリ設定 | 物理アドレス |
---|---|---|
0xFFFF_FFFF 0xFFF0_0000 | ノーマルメモリ 1Mバイト | 0x004F_FFFF 0x0040_0000 |
0xFFEF_FFFF 0x4020_0000 | アクセス禁止空間 | – |
0x401F_FFFF 0x4000_0000 | ノーマルメモリ 2Mバイト | 0x003F_FFFF 0x0020_0000 |
0x3FFF_FFFF 0x0020_0000 | アクセス禁止空間 | – |
0x001F_FFFF 0x0000_0000 | ノーマルメモリ 2Mバイト | 0x001F_FFFF 0x0000_0000 |
第1レベルテーブルの設定を行う場合、仮想アドレスの[31:20]ビットでテーブルを参照し、テーブルの[31:20]ビットが物理アドレスの[31:20]ビットになり、物理アドレスの[19:0]ビットは仮想アドレスの[19:0]ビットになります。例えば、0x400n_nnnn番地を変換する場合、第1レベルテーブルのオフセットは0x400×4=0x1000になり、テーブルの[31:20]ビットに0x002を設定します。仮想アドレスの0x400n_nnnn番地をアクセスした場合、物理アドレスの0x002n_nnnn番地にアクセスします。
第2レベルテーブルを使用したアドレス変換
第1レベルテーブルと第2レベルテーブルを使用した「スモールページ」で、仮想アドレスから物理アドレス変換を行う場合の動作を説明します。第1レベルテーブルは、0x000F_0000番地から配置し、仮想アドレス0x0020_0000番地を物理アドレスに変換します。
- 仮想アドレスの[31:20]ビットを使用して、第1レベルテーブルのオフセットアドレスを求る。
- 第1レベルテーブルは、仮想アドレス1Mバイト単位ごとに、第1レベル記述子が保存されているので、以下の計算式で第1レベルテーブルのアドレスを求める。
アドレスオフセット = 仮想アドレス[31:20]ビット×4=0x002×4=0x008
テーブルアドレス
= 第1レベルテーブルアドレス+アドレスオフセット
= 0x000F_0000+0x008 = 0x000F_0008 - 0x000F_0008番地の第1レベル記述子を読み出し、第1レベル記述子の[31:10]ビットが第2レベルテーブルの先頭アドレスになる。
- 仮想アドレスのビット[19:12]は、仮想アドレス空間アクセス場所を4Kバイト単位で示す。
アドレスオフセット = 仮想アドレス[19:12]ビット×4 = 0x00×4 = 0x000 - 第2レベルテーブルの第2レベル記述子を読み出し、第2レベル記述子の[31:12]ビットが物理アドレスの[31:12]ビットになり、仮想アドレスの[11:0]ビットは物理アドレスの[11:0]ビットになる。
スモールページのアドレス設定例
第1レベルテーブルと第2レベルテーブルを使用し、「スモールページ」で、仮想アドレスから物理アドレスに変換する場合の設定例を説明します。仮想アドレス0x4000_0000番地から32Kバイトの空間を4Kバイト単位で物理アドレス0x0010_0000番地および0x0020_0000番地を先頭に配置します。
仮想アドレス | メモリ設定 | 物理アドレス |
---|---|---|
0xFFFF_FFFF 0x4000_8000 | アクセス禁止空間 | – |
0x4000_7FFF 0x4000_7000 | ノーマルメモリ 32Kバイト | 0x0020_3FFF 0x0020_3000 |
0x4000_6FFF 0x4000_6000 | 0x0010_3FFF 0x0010_3000 | |
0x4000_5FFF 0x4000_5000 | 0x0020_2FFF 0x0020_2000 | |
0x4000_4FFF 0x4000_4000 | 0x0010_2FFF 0x0010_2000 | |
0x4000_3FFF 0x4000_3000 | 0x0020_1FFF 0x0020_1000 | |
0x4000_2FFF 0x4000_2000 | 0x0010_1FFF 0x0010_1000 | |
0x4000_1FFF 0x4000_1000 | 0x0020_0FFF 0x0020_0000 | |
0x4000_0FFF 0x4000_0000 | 0x0010_0FFF 0x0010_0000 | |
0x3FFF_FFFF 0x0010_0000 | アクセス禁止空間 | – |
0x000F_FFFF 0x0000_0000 | ノーマルメモリ 1Mバイト | 0x000F_FFFF 0x0000_0000 |
第1レベルテーブルを仮想アドレスの[31:20]ビットでテーブルを参照し、第2レベルテーブルの先頭アドレスを求めます。仮想アドレスの[19:12]ビットで第2レベルテーブルを参照し、テーブルの[31:12]が物理アドレスの[31:12]になり、物理アドレスの[11:0]ビットは仮想アドレスの[11:0]ビットになります。例えば、0x4000_0nnn番地を変換する場合、第1レベルテーブルのオフセットは0x400×4=0x1000になり、テーブルの[31:10]ビットに設定されている第2レベルテーブルの先頭アドレスを求めます。第2レベルテーブルのオフセットは0x00×4=0x00になり、テーブルの[31:12]ビットに0x00100を設定します。仮想アドレスの0x4000_0nnn番地をアクセスした場合、物理アドレスの0x0010_0nnn番地にアクセスします。
サンプルプログラム
第1レベルテーブルで「セクション」を選択した場合のサンプルプログラムを説明します。仮想アドレス = 物理アドレスとして配置します。
第1レベルテーブル作成サンプルプログラム
第1レベルテーブルの構築をRAM領域に作成するサンプルプログラムです。プログラムは、0x0番地から1Mバイトの領域をノーマルメモリ/内部キャッシュはライトバック/ライトアロケートなし/外部キャッシュ不可に設定します。他の領域はストロングリオーダメモリの設定を行い、第1レベルテーブルは0x0010_0000番地から配置します。ドメインは、D16を参照する設定にします。
LEVEL1_BASE_ADDR EQU 0x00100000 ; 第1レベルテーブルの先頭アドレス VECTOR_BASE_ADDR EQU 0x00000000 ; ベクタテーブル先頭アドレス ; ; TTBCR(テーブル変換ベース制御レジスタ)/TTBR0の設定 ; MOV r0,#0x0 ; TTBCR 0x0の初期値 MCR p15,0,r0,c2,c0,2 ; TTBCRの書き込み LDR r0,=LEVEL1_BASE_ADDR ; 第1レベルテーブルアドレスを設定 MOV r1,#0x48 ; TTBR0の初期化を実施 ; TTBR0.IRGN[6.0]=01:ノーマルメモリ ; 内部ライトバック書き込み割り当てキャッシュ可能 ; TTBR0.S[1]=0:共有不可設定 ; TTBR0.RGN[4:3]=01:ノーマルメモリ ; 外部ライトバック・ライトアロケート・キャッシュ可能 ORR r0,r0,r1 ; TTBR0の設定値を設定 MCR p15,0,r0,c2,c0,0 ; TTBR0の書き込み ; ; 第1レベルテーブルの作成 ; LDR r0,=LEVEL1_BASE_ADDR ; 第1レベルテーブルアドレスを設定 LDR r1,=0xfff ; ループカウンタを初期化 LDR r2,=0x00000de2 ; テーブルの初期設定値を設定 init_ttb_1 ORR r3,r2,r1,LSL#20 ; ベースアドレスを設定 STR r3,[r0,r1,LSL#2] ; 第1記述子書き込み SUBS r1,r1,#1 ; ループカウンタを-1 BPL init_ttb_1 ; 変換テーブル作成終了? ; ; ベクタ領域の第1記述子を変更 ; LDR r1,=VECTOR_BASE_ADDR ; ベクタの先頭アドレスを設定 LSR r1,#20 ; 1Mバイト境界にアドレスを設定 ORR r3,r2,r1,LSL#20 ; テーブルの初期値を求める ORR r3,r3,#0x0c ; ノーマルメモリ内部キャッシュ可能設定 ORR r3,r3,#0x1000 ; 外部キャッシュ不可設定 STR r3,[r0,r1,LSL#2] ; テーブルエントリを設定
ドメインの初期化
ドメイン設定は、D0からD15の全ての設定を「クライアント」に設定しています。第1レベル記述子のドメイン設定値(5ビットから8ビットの範囲を設定)がDACRを参照します。「クライアント」設定は、第1レベル記述子のアクセス設定に準じます。
;================================================== ; ドメインアクセス制御レジスタの全クライアント設定 ;================================================== LDR r0,=0x55555555 ; クライアント設定 MCR p15,0,r0,c3,c0,0 ; DACRに書き込み
MMUの稼働設定
MMUは、リセット時は非稼働に設定されているので、終了後に全ての設定を有効にします。第1レベルテーブルの設定(4096個の第1レベル記述子)/TTBCRの設定/TTBR0/TTBR1/DACRの各設定が適切であることを確認した後に、SCTLRのMビットを有効に設定します。
; ; MMUを稼働状態に設定 ; MRC p15,0,r0,c1,c0,0 ; SCTLRを読み込み ORR r0,r0,#0x1 ; MMUを稼働状態に設定 (SCTLR.M[0]) MCR p15,0,r0,c1,c0,0 ; SCTLRに書き込み
こちらも是非
“もっと見る” Cortex-A編
初期化処理
リセット例外からmain()関数を呼び出すまでの初期化は、ユーザが作成する部分とArmコンパイラが実行する部分に分けることができます。コードのコピーや初期化変数/未初期化変数の初期化は、リンカのメモリ配置設定を処理系ライブラリが実行します。
PMU(パフォーマンス監視ユニット)
PMUに関連するレジスタは、ユーザモードでのアクセスは禁止されていますので、PMUSERENR(ユーザイネーブルレジスタ)を特権モードでユーザモードアクセス許可を設定します。PMUSERENRについては、 後述の該当項目を参照ください。
TrustZone(セキュリティ拡張機能)
TrustZoneはCortex-Aシリーズの拡張機能で、大規模OSやアプリケーションが動作するノーマルワールドとセキュリティ関連が動作するセキュアワールドを導入しています。TrustZoneでは、ノーマルワールドメモリ空間とセキュアワールドメモリ空間の分離が可能です。