Go
Linux
ARM

ARMプロセッサにFPUが搭載されているか確認する方法

ARMv7なLinuxマシン上で、GoでビルドしたARMバイナリを実行してみたら「Illegal instruction」エラーで死にました。

# uname -m
armv7l
# ./hello
Illegal instruction

このARMバイナリは下記コマンドで生成しました。GOARM環境変数が指定されていない場合はデフォルトでARMv6バイナリを生成します。

$ GOOS=linux GOARCH=arm go build

ARMv7の方がバージョンが上なのだから、ARMv6バイナリは動きそうなものです。ちなみに、ARMv7バイナリを生成してみても同じエラーで死にます。

FPUの有無を確認する方法

結論から言うと、今回作ったARMバイナリはFPU命令を含んでいるのですが、このCPUにはFPUがないためエラーで終了しています。

対象のCPUにFPUが存在するかどうかは次のように確認できます。

# cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 0 (v7l)
BogoMIPS        : 1594.16
Features        : half thumb fastmult edsp tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc09
CPU revision    : 0

Hardware        : BCM5301X
Revision        : 0000
Serial          : 0000000000000000

Featuresの行にvfpという文字列が見当たらなかったらFPU無しということになります。つまり、このCPUはARMv7命令は理解するけどFPU命令は理解できないということになります。

GoでARMのsoft-floatバイナリを生成する方法

この問題への対策ですが、Goプロジェクトのビルド時にGOARM=5でARMv5バイナリを指定すればFPU無しの機種でも動くバイナリがコンパイルできます。

$ GOOS=linux GOARCH=arm GOARM=5 go build

現状のGoコンパイラではv5用はsoft-floatバイナリしか作ることはできない一方で、v6用やv7用は必ずhard-floatバイナリになってしまうようです。

参考URL