14 KiB
零、前言说明
本教程使用systemd-networkd、systemd-resolved及nftables配置waydroid的网络,与官方基于iproute2、dnsmasq及iptables的方法不同。原因是我的qemu-KVM虚拟机网络也是基于systemd、nftables配置的,这种方法更为现代化,且比iproute2、dnsmasq及iptables繁琐的规则简单多了。
waydroid是基于lxc的容器方案,能在X86_64位CPU上运行原生安卓系统(LineageOS X86_64系统),与宿主机器共享同一个linux内核(包括你自己编译优化的内核),能直接调用宿主机显卡硬件,是目前所有安卓兼容方案中性能最高的。但是需要添加ARM转译层(libhoudini或libndk)的支持才能运行绝大多数手机app,这点教程里会教你。
waydroid的图形实现是wayland,所以你的linux桌面必须是以wayland环境启动(KDE、Gnome、sway、Hyprland、Weston等)。不要再想着你的X11了,这种老旧的协议应该早点淘汰。
教程里有一些重复的步骤,尤其是"修改waydroid的网络配置",不要觉得麻烦就跳过,这些步骤都是设计好的,没有多余的步骤。跳过的话你执行"waydroid session start"命令是不会成功的。
一、首先准备编译内核
#写在前头:不会配置编译内核的朋友,请换用Archlinux的linux-zen内核,然后在你们grub内核引导配置的末尾加上一个"psi=1"就ok了。
选中所有cgroup和namespace的子选项
CONFIG_CGROUP_FAVOR_DYNMODS=n
CONFIG_PSI=y
CONFIG_PSI_DEFAULT_DISABLED=n
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
CONFIG_VETH=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y
CONFIG_ANDROID_BINDER_DEVICES=""
CONFIG_ANDROID_BINDER_IPC_SELFTEST=n
CONFIG_EXT4_FS=y
CONFIG_EXT4_USE_FOR_EXT2=y
#"n"表示取消选择
重新编译并安装内核(参见我的内核编译教程)
二、下载waydroid和image
在pacman里添加archlinuxcn源
sudo pacman -Syu
sudo pacman -S waydroid waydroid-image
paru -S python-pyclip
sudo waydroid init -f -i /usr/share/waydroid-extra/images
sudo systemctl enable waydroid-container.service
sudo systemctl start waydroid-container.service
这里先不启动waydroid,我们先配置网络
四、配置网络(使用systemd-networkd和nftables)
更改以下脚本,删除关于iproute2和dnsmasq的设置
sudo nano /usr/lib/waydroid/data/scripts/waydroid-net.sh :
#!/bin/bash
echo "mama"
#每次waydroid更新后均需要修改此脚本
修改waydroid的网络配置
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置的那一段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
#每次waydroid更新后均需要修改此配置文件
修改systemd-networkd的网络配置
sudo nano /etc/systemd/network/waydroid0.network :
[Match]
Name=waydroid0
[Network]
Address=192.168.24.1/24
DHCPServer=true
IPForward=yes
修改nftables的防火墙配置
sudo nano /etc/nftables.conf :
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
iifname "lo" accept
iifname "waydroid0" accept
ct state established,related accept
ct state invalid drop
}
chain output {
type filter hook output priority filter; policy accept;
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname "waydroid0" oifname "wlan0" accept
iifname "wlan0" oifname "waydroid0" accept
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
iifname "waydroid0" oifname "wlan0" masquerade
}
}
#其中"wlan0"更改为你自己用于连接外部网络上网的设备,用"ip a"命令查看
启用ip转发
sudo nano /etc/sysctl.d/90-override.conf :
net.ipv4.ip_forward = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1
停用dnamasq、dhcpd、networkmanager网络服务及iptables防火墙,他们会和systemd-networkd、systemd-resolved和nftables冲突
sudo systemctl disable dnsmasq.service
sudo systemctl disable dhcpd.service
sudo systemctl disable NetworkManager.service
sudo systemctl disable iptables.service
启用systemd-networkd、systemd-resolved和nftables
sudo rm /etc/resolv.conf
sudo ln -rsf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo systemctl enable systemd-networkd.service
sudo systemctl enable systemd-resolved.service
sudo systemctl enable nftables.service
好了,重启电脑
五、为waydroid安装arm兼容层
终端里执行
完成后退出执行("ctrl+c"终止运行)
安装相关依赖及脚本
sudo pacman -S lzip sqlite
paru -S waydroid-script-git
AMD的cpu安装libndk
Intel的cpu安装libhoudini
修改waydroid的网络配置
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
六、使用waydroid
终端里执行,不终止退出
为waydroid配置网关
echo "ip route add default via 192.168.24.1" | sudo waydroid shell
#这一步很重要,不配置网关无法上网。此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
接下来即可进入waydroid图形界面开始上网
七、小技巧
列出waydroid系统里安装的包及包名
安装安卓应用
waydroid app install /path/to/apk
不启动安卓界面,只启动一个app
waydroid app launch $package-name #Can be retrieved with `waydroid app list`
有的app不识别鼠标点击事件
waydroid prop set persist.waydroid.fake_touch $package-name
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
有的app即使联网了也不能上网,浏览器能上网但不能下载东西
waydroid prop set persist.waydroid.fake_wifi $package-name
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
八、Trouble Shooting
- 一些ARM应用无法正常启动
事关libndk和libhoudini本身的兼容性,无解,只能等待google和intel更新
- 一些app和游戏无法识别键盘和鼠标,只识别触摸屏事件,极大阻碍waydroid实际使用体验
1、使用qtscrcpy,但是键盘鼠标映射配置复杂,通过adb投屏的画质差、延迟高
2、下载安卓键鼠映射app,比如panda mouse pro、八爪鱼,相关教程去B站上搜,反正我是没成功过
3、此类问题最有希望的是waydroid官方上游加入类似windows平台上mumu、雷电模拟器的键鼠映射支持,否则基本无解
目前我只找到了键盘映射触屏事件的app,即Key Mapper+Shizuku。鼠标映射触屏实在是没办法。
#不玩游戏时记得把上述键盘映射关了,免得影响日常输入法体验。
关于在映射触屏tap事件时,如何获取屏幕触击坐标?
首先开启开发者模式
设置-->关于手机-->版本号,连续点击"版本号"7次以上
然后
系统-->高级-->开发者选项-->指针位置,开启"指针位置"
此时长按鼠标左键即可在屏幕上方显示当前触击点的x,y坐标。
- 一些app启动后默认竖屏,导致屏幕翻转,鼠标操控困难
安装一款名叫Rotation的app,不用破解版也行。上网随便一搜就能找到。
右下角Rotation
如红色选中的设置为强制横屏
设置为开机启动
#注意:强制横屏后,原本你在Key Mapper里配置的竖屏app的触屏事件坐标会对应不上,需要重新配置改为横屏后的触屏坐标。
九、挂载宿主机目录到waydroid内部目录里
比如
sudo mount --bind /home/zouzi/ ~/.local/share/waydroid/data/media/0/Download/
之后你就可以在waydroid系统里的Download目录里看见你宿主机上的内容了
每一次"waydroid session start"启动后,需要先执行
sudo umount ~/.local/share/waydroid/data/media/0/Download/
再执行
sudo mount --bind /home/zouzi/ ~/.local/share/waydroid/data/media/0/Download/
否则挂载失效
若重复两次及以上挂载,waydroid系统里不会看到宿主机上的内容。这时候需要
多次重复执行
sudo umount ~/.local/share/waydroid/data/media/0/Download/
直到出现提示
umount: /home/zouzi/.local/share/waydroid/data/media/0/Download/: not mounted.
再次执行一次
sudo mount --bind /home/zouzi/ ~/.local/share/waydroid/data/media/0/Download/
就可以了
十、删除所有waydroid配置,重新安装
有的时候遇到难以修改的问题,可以删除所有的waydroid文件及配置,重新安装
sudo systemctl stop waydroid-container.service
sudo rm -rf /var/lib/waydroid/ /home/.waydroid/ ~/waydroid/ ~/.share/waydroid/ ~/.local/share/applications/*aydroid*/ ~/.local/share/waydroid/
sudo pacman -S waydroid-image #重新安装waydroid镜像,这一步必不可少
sudo waydroid init -f -i /usr/share/waydroid-extra/images
sudo systemctl start waydroid-container.service
修改waydroid的网络配置
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
执行
完成后退出
AMD的cpu安装libndk
Intel的cpu安装libhoudini
修改waydroid的网络配置
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
启动waydroid
waydroid session start
echo "ip route add default via 192.168.24.1" | sudo waydroid shell
waydroid show-full-ui
十一、如何执行root操作
waydroid里的LineageOS X86_64安卓系统并没有被预先root。
一些app可能需要通过开启安卓系统ADB调试的方式来获取root权限。如Shizuku,需要连接USB ADB调试或Wifi ADB调试后执行
adb shell sh /storage/emulated/0/Android/data/moe.shizuku.privileged.api/start.sh
才能激活运行。
但是waydroid容器不用那么复杂,只需要在宿主机上执行
即可以最高root权限进入waydroid系统内执行命令
sh /storage/emulated/0/Android/data/moe.shizuku.privileged.api/start.sh
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
不用开启USB ADB调试或Wifi ADB调试,即可成功激活Shizuku。
激活命令可以改为
echo "sh /storage/emulated/0/Android/data/moe.shizuku.privileged.api/start.sh" | sudo waydroid shell
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
在宿主机终端里执行。
十二、最终实现效果
目前,我通过自己编译配置内核,已经实现了qemu-KVM虚拟机运行win10系统办公微信写论文、waydroid容器运行安卓游戏、steam proton玩游戏、yuzu模拟器玩塞尔达旷野之息和王国之泪、pcsx2模拟器玩老PS2经典游戏、webd服务器自建网盘、mpv+SVP+Anime4k高清60帧看番剧。我的linux桌面系统正在被我调教成一个兼具办公和娱乐的高性能六边形战士,感觉十分有趣。