Запуск Linux на устройствах Android без поддержки AVF

от автора

виртуальная машина Debian

виртуальная машина Debian

В этой статье я поделюсь своим опытом запуска 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

  1. Использование Crosvm: Для загрузки Debian я использую Crosvm. Файл Crosvm находится по пути: /apex/com.android.virt/bin Для доступа к этой директории требуется Root на устройстве.

  2. Компиляция ядра Linux ARM64: Сначала необходимо скомпилировать ядро Linux ARM64.

  3. Создание образа с дистрибутивом: Я рекомендую использовать Debootstrap для создания образа с дистрибутивом.

  4. Настройка Интернета: Поскольку настройка интернета из официального руководства не всегда работает, я использую Gvisor.

  5. Настройка SSH: настройка виртуального сетевого устройства Tap.

  6. GUI: Для графического интерфейса можно использовать Xserver XSDL для Android.

  7. Настройка общих папок: Общие папки настраиваются по инструкции к 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

network.sh

./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).


ссылка на оригинал статьи https://habr.com/ru/articles/921620/