🙆‍♀️

arm64のubuntuでarm32bitのコードを実行する方法

2022/04/20に公開

CPUもカーネルもarm32bitのコードに対応しているので、足りないのはライブラリだけです。

試した環境

前回の記事 Oracle Cloudでarm64のインスタンスを作ってみた の環境でやっています。

$ uname -a
Linux instance-20220420-1140 5.11.0-1028-oracle #31~20.04.1-Ubuntu SMP Wed Jan 26 14:20:52 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux

題材のソースコード

hello.c
#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
}

ネイティブでコンパイルして実行

$ gcc -o hello_native hello.c
$ file hello_native 
hello_native: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=982c4d8bebf992bf011731c4782b8ace99cd4387, for GNU/Linux 3.7.0, not stripped
$ ./hello_native 
Hello, world!

想定通り実行できました。
ちなみに、このファイルを実行するには以下のファイルが必要です。

$ ldd ./hello_native 
	linux-vdso.so.1 (0x0000ffff91d92000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff91bdd000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffff91d62000)

arm32bit 用のクロスコンパイラの準備

$ sudo apt install g++-arm-linux-gnueabihf

gccしか必要なくてもg++をインストールするのがコツです。そうするとlibcなど必要なものが全て芋づる式にインストールされます。

クロスコンパイルして実行

$ arm-linux-gnueabihf-gcc -o hello_arm32 hello.c
$ file hello_arm32
hello_arm32: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=0cfd1bce98fa5ac9fa0e155a181a3e16776cee3c, for GNU/Linux 3.2.0, not stripped

fileコマンドの結果の通り、arm32bitの実行ファイルができました。
しかし、今の状態では実行してもエラーになります。

$ ./hello_arm32
-bash: ./hello_arm32: No such file or directory

なんで "No such file or directory" のエラーになるのでしょうか?
実は ./hello_arm32を実行しようとすると、まず /lib/ld-linux-armhf.so.3 を実行します。これは上記のfileコマンドの結果にinterpreter /lib/ld-linux-armhf.so.3と記載されていることからわかります。

$ ls /lib/ld-linux-armhf.so.3
ls: cannot access '/lib/ld-linux-armhf.so.3': No such file or directory

確かにこのファイルがありません。

arm32bit用のライブラリのインストール

arm32bit用のライブラリはubuntu (Debian)のパッケージのmultiarchの機能を使ってインストールすることができます。

$ sudo dpkg --add-architecture armhf
$ sudo apt update
$ sudo apt install libc6:armhf

このように、apt install のときにリポジトリ名の後ろに:armhf とつけることで他のアーキテクチャのものをインストールすることができます。

$ ls -l /lib/ld-linux-armhf.so.3 
lrwxrwxrwx 1 root root 30 Feb 24 19:42 /lib/ld-linux-armhf.so.3 -> arm-linux-gnueabihf/ld-2.31.so

さきほど足りなかったファイルがあることが確認できました。

$ ./hello_arm32 
Hello, world!

無事に実行できました。

注意

arm64のCPUの中にはarm32の命令を実行する機能を削除してしまっているものもあります。
これはlscpuコマンドで確認できます。以下のようにop-modeの項目に32-bit があればOKです。

$ lscpu |grep op-mode
CPU op-mode(s):                  32-bit, 64-bit

参考

MultiarchHOWTO

Discussion