Debian on android shell

Goal: I had one old Android phone, with broken touching/gesture layer. One day, I found it on a dirty old place.

  • I wonder how can I make it better with more usability.
  • How can I make it work exactly as I needed.
  • How can I transform this old phone to a super tiny linux machine with interactive shell?
Device: xiaomi Mi4W LTE, android 6.0.1 MMB29M
Specs: Qualcomm MSM8974PRO-AC Quad-core max 2.5GHz, 3.00 GB memory, 16GB disk
Kernel: 3.4.0-gf4b741d-00690-gc8911e
Arch: armv7l

Table of Contents

A. Knowledge base

For accessing default android shell, we need adb tools. For booting operation with custom image, we use fastboot or adb reboot recovery. After accessing, with twrp and supersu we can grant root privileges because we need root permission for doing mount filesystem and totally control the whole system.

We also need busybox for expanding utilities like editing files by vi, checking network connection, … It’s done for controlling android via adb shell, but currently, linux os on android is designed for mobile, apk applications, everyday carry and easy to use for all kinds of users, also it’s not using any kind of package management like apt or yum, I nearly can do nothing on current system.

From devops/sre point of view, all I want is pushing/booting a fully linux os to my android, that’s I can do more things on this, instead of limited android os. I decided to use debian stretch with debootrap for extract custom image and init debian filesystem via chroot to current android sdcard directory.

B. Hacking / Practicing zone

1. Install adb and fastboot tools on mac

mac❯❯ brew cask install android-platform-tools

mac❯❯ adb --version
Android Debug Bridge version 1.0.40
Version 4797878
Installed as /usr/local/bin/adb

mac❯❯ fastboot --version
fastboot version 28.0.0-4797878
Installed as /usr/local/bin/fastboot

# Connect android to mac via usb 
# Verify device

mac❯❯ adb devices -l
List of devices attached
1f703708  device usb:336592896X product:cancro_wc_lte model:MI_4W device:cancro transport_id:13

2. Download then install twrp & supersu on fastboot

mac❯❯ wget ./
mac❯❯ wget ./
mac❯❯ adb push ./ /storage/self/primary/ 1 file pushed. 5.8 MB/s (6882992 bytes in 1.127s)

mac❯❯ adb reboot bootloader

mac❯❯ fastboot devices
1f703708	fastboot

mac❯❯ fastboot flash recovery ./twrp-3.1.0-0-cancro.img
Sending 'recovery' (13682 KB)                      OKAY [  0.464s]
Writing 'recovery'                                 OKAY [  0.305s]
Finished. Total time: 0.772s

mac❯❯ fastboot boot ./twrp-3.1.0-0-cancro.img
Downloading 'boot.img'                             OKAY [  0.432s]
booting                                            OKAY [  0.119s]
Finished. Total time: 0.560s

# After booted into TWRP
# Install from TWRP
# Do it on touch screen, or via twrp commandline

mac❯❯ adb shell 
android❯❯ twrp install /storage/self/primary/
android❯❯ twrp wipe cache
android❯❯ reboot

# Verify root on device

mac❯❯ adb shell
[email protected]:/ $ su -
[email protected]:/ # whoami

3. Expand utilities with busybox

mac❯❯ wget
mac❯❯ adb push busybox-armv7l /data/local/tmp
busybox-armv7l: 1 file pushed. 3.8 MB/s (1079156 bytes in 0.270s)

mac❯❯ adb shell
[email protected]:/ $ su -
[email protected]:/ # mkdir /data/busybox
[email protected]:/ # move /data/local/tmp/busybox-armv7l /data/busybox
[email protected]:/ # cd /data/busybox
[email protected]:/data/busybox # ls -l
-rwxrwxrwx shell    shell     1079156 2018-02-15 20:47 busybox-armv7l
[email protected]:/data/busybox # ./busybox-armv7l --install ./

# Use ls of busybox 
# instead of current ls on android

[email protected]:/ # which ls

[email protected]:/ # export PATH=/data/busybox:$PATH
[email protected]:/ # which ls
[email protected]:/ # which vi

