🤖

Jetson nanoでx86_64のdockerイメージを動かす

2022/04/29に公開

クロスのdockerイメージを動かすにはLinuxカーネルのbinfmt_miscのしくみとstatic linkされたqemuを使用します。
Oracle Cloudのarm64のインスタンスでは特に問題なくできました。

同じことをjetson nano でやってみたらうまくいかない。
warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
というメッセージが連発して、dpkgやaptが異常終了してしまいます。
このメッセージで検索すると以下の記事がヒットしました。全く同じ状況です。

https://shintarof.hatenablog.com/entry/2020/03/21/014359
この記事では私が過去に書いた記事が引用されていました。活用してくれるのは嬉しいものです。

さて、同じことがOracle Cloudではできて、jetson nanoではできないのはなぜなのか気になります。
両者のcpuinfoを比べてみます。

Oracle
$ cat /proc/cpuinfo

...

processor	: 3
BogoMIPS	: 50.00
Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x3
CPU part	: 0xd0c
CPU revision	: 1
jetson nano
$ cat /proc/cpuinfo

...

processor	: 1
model name	: ARMv8 Processor rev 1 (v8l)
BogoMIPS	: 38.40
Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x1
CPU part	: 0xd07
CPU revision	: 1

jetson nanoの方はFeatures の項目がかなり少ないです。arm64の初期型のためです。

cpuidというのが気になります。これでいろいろ検索してみるとx86_64にはCPUIDという命令があり、これで現在実行中のCPUコアを識別することができます。これと同等のことをarm64でやるのはMultiprocessor Affinity Register (MPIDR_EL1)を読むことでできます。しかし、jetson nanoのCPUではこのレジスタはユーザーモード(EL0)からは読むことができず、getcpuというLinuxカーネルのシステムコールを呼ぶことで同等のことが実現できます。一方、 OracleのCPUではこのレジスタをユーザーモードから読むことができるようになっています。/proc/cpuinfoFeaturescpuidがこれを示しています。

warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
このメッセージの意味はCPUIDがユーザーモードから読めないということを訴えているようです。
でもそれは、qemuがgetcpuのシステムコールを呼ぶようなコードを生成すればいけるはずです。
jetson nanoで使用していたqemuのバージョンは

$ /usr/bin/qemu-x86_64-static --version
qemu-x86_64 version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.39)
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers

最新のqemuは7.0.0なので、だいぶ古いものでした。

というわけで、新しいものをソースからビルドして差し替えてみました。その方法はこの記事に書きました。
https://zenn.dev/tetsu_koba/articles/af77c1e196f1a8

その結果、問題は解消しました!
ブラボー!!

ただし、その実行速度はひどいもので全く実用にはなりません。計測していませんが、Oracleのものより10倍のオーダーで遅いです。

追記 2022.4.29

qemu 7.0.0はメジャーバージョンアップの最初のものなので、安定性にやや難があるようでした。
qemu 6.2.0に差し替えたら安定して動作しました。

関連

Momoをarm64のLinuxで(無理矢理)ビルドする

Discussion