3月27-29日にKernelVMキャンプに参加してきました. その成果報告をここに書きます.
知らない方のために説明すると,KernelVMキャンプは東京の山奥に籠もり昼夜問わず黙々とハックし続ける非常に厳しいキャンプで……えっ? 温泉? あいまいみー? 女装ヒルクライム? 何言ってるのかさっぱりわからないですね……
やったこと1:Raspberry Pi 2 を JTAGデバッグする
以前からsyuuさんと進めているRasPi2用VMM実装のため,JTAGデバッガが欲しいという話をしていました.
この時はまだdbgbaseの話がフォーラムに上がっておらず,何故動かないのかをコードを追って探っていました. 結果,
- Cortex-A7/A15 のサポートが 0.8.0リリース以降に追加されていること
- JTAG接続先が見つかり,接続(TAP)はできていること
- バスのアクセスポイントは見つかっており,接続できていること
までわかったところで2日目の夜になり,一旦切り上げて他のことをすることにしました.
※この問題は,後日ざますさんに聞いたら数分で解決しましたとさ(あびゃ〜)
やったこと2: Raspberry Pi 2 のレジスタダンプ表示機能実装
「デバッガがうまくいかないなら,せめてシリアルからレジスタダンプを出したい」という要望を受けて,何らかの例外が飛んできた時にバンクレジスタを含めたレジスタダンプを表示するコードを作りました.
成果物は以下を参照してください.
ARMの一部のレジスタはバンクレジスタとなっており,CPUモードが切り替わるたびに,モードに合わせてレジスタが切り替わるようになっています. 詳細は,以下を参照してください.
今までこのバンクレジスタは対応するCPUモードからでないと読めないと思っていましたが,実はそうでなく,以下のようにmrs命令とmsr命令を用いれば各バンクレジスタにアクセスできました.
// IRQモードのspレジスタ値をr0にロード mrs r0, SP_irq
後は読んだものを適当にスタックに積んで,printfで出力するだけ.
動かしてみると,バンクレジスタ含めたレジスタダンプが得られました.
swi called swi_hello: cpsr = 0x600001d3 lr_und: 0xefdf6ed7 sp_und: 0xfeb74eb7 lr_abt: 0xebdd7acf sp_abt: 0xff8fcbff lr_svc: 0x00008070 sp_svc: 0x063fff5c lr_irq: 0xbf9cfd7f sp_irq: 0x00008000 lr_fiq: 0xf5feff8f sp_fiq: 0xecf5ff66 r12_fiq: 0xe7a43d5b r11_fiq: 0xdcfab3b9 r10_fiq: 0xef66f5ba r9_fiq: 0x7ff7f9d3 r8_fiq: 0x7eeb5d7f lr_usr: 0x3caafffd sp_usr: 0xb7ffa6fb r12_usr: 0x00000000 r11_usr: 0x063ffffc r10_usr: 0x7b7f7138 r9_usr: 0x7dfdf7ff r8_usr: 0xff777dff r7_usr: 0x98f1fcfb r6_usr: 0xffd77ff7 r5_usr: 0xfdfdaf5f r4_usr: 0x00008000 r3_usr: 0x00000000 r2_usr: 0x00382157 r1_usr: 0x00000000 r0_usr: 0x0000000a
どはまりぽいんと
バンクレジスタ名はcase sensitive
バンクレジスタ名はcase sensitive(大文字小文字を区別する)なので,SPとLRは大文字にしないとコンパイルエラーとなる点に注意しないといけない.(最近のgccとかllvmだと治ってるかも)
HYPモードとMONモードのバンクレジスタ
このコードはSVCモードで走っているが,HYPモードとMONモードはSVCモードより権限が上なので,SVCモードからHYPやMONモードのバンクレジスタにアクセスしに行くとアクセス違反で落ちてしまう.
HYPモードとMONモードのバンクレジスタは,モード切り替えして取りに行かないとダメかもしれない(まだ試してない).
今後の方針
- 仮想化支援機構をつかって,HYPモードと別モード間を行き来するデモを作る