Back in 2018 Samsung had a beta called Linux on DeX: plug the phone into a monitor and get a real Linux desktop out of it. It was dropped with Android 10 and never came back. I always found that a shame, because the hardware in these phones has only become more capable since.
In the past few days I’ve been working on two projects that go in that direction, from a different angle: LomiriDroid and PlasmaDroid. Both run a full Linux desktop on a rooted Android phone, on the phone’s own display and GPU using DRM Hijacking, and can also drive an external monitor in a DeX-like mode.
Everything below is tested on a single device, my Galaxy Z Fold 8 (h8q) on Android 17 with its 6.12 kernel.
An important now, to get root access we are relying on GhostLock CVE / DirtyFrag exploit which to me are the state of the art root escalation as they keep the device in a clean state (bootloader locked and knox pristine)
Where this comes from #
This idea started with phosh-termux-GPU, which runs Phosh on an unrooted phone: Termux, a Fedora proot-distro container, phoc on a patched wlroots 0.19 and Turnip built from Mesa main against KGSL. Frames go out to Termux:X11 over XShm. I developed it on a Galaxy S25 and also checked it on a Z Flip 6. That project is done.
The limit of that approach is that Linux is a guest window inside Android. It never owns the display, and every frame goes through a copy. The Fold 8 prototype started as a fork of phosh-termux-gpu. The big change is having root accesses: instead of drawing into an Android window, the Linux compositor takes over the panel.
How the takeover works #
The common part lives in droid-linux-core: a launcher APK, a root controller listening on a root-only Unix socket, the display handoff, the graphics setup and a set of bridges back to Android for audio, haptics, brightness, battery, radios and time sync (NTP).
The display handoff is the interesting bit. Samsung’s msm_drm is display-only, and the hardware composer holds DRM master on /dev/dri/card0. Root takes a copy of that master with pidfd_getfd, then Mir or KWin becomes master and drives the panel. Going back to Android restores everything. SurfaceFlinger and the composer keep running in the background, and a watchdog expects a heartbeat from the session: if it goes quiet for 12 seconds, Android gets its display back.
On the GPU side we use the Adreno 840 through /dev/kgsl-3d0 with a Mesa 26.3 overlay, based on lfdevs’ mesa-for-android-container build. That gives Turnip for Vulkan and Freedreno for GL 4.6 / GLES 3.2. There is no DRM render node on this phone, so the compositor renders into Android buffers allocated through libhybris and scans them out with atomic commits, paced to 120 Hz.
Input is plain evdev: the controller grabs the devices and filters out the nodes that aren’t useful. Bluetooth keyboards and mice show up the same way.
One thing to be clear about: the guest only gets its own mount namespace. Network, PID and IPC are shared with Android, root comes from KernelSU (or Magisk), and the desktops run as root.
LomiriDroid #
LomiriDroid runs Lomiri on Mir 2 from a Debian 13 rootfs (Lomiri 0.5.0, QtMir 0.8.0, Mir 2.20.2), with a custom Mir native-output module for the takeover. It’s a development preview, not a full Ubuntu Touch.
What works so far: the shell at 2.25× scale, the OpenStore with Click installs (Calculator was the first one), the on-screen keyboard with haptics, the camera through Camera2, Wi-Fi and Bluetooth indicators, sound and Bluetooth audio.
PlasmaDroid #
PlasmaDroid runs KDE Plasma 6.7.5 on Qt 6.11.2 in a Fedora 44 container. Here there is no Mir at all: KWin runs directly with kwin_wayland --android, which needs a patch of roughly a thousand lines against KWin 6.7.5 for KGSL and the Android buffer path.
Working: touch, autorotation in all four directions, 200% scale, KDE apps, Plasma Keyboard (with the style I made for Linux4Switch), logging out back to Android and 120 Hz flip pacing.
The weak point until now was app frames. Clients are presented through zero-copy linux-dmabuf working on the device, using dma-heap buffers.
The DeX part #
Funny enough, Android itself never drove the DisplayPort output on this firmware: the link trains but reports zero modes, and the DeX tile is gone. So during a takeover Linux drives DP-1 on its own.
With a USB-C to DisplayPort monitor at 2560×1440@60, PlasmaDroid now has three modes:
- DeX: the monitor is the desktop and the phone panel is blanked.
- Combined: the monitor is a second Plasma output next to the phone panel.
- Internal: phone panel only.
Keyboards and mice can be plugged in and out during the session.
What’s missing #
- Folding the phone ends the session. No suspend, no microphone yet.
- No monitor hotplug during a session, and the display modes aren’t done on the Lomiri side.
- Zero-copy for Mir and proper fences are still open.
- Testing on various devicex/SoC and reporting
- Clear release tagging
Next on the list are gaming with Turnip and FEX, KDE Connect, tiling around the crease and a small ofono shim for telephony.
Special thanks #
To the Mesa developers behind Turnip and Freedreno, lfdevs for the Android container Mesa build, the libhybris, Mir, QtMir and Lomiri people, the KDE folks, security researchers behind GhostLock and DirtyFrag and the Termux and Termux:X11 projects that phosh-termux-GPU was built on.
Sources #
- droid-linux-core (shared base)
- LomiriDroid
- PlasmaDroid
- phosh-termux-GPU
