Now, is waydroid part. You should know the core of waydroid is waydroid’s LXC, which is a LXC container, so you don’t need to put waydroid in container. And I can firmly tell you only need LXC and binder and (memfd|ashmem) and psi=1 to start waydroid’s LXC.
Step 1
So, before you try, you need to know whether your kernel support binder.
For ubuntu:
grep -i -e android -e memfd -e ashmem "/boot/config-$(uname -r)"
You will see:
CONFIG_LIVEUPDATE_MEMFD=y
CONFIG_KVM_GUEST_MEMFD=y
CONFIG_MEMFD_CREATE=y
CONFIG_X86_ANDROID_TABLETS=m
# Android
CONFIG_ANDROID_BINDER_IPC=m
# CONFIG_ANDROID_BINDER_IPC_RUST is not set
CONFIG_ANDROID_BINDERFS=m
CONFIG_ANDROID_BINDER_DEVICES=""
# end of Android
For arch linux:
zgrep -i -e android -e memfd -e ashmem /proc/config.gz
You will see:
CONFIG_LIVEUPDATE_MEMFD=y
CONFIG_KVM_GUEST_MEMFD=y
CONFIG_MEMFD_CREATE=y
CONFIG_X86_ANDROID_TABLETS=m
# Android
# CONFIG_ANDROID_BINDER_IPC is not set
CONFIG_ANDROID_BINDER_IPC_RUST=y
CONFIG_ANDROID_BINDER_DEVICES=""
# end of Android
From archwiki: The modules can either be compiled into the kernel (y), into modules (m), or not at all (n).
So for ubuntu, it has memfd compiled into the kernel and binder compiled into modules. For arch linux, it has memfd and binder compiled into the kernel. Debian’s binder is not at all, please tell me if you know how to compile binder into module.
Step 2
Install LXC, and we are good to go.
Now I’m going to give you 2 choices, choose one you like.
Q: where do you want to runwaydroid LXC?
A: Run waydroid LXC in host without install waydroid
First part is prepare binary and script and folder and config files.
Install wayland compositor and audio control service you like, I’m using labwc and pulseaudio. And start them.
As user not root: mkdir -p ~/.local/share/waydroid/data
And download waydroid image zips and unzip to /etc/waydroid-extra/images. You should know system image has 2 kinds, one with VANILLA can’t use google, one with GAPPS can use google. I’m using VANILLA.
Now switch to root.
mkdir -p /var/lib/waydroid/lxc/waydroid/
For create binder devices I copyed a part of python3 script from waydroid/tools/helpers/drivers.py at main · waydroid/waydroid · GitHub line 43 to line 65. And add a line to call the function:
allocBinderNodes("", ["anbox-binder", "anbox-hwbinder", "anbox-vndbinder"])
I put the python3 script in /var/lib/waydroid/binder.py. And chmod +x /var/lib/waydroid/binder.py.
I’m not pasting the script just to avoid license problem.
If running in real host, I guess ro.hardware.gralloc=gbm and ro.hardware.egl=mesa should work with intel GPU. DO remember to change waydroid.host.user and waydroid.host.uid and waydroid.host.gid and waydroid.host_data_path to fit your environment. Normally waydroid.wayland_display is wayland-0, you can check with ls $XDG_RUNTIME_DIR
/var/lib/waydroid/waydroid.prop
sys.use_memfd=true
ro.adb.secure=1
ro.debuggable=0
gralloc.gbm.device=/dev/dri/renderD128
debug.stagefright.ccodec=0
ro.hardware.camera=v4l2
ro.opengles.version=196610
waydroid.updater.disabled=true
waydroid.tools_version=1.6.3
ro.vndk.lite=true
ro.hardware.gralloc=default
ro.hardware.egl=swiftshader
waydroid.host.user=USERNAME
waydroid.host.uid=1000
waydroid.host.gid=1000
waydroid.host_data_path=/home/USERNAME/.local/share/waydroid/data
waydroid.background_start=false
waydroid.xdg_runtime_dir=/run/xdg
waydroid.pulse_runtime_path=/run/xdg/pulse
waydroid.wayland_display=wayland-0
waydroid.stub_sensors_hal=1
Because after ubuntu installed lxc, it create a lxcbr0, so lxc.net.0.link = lxcbr0.
/var/lib/waydroid/lxc/waydroid/config
# Waydroid LXC Config
lxc.rootfs.path = /var/lib/waydroid/rootfs
lxc.arch = x86_64
lxc.autodev = 0
# lxc.autodev.tmpfs.size = 25000000
lxc.cap.keep = audit_control sys_nice wake_alarm setpcap setgid setuid sys_ptrace sys_admin wake_alarm block_suspend sys_time net_admin net_raw net_bind_service kill dac_override dac_read_search fsetid mknod syslog chown sys_resource fowner ipc_lock sys_chroot
lxc.mount.auto = cgroup:ro sys:ro proc
lxc.console.path = none
lxc.include = /var/lib/waydroid/lxc/waydroid/config_nodes
lxc.include = /var/lib/waydroid/lxc/waydroid/config_session
# lxc.hook.post-stop = /dev/null
lxc.uts.name = waydroid
lxc.apparmor.profile = unconfined
lxc.seccomp.profile = /var/lib/waydroid/lxc/waydroid/waydroid.seccomp
lxc.no_new_privs = 1
lxc.init.cmd = /init
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = lxcbr0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.pty.max = 10
lxc.seccomp.allow_nesting = 1
/var/lib/waydroid/lxc/waydroid/config_nodes
lxc.mount.entry = tmpfs dev tmpfs nosuid 0 0
lxc.mount.entry = /dev/zero dev/zero none bind,create=file,optional 0 0
lxc.mount.entry = /dev/null dev/null none bind,create=file,optional 0 0
lxc.mount.entry = /dev/full dev/full none bind,create=file,optional 0 0
lxc.mount.entry = /dev/fuse dev/fuse none bind,create=file,optional 0 0
lxc.mount.entry = /dev/tty dev/tty none bind,create=file,optional 0 0
lxc.mount.entry = /dev/char dev/char none bind,create=dir,optional 0 0
lxc.mount.entry = /dev/dri/renderD128 dev/dri/renderD128 none bind,create=file,optional 0 0
lxc.mount.entry = /dev/fb0 dev/fb0 none bind,create=file,optional 0 0
lxc.mount.entry = /dev/dma_heap/system dev/dma_heap/system none bind,create=file,optional 0 0
lxc.mount.entry = /dev/anbox-binder dev/binder none bind,create=file,optional 0 0
lxc.mount.entry = /dev/anbox-vndbinder dev/vndbinder none bind,create=file,optional 0 0
lxc.mount.entry = /dev/anbox-hwbinder dev/hwbinder none bind,create=file,optional 0 0
lxc.mount.entry = none dev/pts devpts defaults,mode=644,ptmxmode=666,create=dir 0 0
lxc.mount.entry = /dev/uhid dev/uhid none bind,create=file,optional 0 0
lxc.mount.entry = /dev/net/tun dev/tun none bind,create=file,optional 0 0
lxc.mount.entry = /var/lib/waydroid/host-permissions vendor/etc/host-permissions none bind,optional 0 0
lxc.mount.entry = /sys/kernel/debug sys/kernel/debug none rbind,create=dir,optional 0 0
lxc.mount.entry = tmpfs mnt_extra tmpfs nodev 0 0
lxc.mount.entry = tmpfs tmp tmpfs nodev 0 0
lxc.mount.entry = tmpfs var tmpfs nodev 0 0
lxc.mount.entry = tmpfs run tmpfs nodev 0 0
DO check user id and name and compositor name.
/var/lib/waydroid/lxc/waydroid/config_session
lxc.mount.entry = tmpfs /run/xdg none create=dir 0 0
lxc.mount.entry = /run/user/1000/wayland-0 run/xdg/wayland-0 none rbind,create=file 0 0
lxc.mount.entry = /run/user/1000/pulse/native run/xdg/pulse/native none rbind,create=file 0 0
lxc.mount.entry = /home/USERNAME/.local/share/waydroid/data data none rbind 0 0
/var/lib/waydroid/lxc/waydroid/waydroid.seccomp
2
blacklist
init_module
finit_module
delete_module
_sysctl
kexec_file_load
kexec_load
reboot
open_by_handle_at errno 38
adjtimex errno 0
clock_adjtime errno 0
clock_adjtime64 errno 0
clock_settime errno 0
clock_settime64 errno 0
settimeofday errno 0
stime errno 0
add_key errno 0
keyctl errno 0
request_key errno 0
swapoff errno 0
swapon errno 0
Create this folders and preparation will be done.
mkdir -p /var/lib/waydroid/host-permissions
mkdir -p /var/lib/waydroid/overlay/vendor
mkdir -p /var/lib/waydroid/overlay_rw/system
mkdir -p /var/lib/waydroid/overlay_rw/vendor
mkdir -p /var/lib/waydroid/overlay_work/system/index
mkdir -p /var/lib/waydroid/overlay_work/system/work
mkdir -p /var/lib/waydroid/overlay_work/vendor/index
mkdir -p /var/lib/waydroid/overlay_work/vendor/work
mkdir -p /var/lib/waydroid/rootfs
Second part is run waydroid.
Make sure user has started wayland compositor and audio control service.
As root run below commands:
mkdir -p /dev/binderfs
modprobe binder_linux
mount -t binder binder /dev/binderfs
/var/lib/waydroid/binder.py
chmod 666 -R /dev/binderfs/anbox-binder
chmod 666 -R /dev/binderfs/anbox-vndbinder
chmod 666 -R /dev/binderfs/anbox-hwbinder
ln -s /dev/binderfs/anbox-hwbinder /dev/binderfs/anbox-vndbinder /dev/binderfs/anbox-binder /dev/binderfs/features /dev/binderfs/binder-control /dev/
chmod 777 -R /dev/dri/renderD128
chmod 777 -R /dev/fb0
chmod 777 -R /dev/dma_heap/system
mount -o ro /etc/waydroid-extra/images/system.img /var/lib/waydroid/rootfs
mount -t overlay -o ro,lowerdir=/var/lib/waydroid/overlay:/var/lib/waydroid/rootfs,upperdir=/var/lib/waydroid/overlay_rw/system,workdir=/var/lib/waydroid/overlay_work/system,xino=off overlay /var/lib/waydroid/rootfs
mount -o ro /etc/waydroid-extra/images/vendor.img /var/lib/waydroid/rootfs/vendor
mount -t overlay -o ro,lowerdir=/var/lib/waydroid/overlay/vendor:/var/lib/waydroid/rootfs/vendor,upperdir=/var/lib/waydroid/overlay_rw/vendor,workdir=/var/lib/waydroid/overlay_work/vendor,xino=off overlay /var/lib/waydroid/rootfs/vendor
mount -o bind /var/lib/waydroid/waydroid.prop /var/lib/waydroid/rootfs/vendor/waydroid.prop
lxc-start -P /var/lib/waydroid/lxc -n waydroid -- /init
Wait a few seconds, waydroid will show in your screen.
To verify the CT status: lxc-info -P /var/lib/waydroid/lxc -n waydroid -sH
To stop the CT with cli: lxc-stop -P /var/lib/waydroid/lxc -n waydroid -k
B: Run waydroid LXC in privileged LXC CT
Well, I’m just going to continue use CT in previous session to use wayland and pulseaudio’s socket.
Part loop:
Ubuntu has already 7 loop exist, and used 3.
Because I failed to mount img file in host then mount the folder in incus container, i only tried mount in CT.
Add this to the CT’s config:
lxc.cgroup2.devices.allow = c 10:237 rwm
lxc.cgroup2.devices.allow = b 7:4 rwm
lxc.cgroup2.devices.allow = b 7:5 rwm
lxc.cgroup2.devices.allow = b 7:6 rwm
lxc.cgroup2.devices.allow = b 7:7 rwm
lxc.mount.entry = /dev/loop-control dev/loop-control none bind,create=file 0 0
lxc.mount.entry = /dev/loop0 dev/loop0 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/loop1 dev/loop1 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/loop2 dev/loop2 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/loop3 dev/loop3 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/loop4 dev/loop4 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/loop5 dev/loop5 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/loop6 dev/loop6 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/loop7 dev/loop7 none bind,optional,create=file 0 0
lxc.mount.entry = /etc/waydroid-extra/images etc/waydroid-extra/images none bind,create=dir,optional 0 0
Part waydroid need devices and folders
Add this to the CT’s config:
## waydroid devices
lxc.cgroup2.devices.allow = c 29:0 rwm
lxc.cgroup2.devices.allow = c 10:239 rwm
lxc.cgroup2.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/fb0 dev/fb0 none bind,create=file 0 0
lxc.mount.entry = /dev/uhid dev/uhid none bind,create=file 0 0
lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file 0 0
lxc.mount.entry = /dev/fuse dev/fuse none bind,create=file 0 0
lxc.mount.entry = /dev/dma_heap dev/dma_heap none bind,create=dir,optional 0 0
lxc.mount.entry = /dev/char dev/char none bind,create=dir,optional 0 0
Part binder:
I can still give you 2 choices, where do you want /dev/binderfs created? I recommand in CT.
A: in CT:
Add this to the CT’s config:
## binder
lxc.cgroup2.devices.allow = c 239:0 rwm
lxc.cgroup2.devices.allow = c 239:1 rwm
lxc.cgroup2.devices.allow = c 239:2 rwm
lxc.cgroup2.devices.allow = c 239:3 rwm
/dev/binderfs cannot exist in host, in host run:
modprobe binder_linux
B: in host:
Add this to the CT’s config:
## binder
lxc.cgroup2.devices.allow = c 239:0 rwm
lxc.cgroup2.devices.allow = c 239:1 rwm
lxc.cgroup2.devices.allow = c 239:2 rwm
lxc.cgroup2.devices.allow = c 239:3 rwm
lxc.mount.entry = /dev/binderfs dev/binderfs none bind,create=dir,optional 0 0
/var/lib/waydroid/binder.py is a part of python3 script from waydroid/tools/helpers/drivers.py at main · waydroid/waydroid · GitHub line 43 to line 65. And add a line to call the function:
allocBinderNodes("", ["anbox-binder", "anbox-hwbinder", "anbox-vndbinder"])
In host run:
modprobe binder_linux
mkdir -p /dev/binderfs
mount -t binder binder /dev/binderfs
/var/lib/waydroid/binder.py
chmod 666 -R /dev/binderfs/anbox-binder
chmod 666 -R /dev/binderfs/anbox-vndbinder
chmod 666 -R /dev/binderfs/anbox-hwbinder
In CT run:
ln -s /dev/binderfs/anbox-hwbinder /dev/binderfs/anbox-vndbinder /dev/binderfs/anbox-binder /dev/binderfs/features /dev/binderfs/binder-control /dev/
Now everything waydroid depends on exist in the CT.
Part prepare script and folder and config files
Do what’s in “Run waydroid LXC in host without install waydroid” in the CT, except /var/lib/waydroid/lxc/waydroid/config, delete every thing start with lxc.net.0. And as user in CT create ~/.local/share/waydroid/data.
Part run waydroid LXC in CT
the full command line after a host boot then start waydroid in LXC If you choose /dev/binderfs in CT should be:
chvt 7
sudo su
modprobe binder_linux
chmod 777 -R /dev/dri/renderD128
chmod 777 -R /dev/fb0
chmod 777 -R /dev/dma_heap/system
# my LXC CT name is debian13
lxc-start --name debian13
lxc-attach --name debian13 --clear-env
mkdir -p /dev/binderfs
mount -t binder binder /dev/binderfs
/var/lib/waydroid/binder.py
chmod 666 -R /dev/binderfs/anbox-binder
chmod 666 -R /dev/binderfs/anbox-vndbinder
chmod 666 -R /dev/binderfs/anbox-hwbinder
chmod 660 /dev/tty0
chmod 660 /dev/tty7
ln -s /dev/binderfs/anbox-hwbinder /dev/binderfs/anbox-vndbinder /dev/binderfs/anbox-binder /dev/binderfs/features /dev/binderfs/binder-control /dev/
mount -o ro /etc/waydroid-extra/images/system.img /var/lib/waydroid/rootfs
mount -t overlay -o ro,lowerdir=/var/lib/waydroid/overlay:/var/lib/waydroid/rootfs,upperdir=/var/lib/waydroid/overlay_rw/system,workdir=/var/lib/waydroid/overlay_work/system,xino=off overlay /var/lib/waydroid/rootfs
mount -o ro /etc/waydroid-extra/images/vendor.img /var/lib/waydroid/rootfs/vendor
mount -t overlay -o ro,lowerdir=/var/lib/waydroid/overlay/vendor:/var/lib/waydroid/rootfs/vendor,upperdir=/var/lib/waydroid/overlay_rw/vendor,workdir=/var/lib/waydroid/overlay_work/vendor,xino=off overlay /var/lib/waydroid/rootfs/vendor
mount -o bind /var/lib/waydroid/waydroid.prop /var/lib/waydroid/rootfs/vendor/waydroid.prop
# my username in LXC CT is test
su -l test
WLR_NO_HARDWARE_CURSORS=1 labwc >/dev/null 2>&1 &
sudo lxc-start -P /var/lib/waydroid/lxc -n waydroid -- /init
the full command line after a host boot then start waydroid in LXC If you choose /dev/binderfs in host should be:
chvt 7
sudo su
modprobe binder_linux
chmod 777 -R /dev/dri/renderD128
chmod 777 -R /dev/fb0
chmod 777 -R /dev/dma_heap/system
mkdir -p /dev/binderfs
mount -t binder binder /dev/binderfs
/var/lib/waydroid/binder.py
chmod 666 -R /dev/binderfs/anbox-binder
chmod 666 -R /dev/binderfs/anbox-vndbinder
chmod 666 -R /dev/binderfs/anbox-hwbinder
lxc-start --name debian13
lxc-attach --name debian13 --clear-env
chmod 660 /dev/tty0
chmod 660 /dev/tty7
ln -s /dev/binderfs/anbox-hwbinder /dev/binderfs/anbox-vndbinder /dev/binderfs/anbox-binder /dev/binderfs/features /dev/binderfs/binder-control /dev/
mount -o ro /etc/waydroid-extra/images/system.img /var/lib/waydroid/rootfs
mount -t overlay -o ro,lowerdir=/var/lib/waydroid/overlay:/var/lib/waydroid/rootfs,upperdir=/var/lib/waydroid/overlay_rw/system,workdir=/var/lib/waydroid/overlay_work/system,xino=off overlay /var/lib/waydroid/rootfs
mount -o ro /etc/waydroid-extra/images/vendor.img /var/lib/waydroid/rootfs/vendor
mount -t overlay -o ro,lowerdir=/var/lib/waydroid/overlay/vendor:/var/lib/waydroid/rootfs/vendor,upperdir=/var/lib/waydroid/overlay_rw/vendor,workdir=/var/lib/waydroid/overlay_work/vendor,xino=off overlay /var/lib/waydroid/rootfs/vendor
mount -o bind /var/lib/waydroid/waydroid.prop /var/lib/waydroid/rootfs/vendor/waydroid.prop
su -l test
WLR_NO_HARDWARE_CURSORS=1 labwc >/dev/null 2>&1 &
sudo lxc-start -P /var/lib/waydroid/lxc -n waydroid -- /init
I’m sorry for this part I shouldn’t make assumption waydroid will work in CT.
This will not work, I make this work in below reply
Guess what I’m going to do.
apt install curl ca-certificates -y
curl -s https://repo.waydro.id | bash
apt update
apt install waydroid -y
waydroid init -f
cat >> /var/lib/waydroid/waydroid.cfg << EOF
ro.hardware.gralloc=default
ro.hardware.egl=swiftshader
EOF
waydroid upgrade -o
systemctl restart waydroid-container.service
Restart the host.
You should run:
modprobe binder_linux
chmod 777 -R /dev/dri/renderD128
chmod 777 -R /dev/fb0
chmod 777 -R /dev/dma_heap/system
If you choose /dev/binderfs in CT, you only need to get in the CT, switch to user and start wayland compositor and audio control service and run waydroid, that all.
If you choose /dev/binderfs in host, you run binderfs create commands. Get in the CT, switch to user and start wayland compositor and audio control service and run waydroid, that all.
Thank to this, even though my first language is Chinese, I can only understand half of what he said:
If you find something is wrong, please reply.