In this Article, I will describe how to install a debian system on an android based smartphone. My device is the motorola razr i, which has an x86 based CPU. If you want to try it with another device, make sure you use armhf instead of i386, when I write something like --arch=i386. My android version is CyanogenMod 13. But other version should work as well.

Step1: bootstrapping debian

The first step is to bootstrap debian. A detailed instruction how to bootstrap debian on a phone can be found here: on my device I can skip the debootstrap second stage because of the x86 CPU.

my terminal window looked like this:

$ sudo mkdir debian_root
$ sudo debootstrap --arch=i386 stable debian_root
***much output here***
$ cd debian_root/
$ sudo tar -czf ../debian.tar.gz *
$ cd ..
$ sudo rm -r debian_root/
$ adb root
$ adb push debian.tar.gz /data/local/
822 KB/s (144053693 bytes in 170.958s)
$ adb shell
# mkdir /data/debian
# cd /data/debian/
# tar -xzf /data/local/debian.tar.gz
# rm /data/local/debian.tar.gz
# exit
$ sudo rm debian.tar.gz

Step 2: configuring debian

Now we have a debian system accessible with chroot. The documentation about configuring debian can be found here: The most things are same on a smartphone. But don’t try to install a kernel or bootloader now. It could possibly break your device! I will show the kernel installation in the third step. I will now show the important things to get debian running on a smartphone. The following is my terminal session inside the adb shell:

# export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
# export HOME=/root
# for f in dev dev/pts proc sys ; do mount -o bind /$f /data/debian/$f ; done
# cp /system/etc/firmware/* /data/debian/lib/firmware/
# chroot /data/debian /bin/bash -l
# passwd
# apt-get update
# apt-get install initramfs-tools
# cd /usr/share/initramfs-tools/scripts/
# chmod -x init-top/udev init-bottom/udev
# cd /
# mkinitramfs -o /root/initramfs.cpio.gz
***ignore warnings***

During my first attempts, I got errors about missing firmware files. Therefore I created an initramfs hook to include all firmware files. Save the following file in /etc/initramfs-tools/hooks/firmware, change the permission to 0755 and recreate the initramfs.



	echo "$PREREQ"

case $1 in
# get pre-requisites
	exit 0

. /usr/share/initramfs-tools/hook-functions
cp -r /lib/firmware ${DESTDIR}/lib/firmware

We will need the initramfs.cpio.gz file later. First we have to write the /etc/fstab file. The partition information can be taken from androids fstab. We use androids /data partition as the new / partition. The fstab for my device was the following:

$ adb shell cat /fstab.sc1
# Android fstab file.
# The filesystem that contains the filesystem checker binary (typically /system) cannot
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK

/dev/block/mmcblk0p16 /system ext4 ro,noatime wait
/dev/block/mmcblk0p14 /cache ext4 nosuid,nodev,noatime,nodelalloc,barrier=1,data=ordered wait,check
#/dev/block/panic /panic raw defaults wait
/dev/block/mmcblk0p17 /data ext4 nosuid,nodev,noatime,nodelalloc,barrier=1,data=ordered wait,check,encryptable=footer
/dev/block/mmcblk0p12 /pds ext4 nosuid,nodev,noatime,nodelalloc,barrier=1,data=ordered wait,check

# zram
/dev/block/zram0 none swap defaults zramsize=104857600

# Voldmanaged
/devices/pci0000:00/0000:00:04.0/mmc_host/mmc1 auto auto defaults voldmanaged=sdcard1:auto

# Recovery
/dev/block/mmcblk0p5 /boot emmc defaults defaults
/dev/block/mmcblk0p6 /recovery emmc defaults defaults

Now I create the new fstab by running editor /etc/fstab inside the debian chroot shell. Based on the android file it should look like this:

# <file system>        <dir>         <type>    <options>             <dump> <pass>
 /dev/mmcblk0p17        /             ext4      defaults              0      1
 /dev/mmcblk0p16        /system       ext4      ro                    0      2
 /dev/mmcblk0p14        /cache        ext4      defaults              0      2
 /dev/mmcblk0p12        /pds          ext4      defaults              0      2

2.1: installing an onscreenkeyboard

I wrote a simple onscreenkeyboard myself. It can be used in the linux text console. You can view the code on github: The installation is simple. Just do the following inside the debian chroot shell:

apt-get install git make gcc libfreetype6-dev fonts-dejavu
cd ~
git clone
cd fbkeyboard
cp fbkeyboard /usr/bin/fbkeyboard

Step 3: building and installing kernel

For this step you need two things. The kernel source code for your device and tools to pack and flash a boot image to your device. You can search in the xda forum: to find them. For my device I can find these things on the github site of HazouPH. Then you need to find the right gcc toolchain for your device on I will take i686-linux-android-4.7 because my device is x86. I downloaded these things with git:

git clone
git clone
git clone --depth=1