4. Config / fix env variables and configuations

# Choose one: (for security mount /system back to RO when finished)
# Mount system RW: mount -o rw,remount /system
# Mount system RO: mount -o ro,remount /system

[email protected]:/ # mount -o rw,remount /system
[email protected]:/ # vi /system/etc/mkshrc
export PATH=/data/busybox:$PATH

when facing with su command like this, we need reconfigure su

# Issue with su command

[email protected]:/ $ su
su: must be suid to work properly

# Resolve

[email protected]:/ # cp /su/bin/su /data/busybox/su
[email protected]:/ # ls -lh /su/bin/su
-rwxr-xr-x    1 0        0          73.6K Sep 11 13:49 /su/bin/su
[email protected]:/ # ls -lh /data/busybox/su
-rwx------    1 0        0          73.6K Sep 11 15:58 /data/busybox/su

5. Extract debian.img from available debian system (not BSD os like Mac)

Install debootstrap then bootstrapping debian stretch image for armv7l arch

debian❯❯ apt install -y debootstrap debian-archive-keyring debian-ports-archive-keyring
debian❯❯ mkdir debian-armhf
debian❯❯ cd debian-armhf/
debian❯❯ dd if=/dev/zero of=debian.img bs=1MiB count=2000
debian❯❯ mke2fs -F debian.img
debian❯❯ mkdir debian
debian❯❯ mount -o loop debian.img debian
debian❯❯ debootstrap --arch armhf --foreign --verbose stretch debian
debian❯❯ umount debian


rsync file debian.img from debian system to mac system, then push this img to android

mac❯❯ adb push debian.img /sdcard/

6. Debootstrapping debian into android os

mac❯❯ adb shell

[email protected]:/ $ su -
[email protected]:/ # mkdir /sdcard/debian-stretch9
[email protected]:/ # losetup /dev/block/loop99 /sdcard/debian.img
[email protected]:/ # mount /dev/block/loop99 /sdcard/debian-stretch9
[email protected]:/ # chroot /sdcard/debian-stretch9 /bin/bash

export PATH=/usr/bin:/usr/sbin:/bin:$PATH
export TERM=linux
export HOME=/root
export USER=root
/debootstrap/debootstrap --second-stage

echo "nameserver" >> /etc/resolv.conf
echo " localhost" > /etc/hosts

mac❯❯ adb shell
[email protected]:/ $ su -
[email protected]:/ # chroot /sdcard/debian-stretch9 /bin/su - root
[email protected]:~# whoami #should be root
[email protected]:~# cat /etc/debian_version #9.5

7. Complete debian os with apt and networking

From the first time, I cannot use ping or apt, because Android uses a special Kernel patch that’s activated with CONFIG_ANDROID_PARANOID_NETWORK. For adding specific groups, this patch allows network access to system users that belong to certain special groups with hardcoded IDs.

mac❯❯ adb shell
[email protected]:/ $ su -
[email protected]:/ # chroot /sdcard/debian-stretch9/ /bin/su - root

[email protected]:~# groupadd -g 3001 aid_bt
[email protected]:~# groupadd -g 3002 aid_bt_net
[email protected]:~# groupadd -g 3003 aid_inet
[email protected]:~# groupadd -g 3004 aid_net_raw
[email protected]:~# groupadd -g 3005 aid_admin
[email protected]:~# usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin root
exit - relogin

[email protected]:~# grep -E "_apt" /etc/passwd

[email protected]:~# usermod -g 3003 _apt
[email protected]:~# grep -E "_apt" /etc/passwd

[email protected]:~# apt update
Ign:1 stable InRelease
Get:2 stable Release [118 kB]
Fetched 12.7 MB in 36s (351 kB/s)
Reading package lists... Done
Building dependency tree... Done
All packages are up to date.

8. Performance benchmarking

…to be continue

C. Reference

  1. TWRP fastboot
  2. ADB shell environment
  3. Mount /system RR
  4. Busybox FAQ
  5. Debian on android
  6. Chroot on android