Androidスマートフォン/タブレットに、完全なLinuxシステムの仮想マシンをインストールする方法を紹介します。rootは不要です。
TermuxではQEMUを使ってLinux仮想マシンをエミュレート実行でき、proot-distro環境の不足を補えます。
なぜQEMUを使うのでしょうか。proot-distroが提供するLinux環境はchrootに似ていますが、それでもPodman、Docker、Snap、Flatpak、Systemdに依存するプログラムなど、動かないパッケージがあります。そのため仮想マシンが必要になります。
QEMUを使うと、x86またはARMアーキテクチャの仮想マシンをエミュレートし、完全なLinuxデスクトップシステムを実行できます。下の画像はAndroidスマートフォンでXubuntuシステムを動かしている画面です。
これでほぼすべてのソフトウェアが動かせます。画像はPodmanの実行結果です。
ついでに言うと、QEMUはLimbo PC Emulatorの背後で使われているエミュレータです。Limboの更新が止まった後でも、TermuxのQEMUパッケージで仮想マシンを動かせます。
注意: ほとんどのAndroidスマートフォンにはKVMカーネルモジュールがありません(Root化したPixelスマートフォンでpKVMを使いQEMUを高速化のみ)。そのためTermuxのQEMUは、PC版LinuxのようにKVMで仮想マシンの実行を高速化できません。KVMがない場合、QEMU仮想マシンの実行速度は非常に遅く、仮想マシン内のプログラム実行速度はTermuxネイティブパッケージの5分の1にも届かない程度です。テキストだけのプログラムならなんとか使えますが、文書作業の体験はよくありません。ゲームはなおさらです。
この実行速度を考えると、グラフィカル画面を動かさず、直接SSHで入ってプログラムを実行してもよいでしょう。
1. 環境#
- スマートフォン:Sony Xperia 5 II
- システムバージョン:Android 14
- プロセッサ:Qualcomm Snapdragon 865
- RAM:8GB
- Linux仮想マシンのシステム:Ubuntu 24.04 x86_64 (Xubuntu)
QEMUを動かすスマートフォンは、フラッグシップ級プロセッサを搭載し、RAM 8GB以上の機種が必要です。
LinuxディストリビューションはUbuntuを使います。ただしGNOMEは少し重すぎるので、ここでは軽量なXubuntuを選び、XFCEデスクトップを使います。グラフィカル画面が不要なら、Ubuntu Serverを選んでもかまいません。Ubuntu以外では、組み込みシステム向けに設計されたAlpine Linuxという、さらに軽量な選択肢もあります。起動速度も速いです。(参照:Termuxでheadless Alpine Linux QEMU仮想マシンを動かす)
KVMアクセラレーションがないため、x86とARMのどちらのアーキテクチャをエミュレートしても大きな差はありません。
ヒント:Linux PC上でQEMUを動かし(KVMがあると速いです)、システムをインストール済みのqcow2イメージを作ってからスマートフォンへ移して起動すると、システムのインストール時間を節約できます。
2. 事前依存パッケージをインストール#
AVNCなどのVNCクライアントをインストールします。
Termuxをインストールします。
Termuxを開き、バックグラウンドで実行し続けます。
Xubuntu公式サイトでISOダウンロードリンクをコピーし、wgetコマンドでダウンロードします。
pkg install wget
wget https://ftp.ubuntu-tw.net/mirror/ubuntu-cdimage/xubuntu/releases/24.04/release/xubuntu-24.04-desktop-amd64.iso- 次にQEMUとSSHパッケージをインストールします。
pkg install qemu-system-x86_64 qemu-utils qemu-common openssh vim ovmf3. Linux仮想マシンをインストール#
インストールコマンドはLinux PCでQEMUを動かすと似ていますが、AndroidにはKVMがないため少し変更します。
- 32GBの仮想ハードディスクを追加します。
qemu-img create -f qcow2 xubuntu.qcow2 32G- 起動スクリプトを追加します。
vim startubuntu.sh- 次の内容を入力します。
qemu-system-x86_64 -machine q35 \
-drive if=pflash,format=raw,read-only,file=$PREFIX/share/qemu/edk2-x86_64-code.fd \
-m 4096 \
-accel tcg,thread=multi \
-smp sockets=1,cores=4,threads=1 \
-cpu qemu64 \
-vga std \
-netdev user,id=n1,hostfwd=tcp::2222-:22 -device virtio-net,netdev=n1 \
-device intel-hda \
-usbdevice tablet \
-boot menu=on -drive file=xubuntu.qcow2 \
-vnc :0 \
-cdrom xubuntu-24.04-desktop-amd64.iso- コマンドの説明:
# x86_64の仮想マシンを実行
qemu-system-x86_64 -machine q35 \
# UEFIブートを有効化
-drive if=pflash,format=raw,read-only,file=$PREFIX/share/qemu/edk2-x86_64-code.fd \
# 4GB RAMを割り当て
-m 4096 \
# KVMがないのでTCGアクセラレーションだけを使う
-accel tcg,thread=multi \
# CPUは1ソケット、4コア、1スレッドを割り当て
-smp sockets=1,cores=4,threads=1 \
-cpu qemu64 \
# 仮想グラフィックカード
-vga std \
# virtioネットワークカードを使い、仮想マシンのSSHポートを外部アクセス用に転送
-netdev user,id=n1,hostfwd=tcp::2222-:22 -device virtio-net,netdev=n1 \
# サウンドカード
-device intel-hda \
# マウスとキーボード
-usbdevice tablet \
# 仮想ハードディスク
-boot menu=on -drive file=xubuntu.qcow2 \
# VNCサーバーを起動
-vnc :0 \
# 起動ISO
-cdrom xubuntu-24.04-desktop-amd64.iso- 起動します。
chmod +x startubuntu.sh
./startubuntu.shAVNCアプリを開き、IPに
localhost:5900を入力して、Xubuntuデスクトップへ接続します。
起動画面に入るまで待ち、Xubuntuをインストールしてからシャットダウンします。
スクリプトを編集します。
vim startubuntu.sh- cdromオプションを削除します。
qemu-system-x86_64 -machine q35 \
-drive if=pflash,format=raw,read-only,file=$PREFIX/share/qemu/edk2-x86_64-code.fd \
-m 4096 \
-accel tcg,thread=multi \
-smp sockets=1,cores=4,threads=1 \
-cpu qemu64 \
-vga std \
-netdev user,id=n1,hostfwd=tcp::2222-:22 -device virtio-net,netdev=n1 \
-device intel-hda \
-usbdevice tablet \
-boot menu=on -drive file=xubuntu.qcow2 \
-vnc :0- 以後はこのスクリプトで起動し、システムに入れるかテストします。
4. 仮想マシンへSSHする#
- Xubuntuでターミナルを開き、SSHサービスを有効化します。
sudo apt install openssh-server
sudo systemctl enable --now ssh- Termuxの左側からスライドして新しいsessionを開き、SSHで入れるか試します。
ssh user@localhost -p 2222- SSH操作はグラフィカル画面よりかなり快適なはずです。結局テキストだけですから。

5. 実際の使用感#
Xubuntuデスクトップへ起動するだけで少なくとも10分かかります。
Firefoxは開くだけで5分、Googleトップページの読み込みにさらに5分かかります。GPUアクセラレーションは期待しないでください。(備考:Snapでインストールしないでください。遅すぎます)
podman run hello-worldコマンドの実行時間は……だいたい30秒です。
まとめると、グラフィカル画面を動かすのは実用的ではありませんが、テキストだけのプログラムを動かす価値はあります。


