はじめに
2ヶ月ほどLinuxでソシャゲを動かすことに全力を尽くしていたのですが、ついにヌルヌル動くようになったので方法をシェア。
NVIDIAではなく、RadeonやIntelといったMesaが使えるGPUに関しては、以下の記事をご覧ください。
やり方
構成の概要
ホストOS上のLinuxの中でQEMUを使ってLinuxのVMを動かし、そのVMの中でLXCコンテナであるWaydroidを動かします。

GPU目線だと、ホストOSのNVIDIA GPUをQEMUの機能である仮想GPUに抽象化し、それをLXCコンテナで利用するという感じです。
私の構成の詳細
ホストOS: Ubuntu25.10
VM: QEMU上のUbuntu25.10
Waydroid: Android13
ARMの翻訳レイヤー(任意): libndk
やり方
1. QEMUの環境構築
特に特別なやり方はしていないので省略。
AIや他のサイトに教えてもらってください。
最新のQEMUを使用しているか確認をしてください。特にlibvirglrendererはQEMUと一緒にインストールされていることを確認してください。
ちなみに、今回はQEMUをGUIで操作できるvirt-managerは使わず、CLIから操作します。なのでvirt-managerのインストールは不要です。
2. UbuntuのISOのダウンロード
3. 仮想ディスクを作る
任意でディスクサイズを変えてください。
qemu-img create -f qcow2 ubuntu25.img 42G
4. (任意だけどおすすめ)OVMFをコピーしてくる
VM内のUEFIの設定を保存するためのOVMFを持ってきます。
cp /usr/share/ovmf/OVMF.fd ./
5. VMを起動してOSをインストールする
以下が初回起動用のシェルスクリプトです。
#!/bin/bash
BIOS_FILE="./ovmf.fd"
qemu-system-x86_64 \
-enable-kvm \
-M q35 \
-m 8192 -smp 4 -cpu host \
-drive if=pflash,format=raw,file=$BIOS_FILE \
-drive file=ubuntu25.img,if=virtio \
-cdrom ubuntu-25.10-desktop-amd64.iso \
-usb \
-device virtio-tablet \
-device virtio-keyboard \
-device qemu-xhci,id=xhci \
-machine vmport=off \
-device virtio-vga \
-display sdl \
-audiodev pa,id=snd0 -device AC97,audiodev=snd0 \
-net nic,model=virtio-net-pci -net user,hostfwd=tcp::4444-:5555
この時点ではGPUは使用せずソフトウェアレンダリングを使用します。
GPUの設定で動かないのか、他の原因で起動できていないのかを切り分けるためです。
インストール手順は画面の指示にしたがって行ってください。
6. OSインストール後にGPUを使用して起動する
OSインストール後にGPUを使用して起動するには以下のコマンドを使用します。
#!/bin/bash
BIOS_FILE="./ovmf.fd"
qemu-system-x86_64 \
-enable-kvm \
-M q35 \
-m 8192 -smp 4 -cpu host \
-drive if=pflash,format=raw,file=$BIOS_FILE \
-drive file=ubuntu25.img,if=virtio \
-usb \
-device virtio-tablet \
-device virtio-keyboard \
-device qemu-xhci,id=xhci \
-machine vmport=off \
-device virtio-vga-gl \
-display egl-headless,rendernode=/dev/dri/renderD128 \
-display sdl,gl=on \
-audiodev pa,id=snd0 -device AC97,audiodev=snd0 \
-net nic,model=virtio-net-pci -net user,hostfwd=tcp::4444-:5555
※環境によって /dev/dri/renderD128 ではない場合(129など)があるので、ls -l /dev/dri/ コマンドでNVIDIAのデバイスを確認してください
ソフトウェアレンダリングと仮想GPUレンダリングの変更点は以下の通りです。
| ソフトウェアレンダリング | 仮想GPU | コメント |
|---|---|---|
-device virtio-vga |
-device virtio-vga-gl |
-glを付け足すことでハードウェアレンダリングを使用している |
-display egl-headless,rendernode=/dev/dri/renderD128 |
eglをヘッドレスモードに。レンダラーノードにGPUデバイスを指定。 | |
-display sdl |
-display sdl,gl=on |
gl=onを付け足すことでハードウェアレンダリングを使用している |
特にNVIDIA環境下ではegl-headlessを指定することがとても大事です。
7. GPUレンダリングができているか確認する
VM内のUbuntuの設定->システム->このシステムについて->システムの詳細で確認できます

