やまものブログ

メモ書きブログです (^_^;A

ARM コプロセッサ レジスタの読み出し mrc

MRC (Move to Register from Coprocessor) を使ってみました。

.text
.global _start
_start:
	mrc	p10, 7, r0, c1, c0, 0
	bl	writeHEX32
	vmrs	r0, FPSCR
	bl	writeHEX32
	vcmp.f32 s0, s0
	mrc	p10, 7, r0, c1, c0, 0
	bl	writeHEX32
	vmrs	r0, FPSCR
	bl	writeHEX32
	mov	r0, #0
	mov	r7, #1
	svc	#0

上記で使っている writeHEX32 は以前作成した16進数表示ルーチンです。

使ってみた mrc 命令は
mrc p10, 7, r0, c1, c0, 0
ですが、これはその直後に実行している
vmrs r0, FPSCR
と等価です。

FPSCRを使っているのでコンパイラに -mfpu を指定します。
$ arm-xilinx-linux-gnueabi-as -o writeHEX32.o writeHEX32.s
$ arm-xilinx-linux-gnueabi-as -mfpu=neon -o mrc0.o mrc0.s
$ arm-xilinx-linux-gnueabi-ld writeHEX32.o mrc0.o

実行すると、mrc と vmrs の結果は一致しています。
root@zynq:~# ./a.out 
0x00000000
0x00000000
0x60000000
0x60000000

本当は mrc でアクセスしてみたかったのは、システム制御系のコプロセッサ CP15 だったのですが、それには特権モード(カーネルモード)で実行する必要あります。私の実行環境は QEMU にて Linux で動作させているので、Linuxカーネルモジュールとして組み込んで実行しなければなりませんhttps://cdn-ak.f.st-hatena.com/images/fotolife/w/wyamamo/20190812/20190812205542.gif 今使っている Linux のイメージは出来合いをダウンロードしただけで自分でビルドしていません。残念ながら、自分の現状のスキルでは壁が高いので見送りました。
ビルドした環境さえあれば、ARM用Linuxのカーネルモジュールを作成するで解説して頂いているように insmode で手軽にモジュール追加できるのですが。。。なお、この手順をビルドしたものとは違う環境を参照させて試したところ、
hello_mod: disagrees about version of symbol module_layout
insmod: can't insert 'hello_mod.ko': invalid module format
と怒られてしまいましたhttps://cdn-ak.f.st-hatena.com/images/fotolife/w/wyamamo/20190812/20190812205119.gif