Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
試して理解 ARMv6 MMU/kernelvm hokuriku4
Search
Toshifumi NISHINAGA
November 10, 2018
Programming
4
1.3k
試して理解 ARMv6 MMU/kernelvm hokuriku4
Toshifumi NISHINAGA
November 10, 2018
Tweet
Share
More Decks by Toshifumi NISHINAGA
See All by Toshifumi NISHINAGA
BareMetalで遊ぶRaspberry Pi 5 PCIe編/KernelVM Tokyo17
tnishinaga
0
1.6k
probe-rsの紹介と最近の貢献紹介/CELF-02-03
tnishinaga
1
320
SecurityCamp2023基板作るコース講義資料/Security Camp 2023 Lecture Materials
tnishinaga
8
2.4k
RP2040のPIOを使う話/KernelVM Hokuriku 6
tnishinaga
3
1.2k
JTAGでArmプロセッサをデバッグする方法のつづき/KernelVM_Tokyo16
tnishinaga
0
360
CMSIS-DAPの概要と使い方/KernelVM Online5
tnishinaga
0
1.6k
JTAGでarmプロセッサをデバッグする話/KernelVM Online4
tnishinaga
4
2.9k
ARM入門/arm introduction
tnishinaga
15
12k
俺の仮想マシンルーターがこんなに遅いはずはない/ KernelVM online 1
tnishinaga
0
2.7k
Other Decks in Programming
See All in Programming
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
170
ヤプリ新卒SREの オンボーディング
masaki12
0
130
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
10
1.3k
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
1
100
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
Jakarta EE meets AI
ivargrimstad
0
140
subpath importsで始めるモック生活
10tera
0
300
Pinia Colada が実現するスマートな非同期処理
naokihaba
4
220
TypeScriptでライブラリとの依存を限定的にする方法
tutinoko
2
660
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
レガシーシステムにどう立ち向かうか 複雑さと理想と現実/vs-legacy
suzukihoge
14
2.2k
Featured
See All Featured
It's Worth the Effort
3n
183
27k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
Embracing the Ebb and Flow
colly
84
4.5k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Facilitating Awesome Meetings
lara
50
6.1k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Automating Front-end Workflow
addyosmani
1366
200k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
Transcript
試して理解 ARMv8 MMU Toshifumi NISHINAGA(@tnishinaga) 2018/11/10 KernelVM Hokuriku@4 コードはこちら https://github.com/tnishinaga/kernelvm_hokuriku4
v6 まにあわなかった
$ who • Name: Toshifumi NISHINAGA • Attribute: Hobby embedded
programmer • Activities: ◦ Google Summer of Code 2016(Linux foundation) ▪ https://summerofcode.withgoogle.com/archive/2016/projects/661784 9892175872/ ▪ Porting Linux to ARM Cotex-M7 microcontroller. ◦ U-Boot contributor(not active recently…) • link: ◦ https://github.com/tnishinaga ◦ https://speakerdeck.com/tnishinaga 3
ARMとは • 今最もアツい(個人の感想です) ARM社の RISC CPU • 組み込み機器で多く利用 • 最近はサーバー向けにも進出
• 今買うならSynQuacerってマシン がおすすめ 4
今回のお話 • MMUの概要と実際の設定方法をご紹介 5
もくじ • MMUの概要 ◦ MMUとは ▪ アクセス制御 ▪ アドレス変換 ◦
実践:アクセス制御 • 実践:MMUを動かしてみる ◦ アドレス変換の仕組み ◦ アドレス変換テーブル ◦ MMU Discriptor • 実践:アドレス変換 6
もくじ • MMUの概要 ◦ MMUとは ▪ アクセス制御 ▪ アドレス変換 ◦
実践:アクセス制御 • 実践:MMUを動かしてみる ◦ アドレス変換の仕組み ◦ アドレス変換テーブル ◦ MMU Discriptor • 実践:アドレス変換 7
Memory Management Unit(MMU)とは • 仮想メモリの管理やアクセス制御などを行うユニット • Linuxなどの最近の一般的なOSは基本的にMMUがあること前提 ◦ NOMMU Linuxもあるけどできることがかなり限られる
▪ forkが使えないなど ▪ (MMUがないとアドレス空間が分けられないから?) 8
MMUがあるとできること • 読み書き実行アクセス制御 • メモリアドレス変換(VA -> PA) • その他(キャッシュ可否など。説明skip) 9
読み書き実行アクセス制御 • 特定メモリ領域の読み書き実行可否設定ができる • セキュリティ対策に使える。 • • 例:スタックのメモリを実行不可にする ◦ スタックにコードを置いて実行する攻撃を防げる
▪ Buffer over flow攻撃など 10
アドレス変換 • 仮想アドレス(Virtual Address, VA)を物理アドレス(Physical Address, PA)に変換する機能 • プロセスごとに独立したメモリ空間を用意できる ◦
プログラマやコンパイラがプログラムがどのアドレスに配置されるか気にしなく て良い ◦ メモリ空間がプロセスごとに分かれているので、他プロセスのデータにアクセス はできない 11 proc1の メモリ空間 proc1 proc2の メモリ空間 proc2 仮想メモリ 0x00 0x00 0xff.. 0xff.. proc1の メモリ空間 proc2の メモリ空間 0x00 0xff.. 物理メモリ
もくじ • MMUの概要 ◦ MMUとは ▪ アクセス制御 ▪ アドレス変換 ◦
実践:アクセス制御 • 実践:MMUを動かしてみる ◦ アドレス変換の仕組み ◦ アドレス変換テーブル ◦ MMU Discriptor • 実践:アドレス変換 12
実践: アクセス制御 • 確かめたいこと ◦ メモリに対するアクセス制御ができることを調べたい • 検証方法 ◦ 実行不可としたスタック上にコードを入れて動かしてみる
◦ /proc/self/maps を覗いてstackの読み書き実行フラグ状態を調べる • 期待する動作 ◦ 実行フラグがOFFなっている ◦ SEGVする 13
検証コード • stackに置くコード ◦ https://github.com/tnishinaga/kernelvm_hokuriku4/blob/master/stack_exe c_test/ret1.S • stackのメモリ属性を参照して、stackのコードを実行するコード ◦ https://github.com/tnishinaga/kernelvm_hokuriku4/blob/master/stack_exe
c_test/stack_exec.c 14
実行結果 15 pi@raspberrypi:~/kernelvm_hokuriku/stack_exec_test $ ./stack_noexec.elf buf address: 0xbeaf3490 bead3000-beaf4000 rw-p
00000000 00:00 0 [stack] ret1 addr: 0x106d0 ret1_fin addr: 0x106d8 Segmentation fault 実行権限xがつ いてない
結果 • 実行不可としたスタック上でコードが動かないことを確認した • メモリの属性も実行不可となっているのを確認した 16
Tips: stack実行可否の制御 • 一部例外を除いてstackは実行不可になっている • 例外: ◦ コンパイルオプションに-z execstackをつける(リンカのお仕事) ◦
-z noexecstack をつけずに.cと.Sの混ぜてビルドする ▪ 参考: https://qiita.com/rarul/items/e1920e7ae5d5a28eec03 17
もくじ • MMUの概要 ◦ MMUとは ▪ アクセス制御 ▪ アドレス変換 ◦
実践:アクセス制御 • 実践:MMUを動かしてみる ◦ アドレス変換の仕組み ◦ アドレス変換テーブル ◦ MMU Discriptor • 実践:アドレス変換 18
MMUを動かしてみる ここからはARMv6 MMU(VMSAv6)を実際に設定しつつ、MMUの動作を手を 動かしながら学びます 簡単のため、設定するMMUの仕様は以下 • 変換レベルは1段 • ストレートマップ(VA =
PA) • 解説は基本アドレス変換のみに絞る。その他はskip 19
アドレス変換の仕組み • アドレス変換は変換表を見て対応するアドレスに変換してる • アドレス変換はある程度まとまった単位で行われる ◦ 1byteづつで変換するとメモリと同じサイズの変換テーブルが必要 • ARMではVAの上位n bit(変換段数で変化)を使って変換
• それ以下はVA = PAとしてアドレスを作る CCCC 0xAA CCCC 0xBB 0xBB 0xAA 0x00 0x.. 変換テーブル Virtual Address Physical Address 20
アドレス変換テーブル • アドレス変換はアドレス変換テーブルを参照して行われる • 変換テーブルはメモリ上に置かれる • 場所をTTBRレジスタにセットするとアドレス変換に使われる ◦ TTBR0とTTBR1の2つあるが、簡単のためTTBR0を利用 メモリ
変換テーブル 0xAA 0xAA TTBR0 21
TTBR0への変換テーブル設定コード • TTBR0はシステムレジスタなのでMCR命令で書き込む • テーブルのアドレスは16KiB alignである必要がある • ARMv8前のシステムレジスタ指定は難しい ◦ マニュアルから探すしか無い
◦ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211k/Bhcbiigc.html 22 static inline void set_ttbr0(uint32_t *pagetable) { __asm__ volatile("mcr p15, 0, %[p], c2, c0, 0" : : [p] "r" (pagetable) : ); }
MMU Descriptor • 変換テーブルにはMMU Descriptorが詰まっている • 変換するアドレスの情報を記す • descriptorの形式は複数ある。1段めには以下の2種が作れる ◦
セクション ◦ ページテーブル • 簡単のために今回はセクションを使う ◦ 1段で変換できるので簡単 23
MMU Descriptorのセクション • セクションはVAの上位12bitを変換する ◦ 1セクション1MBを変換できる ◦ 4096エントリで全メモリを変換可能 • •
ディスクリプタ構造の詳細は以下参考 ◦ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0301h/ch06s12s02.html ◦ Figure 6.12. Translation for a 1MB section, ARMv6 format 24
セクション作成コード void vmsav6_set_mmu_section( uint32_t va, uint32_t pa, uint32_t options )
{ uint32_t idx = va >> 20; uint32_t entry = (pa & 0xfff00000) | (options & 0x7ffc) | VMSAv6_SECTION_FLAG; ttbr0_lv1_section[idx] = entry; return; } 25 void create_straight_section(void) { uint32_t entry = 0; uint32_t peri_base = 0x10000000; uint32_t entry_peri_base = peri_base >> 20; for (entry = 0; entry < 4096; entry++) { uint32_t addr = entry << 20; vmsav6_set_mmu_section( addr, addr, VMSAv6_SECTION_AP_FULLACCESS ); } }
MMUの有効化 • ARMv6ではControl Registerを制御してMMUを有効化する • 1bit目を1にするとMMUが有効になる • 参考 ◦ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0301h/Bgbciiaf.html
• 26 図はARM1176JZF-S Technical Reference Manual(Revision: r0p7)のFigure 3.26から引用 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0301h/Bgbciiaf.html
MMUを有効化するコード static inline void enable_mmu(void) { volatile uint32_t mmu_en_mask =
0; mmu_en_mask |= 1; // M = 1 mmu_en_mask |= 1 << 2; // C = 1 mmu_en_mask |= 1 << 16; // I = 1 __asm__ volatile( "mrc p15, 0, r0, c1, c0, 0;" "orr r0, r0, %[x];" "mcr p15, 0, r0, c1, c0, 0;" : : [x] "r" (mmu_en_mask) : "r0" ); } 27
その他 • MMU有効化前に以下も行う必要があるが説明省略 ◦ キャッシュのinvalidate ◦ TLBのinvalidate ◦ ドメインの設定 28
実践: MMUの有効化 • 確かめたいこと ◦ これまでの手順でMMUの有効化ができることを確認する • 検証方法 ◦ MMUを有効化してもコードの実行が止まらなければOK
▪ MMUの設定に失敗すると落ちるので…… 29
コード int main(void) { set_vector_table(0); pl011_init(STDIO, UART_CLOCK); my_puts(STDIO, "HelloWorld!\n"); init_mmu();
// MMU有効化 my_puts(STDIO, "Hello MMU World!\n"); return 0; } 30 全コードはこちら https://github.com/tnishinaga/kernelvm_hokuriku4/tree/master/mmu_enable_test 設定が正しければこの文が出てくる
実行結果 tnishinaga@tx230> ./run_qemu.sh HelloWorld! Hello MMU World! 31
結果 • MMUを有効化はうまく行った • でもVA=PAだと効果がよくわからない • もっとわかりやすい実験はできないものか? ◦ 次の実践でやろう! 32
もくじ • MMUの概要 ◦ MMUとは ▪ アクセス制御 ▪ アドレス変換 ◦
実践:アクセス制御 • 実践:MMUを動かしてみる ◦ アドレス変換の仕組み ◦ アドレス変換テーブル ◦ MMU Discriptor • 実践:アドレス変換 33
実践: アドレス変換 • 確かめたいこと ◦ VAに対応するPAが自由に変換できることを確認する • 検証方法 ◦ メモリ上のアドレス0x00500000
と 0x00600000 をMMUの機能を使って入れ 替えてみる ◦ 予めそれぞれのアドレスに値を入れ、MMU有効後に値を確認する 34 VA 0x00500000 0x00600000 PA 0x00500000 0x00600000 0x00500000 0x00600000
コード *addr_0x00500000 = 0x00500000; *addr_0x00600000 = 0x00600000; (skip) uint32_t tmp
= ttbr0_lv1_section[5]; ttbr0_lv1_section[5] = ttbr0_lv1_section[6]; ttbr0_lv1_section[6] = tmp; init_mmu(); my_puts(STDIO, "\nMMU enabled:\n"); show_5_6(); // 0x00500000と0x00600000の中身を表示 35 全コードはこちら https://github.com/tnishinaga/kernelvm_hokuriku4/blob/master/mmu_exchange_test Entry 5と6を入れ替えて PAとVAの対応を入れ替える
実行結果 MMU disabled: 0x00500000 = 00500000 0x00600000 = 00600000 Create
straight section Exchange entry 5 with 6 MMU enabled: 0x00500000 = 00600000 0x00600000 = 00500000 36 入れ替わった
結果 • 変換テーブルを入れ替えることでVAとPAの対応を変更できることが分かっ た 37
まとめ • MMUはアドレス変換とアクセス制御の機能を提供する • 昨今のOSには無くてはならない機能 • ARMのMMU有効化は基本は以下の手順でできる ◦ セクション作成 ◦
変換テーブル登録 ◦ MMUのON 38