Now I have to configure the kernel. I will load the default config first and then change some things to get debian running. The default android config for my device is called i386_mfld_hazou_defconfig. Then I use xconfig to change the important debian configs:

mkdir kbuild
cd android_kernel_motorola_smi
make ARCH=i386 CROSS_COMPILE=../i686-linux-android-4.7/bin/i686-linux-android- O=../kbuild i386_mfld_hazou_defconfig
make ARCH=i386 CROSS_COMPILE=../i686-linux-android-4.7/bin/i686-linux-android- O=../kbuild xconfig

With xconfig I change the following things:


Now we have to set our new kernel command line. Start with something like this console=tty0 root=/dev/mmcblk0p17 androidboot.selinux=disabled. make sure you use the same root as in your fstab file. Then add your default android kernel command line. Get it with adb shell cat /proc/cmdline. For me the full cmdline is this. Set it with xconfig

CONFIG_CMDLINE="console=tty0 root=/dev/mmcblk0p17 androidboot.selinux=disabled init=/init pci=noearly vmalloc=260046848 earlyprintk=nologger hsu_dma=7 kmemleak=off androidboot.bootmedia=sdcard androidboot.hardware=sc1 androidboot.spid=xxxx:xxxx:xxxx:xxxx:xxxx:xxxx emmc_ipanic.ipanic_part_number=6 slub_max_order=2 loglevel=7 androidboot.mode=main androidboot.wakesrc=0x00004000 androidboot.bootloader=0x2025 cid=0x7 androidboot.serialno=TA23705XWD androidboot.baseband=xmm androidboot.carrier="

You can also enable CONFIG_LOGO if you want a tux logo while booting. After my first kernel build, I noticed, that fbcon didn’t work. I found out that motorola’s framebuffer driver uses some dummy methods. Because of this I had to patch my kernel source the following:

diff --git a/drivers/staging/intel_media/display/pnw/drv/psb_fb.c b/drivers/staging/intel_media/display/pnw/drv/psb_fb.c
index d74bc81..d7098b3 100644
--- a/drivers/staging/intel_media/display/pnw/drv/psb_fb.c
+++ b/drivers/staging/intel_media/display/pnw/drv/psb_fb.c
@@ -789,9 +789,9 @@ static struct fb_ops psbfb_ops = {
        .fb_blank = fb_blank_void,
        .fb_setcolreg = psbfb_setcolreg,
-       .fb_fillrect = psb_cfb_fillrect,
-       .fb_copyarea = psb_cfb_copyarea,
-       .fb_imageblit = psb_cfb_imageblit,
+       .fb_fillrect = cfb_fillrect,
+       .fb_copyarea = cfbI can boot debian._copyarea,
+       .fb_imageblit = cfb_imageblit,
        .fb_mmap = psbfb_mmap,

Now we are ready to start the kernel build:

make ARCH=i386 CROSS_COMPILE=../i686-linux-android-4.7/bin/i686-linux-android- O=../kbuild bzImage

The build process can take some time. After the kernel build we have to pack it as a boot image and flash it to the device. For this we need a working boot image. I extracted one out of a cm flashable zip file. And we need the initramfs.cpio.gz, which we created in the debian chroot.

$ cd ../Intel_bootimage_tools/
$ cp ~/download/boot.img boot.img
$ Tools/unpack boot.img bzImage_orig intramfs_orig.cpio.gz cmdline
$ adb pull /data/debian/root/initramfs.cpio.gz
$ cp ../kbuild/arch/x86/boot/bzImage bzImage
$ Tools/pack boot.img bzImage initramfs.cpio.gz cmdline boot_new.img

To flash the new boot image, the device should be in bootloader mode. You can enter it with adb reboot bootloader. My device uses the normal fastboot flash so I just have to run fastboot flash boot boot_new.img. Samsung user have to use Heimdall instead of fastboot.

Step 4: Last steps to boot debian

For the next steps, we have to be in the android recovery mode. The recovery has to support adb. I’m using the TWRP recovery. We will use android’s data partition as root partition for debian. So we move all android files into a subfolder and move all debian files into the root of /data. Then we write a simple init script to boot up the system. Run the following inside an adb shell:

cd /data
mkdir androiddata
mv * androiddata/
mv androiddata/debian/* .
mv sbin/init sbin/init_orig
cat > sbin/init

the last command will listen for input for the init script. I wrote the init script like this. When you have written the script press ctr-C to get the terminal prompt back:

#!/bin/bash --init-file
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
export HOME=/root
mount -o remount,rw /
udevd --daemon
udevadm trigger
udevadm settle
stty rows 40
fbkeyboard &

the init file has to be executable. So we run chmod 0755 sbin/init

Step 5: Booting debian

Now everything is ready and you can boot debian. You can see a photo and a screen shot at the top of this page. You get a bash prompt and a keyboard. This should be a good starting point. And it shouldn’t be to hard start systemd or Xorg from here.