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.7k
probe-rsの紹介と最近の貢献紹介/CELF-02-03
tnishinaga
1
340
SecurityCamp2023基板作るコース講義資料/Security Camp 2023 Lecture Materials
tnishinaga
8
2.5k
RP2040のPIOを使う話/KernelVM Hokuriku 6
tnishinaga
3
1.2k
JTAGでArmプロセッサをデバッグする方法のつづき/KernelVM_Tokyo16
tnishinaga
0
380
CMSIS-DAPの概要と使い方/KernelVM Online5
tnishinaga
0
1.7k
JTAGでarmプロセッサをデバッグする話/KernelVM Online4
tnishinaga
4
3k
ARM入門/arm introduction
tnishinaga
15
12k
俺の仮想マシンルーターがこんなに遅いはずはない/ KernelVM online 1
tnishinaga
0
2.7k
Other Decks in Programming
See All in Programming
CSC305 Lecture 25
javiergs
PRO
0
130
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
260
暇に任せてProxmoxコンソール 作ってみました
karugamo
1
720
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
110
わたしの星のままで一番星になる ~ 出産を機にSIerからEC事業会社に転職した話 ~
kimura_m_29
0
180
短期間での新規プロダクト開発における「コスパの良い」Goのテスト戦略」 / kamakura.go
n3xem
2
170
見えないメモリを観測する: PHP 8.4 `pg_result_memory_size()` とSQL結果のメモリ管理
kentaroutakeda
0
130
Stackless и stackful? Корутины и асинхронность в Go
lamodatech
0
690
103 Early Hints
sugi_0000
1
220
return文におけるstd::moveについて
onihusube
1
860
StarlingMonkeyを触ってみた話 - 2024冬
syumai
3
270
Effective Signals in Angular 19+: Rules and Helpers @ngbe2024
manfredsteyer
PRO
0
130
Featured
See All Featured
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Gamification - CAS2011
davidbonilla
80
5.1k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
How to train your dragon (web standard)
notwaldorf
88
5.7k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.9k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Faster Mobile Websites
deanohume
305
30k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Bash Introduction
62gerente
608
210k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
96
Rails Girls Zürich Keynote
gr2m
94
13k
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