グラフィックがこのようになっていたら成功
8. waydroidのインストール
以下をご覧ください。
9. (任意)ARMの翻訳レイヤーの導入
ARM専用アプリを動かすときに必要です
おまけ1 ブルアカの動作状況
60fps高設定でもヌルヌル動きます
やる気が出たら動作している動画撮ります
おまけ2 WaydroidとNVIDIA GPUの関係について
なぜホストOSに直接Waydroidを入れてもGPUが動かないのか
結論から言うとNVIDIA GPUはプロプライエタリなので、Android用にビルドし直せないからというのが理由になります。
詳細を以下で説明します。
前提知識1 LXCコンテナとは
WaydroidはLXCコンテナというものを使っています。
コンテナもVMもどちらも仮想化技術ですが、大きな違いは以下の通りです。
- VM: ホストOSとカーネルを共有しない
- コンテナ: ホストOSとカーネルを共有する
VMはカーネルをホストと共有していないので、Linux上でWindowsを動かせたりと違うカーネルが動かせたりします。対して、コンテナは同じカーネルのOSになるという縛りが発生しますが、その分軽量になります。
また、コンテナといえばDockerが有名ですが、一般的な利用上のLXCコンテナとDockerコンテナの違いは以下のようになります。
- LXCコンテナ: initプロセスがsystemdであることが多い
- Docker: initプロセスがアプリケーションであることが多い
よってアプリケーションを動かすための環境としてDockerがよく使われますが、LXCコンテナはOSの仮想環境として使われることが多いです。なので、Dockerはアプリケーションコンテナ、LXCはシステムコンテナと呼ばれます。
また、LXCと最近のDockerコンテナでは実装方法が全然違うらしいです。
前提知識2 GPUによるドライバーの違い
下側がカーネルに組み込まれたドライバーで上側はユーザーランド側のドライバーです。
ざっくり言うと、カーネル側はメモリに保存された機械語を受け取るのを担当し、ユーザーランド側はアプリケーションから利用しやすいように整備されたAPI(OpenGLなど)を機械語に変換する役目を負っています。
また、LXCコンテナの境界に関してもユーザーランドとカーネルの境界と同じになります。つまり、上側がLXCコンテナ内で下がユーザーランドとも言えます。
ちなみに上の図はRadeonやIntelのGPUが使用しているMesaのドライバーの図でしたが、下の図はNVIDIAの図となります。

似てはいますが大きな違いが2つあります。
- ユーザーランドのドライバーがプロプライエタリである
- カーネルランドのドライバーがそもそもカーネルにないかもしれない (カーネルだけで処理しておらず、GPU内のチップでも処理することで高速化している)
つまり、NVIDIAのGPUはプロプライエタリのユーザーランドのドライバーを使わないと動かすことができないということです。(有志によるドライバー制作はされていますが、あまりパフォーマンスが出ないというのが現状です)
AndroidのGPU環境
AndroidもLinuxなのでカーネル部分は同じですが、かなりGoogleの独自実装が多くなっています。
違いは
- DRM操作のために生えているAPIが通常のlibDRMと異なる
- OpenGLといったドライバーから生やすAPIもAndroid用に調整が必要
ということです。
さて、ここでまずMesaを動かすことを考えましょう。
幸いにして、Mesaはオープンソースなので自由に改変して調整することが可能です。つまり、Android用にDRM操作の部分と生やすAPIを調整することが可能です。つまり、MesaはAndroidのドライバーとして改造できるということですね。

今度は、Nvidiaのドライバーを動かすことを考えてみましょう。
Nvidiaドライバーは先程言及したように
- プロプライエタリなドライバーである
- NVIDIAのユーザーランド側のドライバーを使わないと動かせない
といった特徴があるので、Mesaのようにドライバーを改変することはできません。
よって、Nvidiaカードを使ってAndroidを動かすのはだいぶ難しいのです。
ちなみに、Android用に調整されたMesaが入ったAndroidイメージはWaydroidに標準装備されています。
仮想GPUで回避する
VMを使うと仮想GPUというものを使えることがあります。
仮想GPUはカーネル内でGPUの処理を行うのではなく、中間言語に変換します。
その中間言語をホストOSで受け取り、GPU処理を行い、その結果をVMに返すことでVM側からGPUを利用できる技術です。
これはLinuxカーネルに組み込まれた技術であり、Mesaにも対応しています。
これを使うことでNvidiaカードでもWaydroidでGPUを動かすことが可能になっています。


