
В этой статье я поделюсь своим опытом запуска Linux на рутованом non-Pixel телефоне с Android 15 (также работает с Android 14 с ядром 6.1) c помощью Crosvm, без поддержки AVF. С доступом в Интернет, SSH, GUI и общим каталогом. Мой телефон Xiaomi Poco C65 c Android 15. С выходом Android 13 на телефонах Google Pixel в платформу был добавлен Android Virtualization Framework (AVF), основанный на гипервизоре KVM и инструментарии Crosvm. Это позволило запускать виртуальные машины с Linux. В Android 15 для устройств Google Pixel был добавлен Linux-терминал.
Шаги для запуска Linux на Android
Использование Crosvm: Для загрузки Debian я использую Crosvm. Файл Crosvm находится по пути: /apex/com.android.virt/bin Для доступа к этой директории требуется Root на устройстве.
Компиляция ядра Linux ARM64: Сначала необходимо скомпилировать ядро Linux ARM64.
Создание образа с дистрибутивом: Я рекомендую использовать Debootstrap для создания образа с дистрибутивом.
Настройка Интернета: Поскольку настройка интернета из официального руководства не всегда работает, я использую Gvisor.
Настройка SSH: настройка виртуального сетевого устройства Tap.
GUI: Для графического интерфейса можно использовать Xserver XSDL для Android.
Настройка общих папок: Общие папки настраиваются по инструкции к Crosvm.
Установка зависимостей
Для начала необходимо установить некоторые зависимости
Откройте терминал и выполните следующие команды:
$ sudo apt install build-essential debootstrap qemu-user-static gcc-aarch64-linux-gnu atftpd nfs-kernel-server fdisk libcap-dev libgbm-dev pkg-config protobuf-compiler bc bison flex libssl-dev make libc6-dev libncurses5-dev crossbuild-essential-arm64
$ rm -rf /usr/local/go && tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz
После этого добавьте путь к Go в Ваш ~/.bashrc:
export PATH=$PATH:/usr/local/go/bin
Сборка ядра
Скачайте tarball ядра с kernel.org:
$ tar -xvf linux-x.x.xx.tar.xz
$ cd linux-x.x.xx
$ make ARCH=arm64 defconfig
Затем включите необходимые настройки: CONFIG_VSOCKETS=y
$ make menuconfig
$ CROSS_COMPILE=aarch64-linux-gnu- make ARCH=arm64 -j 8
Кросс-компиляция gVisor Proxy
Сначала кросс-компилируем gVisor Proxy для aarch64:
git clone https://github.com/containers/gvisor-tap-vsock gvisor-tap-vsock-arm64
GOARCH=arm64 make
Затем кросс-компилируем gVisor Proxy для Android:
git clone https://github.com/containers/gvisor-tap-vsock gvisor-tap-vsock-android
GOOS=android GOARCH=arm64 make
Создание rootfs
Создайте файловую систему rootfs:
$ mkdir rootfs
$ dd if=/dev/zero of=debian.img bs=1M count=32000
$ sudo mkfs.ext4 debian.img
$ sudo mount debian.img rootfs/
$ sudo debootstrap --arch=arm64 buster rootfs/
Настройте hostname и DNS:
$ echo "vm" | sudo tee ./rootfs/etc/hostname
$ sudo mkdir -p ./rootfs/etc/systemd/resolved.conf.d/
$ sudo nvim ./rootfs/etc/systemd/resolved.conf.d/dns_servers.conf
Установите DNS-серверы:
[Resolve]
DNS=8.8.8.8 1.1.1.1
Создайте пользователя и завершите настройку:
$ sudo chroot ./rootfs /bin/bash
$ useradd -m -g sudo <usermane>
$ passwd <username>
$ chsh -s /bin/bash <username>
$ exit
Скопируйте gVisor Proxy в rootfs:
$ sudo mkdir -p ./rootfs/gvisor-tap-vsock
$ sudo cp -r ./gvisor-tap-vsock-arm64/bin/* ./rootfs/gvisor-tap-vsock/bin
$ sudo umount ./rootfs
Подготовка файлов
Соберите необходимые файлы в архив:
$ tar -czvf gvisor-tap-vsock-android.tar.gz ./gvisor-tap-vsock-android/bin/*
Настройка сети
Создайте скрипт для настройки TAP-интерфейса:
$ nvim network.sh
Добавьте в него следующие строки:
#!/data/data/com.termux/files/usr/bin/sh
# https://crosvm.dev/book/devices/net.html
ip tuntap add mode tap user $USER vnet_hdr crosvm_tap
ip addr add 192.168.10.1/24 dev crosvm_tap
ip link set crosvm_tap up
# routing
sysctl net.ipv4.ip_forward=1
HOST_DEV=$(ip route get 8.8.8.8 | awk -- '{printf $5}')
iptables -t nat -A POSTROUTING -o "${HOST_DEV}" -j MASQUERADE
iptables -A FORWARD -i "${HOST_DEV}" -o crosvm_tap -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i crosvm_tap -o "${HOST_DEV}" -j ACCEPT
# the main route table needs to be added
ip rule add from all lookup main pref 1
На Android настройка сети из документации Crosvm не работает. Проблема в том, что Android не добавляет основную таблицу маршрута в свою файловую систему. Чтобы исправить эту проблему, необходимо добавить основную таблицу маршрута:
ip rule add from all lookup main pref 1
Установите Termux из F-Droid
Затем выполните следующие команды:
# termux-setup-storage
# mkdir kvm
Скопируйте необходимые файлы в директорию /data/data/com.termux/files/home/kvm:
debian.img
gvisor-tap-vsock-android.tar.gz
./linux-x.x.xx/arch/arm64/boot/Image
В Termux выполните:
# su
# cd /data/data/com.termux/files/home/kvm
# chmod +x network.sh
# ./network.sh
Затем распакуйте gVisor:
# cd /data/data/com.termux/files/home/kvm
# tar -xvf gvisor-tap-vsock-android.tar.gz
# cd gvisor-tap-vsock-android/bin
# su
# chmod +x gvproxy
# ./gvproxy -debug -listen vsock://:1024 -listen unix:///data/data/com.termux/files/home/kvm/network.sock
Запуск виртуальной машины с Debian
В новой сессии Termux выполните:
# su
# cd /apex/com.android.virt/bin
# ./crosvm run --disable-sandbox --net tap-name=crosvm_tap -s /data/data/com.termux/files/home/kvm/crosvm.sock --shared-dir "/data/data/com.termux/files/home/host_shared_dir:my_shared_tag:type=fs" -p 'init=/sbin/init' --rwroot /data/data/com.termux/files/home/kvm/debian.img /data/data/com.termux/files/home/kvm/Image --vsock 3 --mem 2048 --cpus 8
В гостевой системе
Внутри виртуальной машины выполните:
$ cd /gvisor-tap-vsock/bin
$ sudo chmod +x gvforwarder
$ sudo ./gvforwarder --debug &
Или:
$ sudo ./gvforwarder --debug > /dev/null 2>&1 &
Проверьте подключение:
$ ping 8.8.8.8
Для работы интернета необходимо включить точку доступа(раздачу интернета) и подключить какой либо девайс.
Настройка SSH
Внутри виртуальной машины выполните:
$ nvim network.sh
Добавьте в него следующие строки:
#!/bin/bash
# Replace with the actual network interface name of the guest
# (use "ip addr" to list the interfaces)
GUEST_DEV=enp0s5
sudo ip addr add 192.168.10.2/24 dev "${GUEST_DEV}"
sudo ip link set "${GUEST_DEV}" up
sudo ip route add default via 192.168.10.1
# "8.8.8.8" is chosen arbitrarily as a default, please replace with your local (or preferred global)
# DNS provider, which should be visible in `/etc/resolv.conf` on the host.
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
Замените enp0s5 на имя своего устройства
Затем выполните:
$ sudo chmod +x network.sh
$ sudo ./network.sh
Подключитесь по SSH
ssh <username>@192.168.10.2
Остановка виртуальной машины
В новой сессии Termux выполните:
# su
# cd /apex/com.android.virt/bin
# ./crosvm stop /data/data/com.termux/files/home/kvm/crosvm.sock
GUI с Xserver XSDL
В гостевой системе
Внутри виртуальной машины выполните:
$ sudo apt install tightvncserver, xfce4, xfce4-terminal, xfce4-goodies
В новой сессии Termux выполните:
# ssh -L 5901:127.0.0.1:5901 -C -N -l <username> 192.168.10.2
Установите Xserver XSDL app для android
Выполните команды со скрина приложения
Общие папки
В Termux выполните:
# mkdir host_shared_dir
# su
# cd /apex/com.android.virt/bin
# ./crosvm run --disable-sandbox --shared-dir "/data/data/com.termux/files/home/host_shared_dir:my_shared_tag:type=fs" -p 'init=/sbin/init' --rwroot /data/data/com.termux/files/home/kvm/debian.img /data/data/com.termux/files/home/kvm/Image
В гостевой системе
Внутри виртуальной машины выполните:
$ sudo su
$ mkdir /tmp/guest_shared_dir
$ mount -t virtiofs my_shared_tag /tmp/guest_shared_dir
Используйте /tmp/guest_shared_dir и /data/data/com.termux/files/home/host_shared_dir
Решение проблем
Ошибка: ping 8.8.8.8. Network is unreachable
Решение: sudo chmod +x gvforwarder
Ошибка: ERRO[0000] gvproxy exiting: cannot listen: listen unix /data/data/com.termux/files/home/kvm/network.sock: bind: address already in use
Решение: Удалить файл network.sock
Ошибка: ERRO[0000] gvproxy exiting: cannot add network services: listen tcp 127.0.0.1:2222: bind: address already in use
Решение: Перезагрузите устройство
Ошибка: ERRO[0000] socket: address family not supported by protocol
Решение: CONFIG_VSOCKETS=y
Ошибка: ERRO[0000] dhcp not found
Решение: Создать дистрибутив с dhclient
Дополнительные возможности
Вы можете запустить несколько виртуальных машин, если разместите бинарный файл Crosvm в другую директорию с образом и ядром.
Заключение
В итоге, у меня есть ARM64 Linux в виртуальной машине на телефоне. Вы можете ознакомиться с моей инструкцией на моем [GitHub](https://github.com/bvucode/crosvm-on-android).