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
マイコンでもRustのtestがしたい/KernelVM Kansai 11
tnishinaga
1
1.1k
BareMetalで遊ぶRaspberry Pi 5 PCIe編/KernelVM Tokyo17
tnishinaga
0
2.2k
probe-rsの紹介と最近の貢献紹介/CELF-02-03
tnishinaga
1
460
SecurityCamp2023基板作るコース講義資料/Security Camp 2023 Lecture Materials
tnishinaga
8
2.6k
RP2040のPIOを使う話/KernelVM Hokuriku 6
tnishinaga
3
1.5k
JTAGでArmプロセッサをデバッグする方法のつづき/KernelVM_Tokyo16
tnishinaga
0
500
CMSIS-DAPの概要と使い方/KernelVM Online5
tnishinaga
0
1.9k
JTAGでarmプロセッサをデバッグする話/KernelVM Online4
tnishinaga
4
3.4k
ARM入門/arm introduction
tnishinaga
14
12k
Other Decks in Programming
See All in Programming
PostgreSQLのRow Level SecurityをPHPのORMで扱う Eloquent vs Doctrine #phpcon #track2
77web
2
510
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
670
地方に住むエンジニアの残酷な現実とキャリア論
ichimichi
5
1.5k
XP, Testing and ninja testing
m_seki
3
240
Node-RED を(HTTP で)つなげる MCP サーバーを作ってみた
highu
0
120
Porting a visionOS App to Android XR
akkeylab
0
420
都市をデータで見るってこういうこと PLATEAU属性情報入門
nokonoko1203
1
610
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
350
設計やレビューに悩んでいるPHPerに贈る、クリーンなオブジェクト設計の指針たち
panda_program
6
2k
Discover Metal 4
rei315
2
130
Hack Claude Code with Claude Code
choplin
3
890
ふつうの技術スタックでアート作品を作ってみる
akira888
1
490
Featured
See All Featured
A Tale of Four Properties
chriscoyier
160
23k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Rebuilding a faster, lazier Slack
samanthasiow
82
9.1k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
20
1.3k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Become a Pro
speakerdeck
PRO
28
5.4k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Side Projects
sachag
455
42k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Adopting Sorbet at Scale
ufuk
77
9.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