🙆♀️
arm64のubuntuでarm32bitのコードを実行する方法
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
Discussion