A while ago I mentioned this in the comment section of a video and @wendell suggested I make a post about it in the project section. It’s been a few months and I figured I should probably get around to doing it so here it is. A couple of prerequisites before we get started. Bare minimum you need a rooted android phone with busybox installed. Magisk or SuperSU is HIGHLY recommended but technically speaking not required. adb(part of the Android SDK) is more or less a requirement but you might be able to get by using a terminal emulator app. There are two ways of doing this. The first is the easy one click script that I’ve written for my own uses which you can find here: https://storage.googleapis.com/debian-chroot/installer.sh. Please note the script REQUIRES Magisk or SuperSU to work properly and may not work on all devices. It has been tested in both system and systemless based roots on two different devices(Moto X 2013(32 bit) and a Nexus 5X(64 bit)) but that doesn’t mean it works across the board. The other method is the manual way, which doesn’t require Magisk or SuperSU, involves quite a bit more work but if you truly want to do it yourself then I’ll walk through that as well. This tutorial is for arm based(both 32 and 64 bit) Android devices. If your device is x86 you can use the general concepts from the manual section but the script won’t work for you and the manual section is not designed with x86 in mind. For those that look at the script and think to themselves “god this is terribly written.” Yes I’m aware…I don’t really shell script often and there are other issues with it but ignore that…it works doesn’t it? One last thing. This tutorial is not really for beginners. You need to be comfortable with the command line and familiar enough with Android to fix your device if you break something. You are playing with root after all. Note: Commands are wrapped like this
DISCLAIMER:
I TAKE NO RESPONSIBILITY FOR ANYTHING YOU DO TO YOUR DEVICE. IT’S YOURS, NOT MINE. AS ADDED WARNING USING THE SCRIPT MOUNTS SOME ANDROID DIRECTORIES INTO YOUR INSTALL SO DELETING YOUR INSTALL WILL BRICK YOUR PHONE. IF YOU WANT TO REMOVE THE INSTALL DELETE /magisk/.core/service.d/debian, /su/su.d/debian, or /system/su.d/debian respectively AND THEN REBOOT THE DEVICE BEFORE DELETING. YOU CAN USE busybox mount
TO SEE WHAT’S MOUNTED. DOUBLE CHECK THAT NOTHING IS MOUNTED TO /data/local/Debian/mnt/system or /data/local/Debian/mnt/data I HAVE BRICKED MY PHONE TWICE BECAUSE OF THIS.
Using the Script:
- Download the script to your PC or adb shell into your device.
- If you downloaded the script to your PC(skip to step 3 if you want to download to your device directly):
- Copy the script to your phone either via MTP(drag and drop to the phone in your system file explorer) or use
adb push installer.sh /sdcard/.
from the directory where you downloaded the script. - Move the script from /sdcard to /data/local using
adb shell
or a terminal emulator. You must do this as root. To elevate to root runsu
from either the terminal emulator or adb shell. Now skip to step 4
- Downloading the script directly to your device(all commands must be run as root. Use
su
to elevate):
- Add a nameserver so that libc can resolve the googleapis domain. You can do this by running
echo "nameserver 8.8.8.8" > /etc/resolv.conf
usingadb shell
or a terminal emulator. - cd to /data/local.
- Download the file with
busybox wget http://storage.googleapis.com/debian-chroot/installer.sh
- Make the installer executable by running
busybox chmod +x installer.sh
- Run the installer:
./installer.sh
- After your phone reboots you can run
/system/xbin/setenv.sh
to launch your install from any terminal.
Doing it manually:
- Get out your Linux PC(yes you need this).
- Install
debootstrap
. - Get a debian install by running
debootstrap --foreign --arch=arm64 stable Debian https://mirrors.kernel.org/debian
replace arm64 with armhf if your device is 32bit. If your device is a unicorn and uses x86 it requires substantially less steps but I’m not covering that. - Copy the Debian folder containing your install to your device either using
adb push Debian /sdcard/.
or by using MTP. If you’ve got adbd insecure then you can probably just push it directly to /data/local. - Move the Debian folder to /data/local.
- Mount some of the needed file systems to finish the install:
busybox mount --bind /dev /data/local/Debian/dev
andbusybox mount --bind /proc /data/local/Debian/proc
- chroot into your install with
busybox chroot /data/local/Debian /bin/bash
- Setup the system environment variables:
export SHELL=/bin/bash export LD_PRELOAD= export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin export TMPDIR=/tmp
- Now we need to install all the packages that make up the base system with:
/debootstrap/debootstrap --second-stage
- When that’s done add the default debian repos to your sources
echo 'deb https://mirrors.kernel.org/debian stable main' > /etc/apt/sources.list
- Set a DNS server with
echo nameserver 8.8.8.8 > /etc/resolv.conf
- Create an aid_inet group so that users can access the internet with
groupadd -g 3003 aid_inet
- Set the _apt users primary group to aid_inet with
usermod -g aid_inet _apt
- Update the base system(should be up to date but just making sure)
apt-get update; apt-get dist-upgrade
The base install is now done but ideally we need to automate some things like mounting file systems at startup and setting environment variables when you enter the chroot. The next section will cover that.
Doing it manually pt. 2(automation):
- Make a script named debian in /magisk/.core/service.d, /su/su.d, or /system/su.d respectively based on whether or not your root is Magisk, SuperSU systemless or SuperSU system
- In the script put the following:
#!/system/bin/sh busybox mount --bind /dev /data/local/Debian/dev busybox mount --bind /dev/pts /data/local/Debian/dev/pts busybox mount --bind /proc /data/local/Debian/proc busybox mount --bind /sys /data/local/Debian/sys
- Now we need to make an easy way to enter the our environment. This script is the android side. You can save it anywhere as anything but I generally make it setenv.sh and put it in /system/xbin:
#!/system/bin/sh busybox mount -o remount,suid,dev /data busybox chroot /data/local/Debian /setenv.sh
- And this one is the debian side. Save it as setenv.sh in the root of your Debian install:
#!/bin/bash export SHELL=/bin/bash export LD_PRELOAD= export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin export TMPDIR=/tmp bash
- You can now run the script we made in step 3 to start your install.
Installing XFCE:
- Enter your install
- Install the debian package xfce4 with
apt-get install xfce4
- Install the android app XSDL which can be found on the play store
- Setup the DISPLAY environment variable according to XSDL(usually just
export DISPLAY=:0
) - Run xfce using
startxfce4
Extras:
- Using a USB type C to displayport cable with a supported phone to mirror the screen with XSDL open in tandem with a Bluetooth keyboard and mouse would allow you to basically have a portable desktop.
Q/A:
Q. Why isn’t my networking working properly???
A. The Android kernel has some added security features namely paranoid networking. Creating a group with gid 3003(traditionally named aid_inet) and then adding users to it will generally fix this issue. This can even affect root.
Q. If you’ve bricked your phone twice because you mounted /system and /data into your Debian install why does the script do that?
A. Because when I open my terminal emulator it automatically enters the chroot and I like being able to access my android files as well. Especially since 99% of the time I need to run a command that’s installed in Debian against a file outside the chroot.
Q. Why not just use Linux Deploy or one of the other Android apps out there
A. Linux Deploy and others don’t work on my Nexus 5X. I’ve tried. They worked on my old Moto X but I’ve been unable to get them working on my 5X. From looking at the logs it seems like Linux Deploy requires ar to work which is not included in busybox. I just said screw trying to figure it out or compiling ar…I’ll just roll my own.