1.9K Views
August 24, 23
スライド概要
2017年作成の、ARM(v7a)用LinuxでのMMU使用方法
nagoya.bin 【低レイヤーLT勉強会】 #1 ARM LinuxのMMUはわかりにくい
初めに • 低レイヤーLT勉強会が開催されるのをconnpassで発見したので参加し てみました • こういう試みはとても面白いので今後も続いてくれるといいなーと 思っています • 今日は、Linuxのキャッシュ周りを調べていて気付いたことに関する発 表です。
MMUとは? • MMU(Memory Management Unit)とは? • CPUのメモリ管理を行うハードウェア • コンピュータサイエンスの教科書では、OS(Operating System)の仮想記憶 を実現するための仕組みとして紹介される • 全てのユーザプログラムに固有のアドレス空間が与えられる • 他のプログラムから隔離・保護される 仮想アドレス 物理アドレス 仮想アドレス VA0-00 PA-00 VA1-00 VA0-01 PA-01 VA1-01 VA0-02 PA-02 VA1-02 VA0-03 PA-03 VA1-03 VA0-04 PA-04 VA1-04 VA0-05 PA-05 VA1-05 VA0-06 PA-06 VA1-06 httpd smbd
MMUの仕組み • Coretex-A9におけるMMUの位置づけ
ARMのMMU • ARMのMMUは何ができるのか? • アドレス変換 • 仮想記憶のためのアドレス変換 • プロセスモデルを実現するために必要 • メモリアクセス許可 • データ領域の実行をできなくしたり、ユーザーモードではアクセスできな くしたりできる • 不正なメモリアクセスをブロックすることで、アプリケーションに触らせたく ないハードウェアレジスタを見えなくする • 攻撃されて任意のデータをメモリに流し込まれても、データ領域は実行属性を 付けないことで実行できなくする • メモリ属性の指定 • キャッシュの有効・無効 • コード領域やデータ領域はキャッシュ有効にしてアクセス速度を速くする • ハードウェアのレジスタは、ハードウェアの状態を直接見ないといけないので キャッシュ無効
ARMのMMU • ARMのMMUは何ができるのか? • アドレス変換, メモリアクセス許可, メモリ属性の指定 • これらはページテーブルに記録される Lv1ページテーブル 仮想アドレス 0x00100000 Lv1ページテーブルは 1MByte単位のLUTに なっている 0x00000000-0x000FFFFF用 0x00100000-0x001FFFFF用 0x00200000-0x002FFFFF用 ・ ・ ・ 0xFFF00000-0xFFFFFFFF用 Lv1ページテーブルのフォーマット この設定はアクセス不許可を意味する 1ページ4KByteの時の設定 (さらにLv2テーブルをルックアップする) 1ページ1MByteの時の設定 1ページ16MByteの時の設定 (使われているのを見たことがない)
ARMのMMU • 1ページ4KByte場合は、さらにもう一回LUTをルックアップする Lv1ページテーブル 仮想アドレス 0x00100000 Lv1ページテーブルは 1MByte単位のLUTに なっている 0x00000000-0x000FFFFF用 0x00100000-0x001FFFFF用 0x00200000-0x002FFFFF用 ・ ・ ・ 0xFFF00000-0xFFFFFFFF用 0x00100000-0x00100FFF用 0x00100000-0x00101FFF用 0x00100000-0x001FFFFF用 0xFFF00000-0xFFF00FFF用 0xFFF00000-0xFFF01FFF用 0xFFF00000-0xFFFFFFFF用 Lv2ページテーブルのフォーマット この設定はアクセス不許可を意味する 1ページ64KByteの時の設定 1ページ4KByteの時の設定
ARMのMMU • ARMのMMUは何ができるのか? • アドレス変換, メモリアクセス許可, メモリ属性の指定 • メモリ属性(キャッシュ設定) Coretex-A9 TEX[2]ビットを1に設定することで、L1, L2キャッ シュの設定が個別にできるようになる
ARMのMMU • ARMのMMUは何ができるのか? • アドレス変換, メモリアクセス許可, メモリ属性の指定 • メモリ属性(キャッシュ設定) Coretex-A9 Linuxの実装ではTEX[2]=0で使用している しかも、表と挙動が違う
犯人はこいつ • Linuxカーネルソースのarch/arm/mmの下に犯人発見 ENDPROC(cpu_v7_set_pte_ext) /* * Memory region attributes with SCTLR.TRE=1 * n = TEX[0],C,B * TR = PRRR[2n+1:2n] - memory type * IR = NMRR[2n+1:2n] - inner cacheable property * OR = NMRR[2n+17:2n+16] - outer cacheable property * n TR IR OR * UNCACHED 000 00 * BUFFERABLE 001 10 00 00 * WRITETHROUGH 010 10 10 10 * WRITEBACK 011 10 11 11 * reserved 110 * WRITEALLOC 111 10 01 01 * DEV_SHARED 100 01 * DEV_NONSHARED 100 01 * DEV_WC 001 10 * DEV_CACHED 011 10 */ .equ PRRR, 0xff0a81a8 .equ NMRR, 0xc0e040e0 0xc 0x4 11 00 01 00 SCTLR.TRE=1にすることで、PRRRとNMRRレジスタを使って設定を上書きできることが判明 Kernel 4.9の場合、WRITEALLOC設定なのにL1はライトバックライトアロケート、L2がライト バックのみになっている
まとめ • ARM Linuxのキャッシュ設定を調べていてぶつかった謎 • キャッシュ設定はページテーブルでコントロールしている • ところが、ページテーブルの設定と挙動が違う • カーネルのARM依存部分を調査した結果、ページテーブル設定をさらに レジスタ設定で変更できることが判明 • ちなみにこの部分、カーネルのバージョンアップでたまに設定が変わりま す。。。 • 参考資料 • http://infocenter.arm.com/help/index.jsp • ARMの資料はここに集約されています。ユーザ登録をしてダウンロードで きないものもありますが、困ったときはまずここで調べてください