Author Topic: Installing Devuan Linux inside Android  (Read 5782 times)

jjrv

  • Newbie
  • *
  • Posts: 13
    • View Profile
Installing Devuan Linux inside Android
« on: February 04, 2020, 06:05:37 pm »
This is a minimal hassle (relatively speaking) way to run Android and Debian style Linux simultaneously on the Cosmo, with reasonably high performance.

Android apps will keep working the same as always, for example to make calls and use a mobile-optimized browser, but you can also use Linux desktop apps, installed normally using apt-get.

As a fan of Ubuntu and Debian I chose Devuan Linux because it doesn't depend on systemd. Other criticisms aside, it's a fact that systemd isn't particularly compatible with Android, which has its own nonstandard ways for handling some of the same features.

Some of the commands were shamelessly copied from this article on Medium.

I'm probably going to stick with this setup even if an official Linux distribution appears, although a desktop environment designed for the Cosmo would work better. Hopefully that would also be Debian-based without relying too heavily on systemd, allowing porting it to my setup for simultaneous access to Android apps.

The first step is to root the device. There are workarounds like PRoot used in Termux, but rooting the Cosmo is easy and improves performance and flexibility.

Easiest way for me, mostly using a Mac, was to unlock the bootloader, install Magisk Manager by opening this link to the APK on the device, get Ninji's rooted boot image and flash it (this file is for Planet-supplied firmware version 19 only):

Code: [Select]
fastboot flash boot boot_200118213137_magisk.img
Next you should get a Linux machine and partition an SD card in two primary partitions, first type c "W95 FAT32 (LBA)" and second type 83 (Linux). The purpose of the first partition is to use as additional storage for Android. You only have one SD card slot and it's good to give Android some extra space as well. I used a 500GB SD card, made the first partition 64GB and gave Linux the rest. Now create the filesystems using:

Code: [Select]
mkfs -t vfat /dev/sdx1
mkfs -t ext4 /dev/sdx2

Replace sdx with the correct device name in the previous and next snippets...

Now you can fetch the Devuan version of debootstrap and use it to transfer a base system installer to the SD card:

Code: [Select]
mount /dev/sdx2 /mnt
git clone https://git.devuan.org/devuan-packages/debootstrap.git

cd debootstrap
sudo DEBOOTSTRAP_DIR=`pwd` ./debootstrap --verbose --arch arm64 --foreign ascii /mnt http://auto.mirror.devuan.org/merged/

The best processor architecture to choose for the Cosmo is arm64. It works and is the most modern one with precompiled binaries available. For example the older 32-bit armel also works, but there's no precompiled Chromium available for it at the moment.

The --foreign flag omits running some setup commands inside the new system. They won't work on most PCs because all the binaries are for ARM processors. We'll run the second stage later, on the Cosmo.

Ascii is the name of the latest Devuan distribution version at the time of this writing.

Now you can insert the SD card in the Cosmo. The next steps can be done from the command line on any computer that has adb installed, with the Cosmo connected over USB (or locally from the Termux shell):

Code: [Select]
adb shell
su
mkdir /data/mnt
mount /dev/block/mmcblk1p2 /data/mnt

echo 'deb http://auto.mirror.devuan.org/merged ascii main contrib non-free' > /data/mnt/etc/apt/sources.list
for f in dev dev/pts proc sys; do mount -o bind /$f /data/mnt/$f; done

export TMPDIR=/tmp
export HOME=/root
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin:/system/bin:$PATH
chroot /data/mnt /bin/bash

debootstrap/debootstrap --second-stage

The new path is needed to find any commands inside the Devuan chroot, which has binaries in wildly different places. In the end it references the old path, so that the shell could find the next chroot command still in the Android directory tree.

It takes a while and in the end it should print:

Quote
I: Base system installed successfully.
I have no name!@localhost:/#

There's now a base system installed but it's pretty broken in some ways. Exit the Devuan environment back to Android shell to fix it from outside, then re-enter:

Code: [Select]
exit

mkdir /data/mnt/dev/shm
mkdir /data/mnt/android
mount -o bind / /data/mnt/android
mount -o bind /data /data/mnt/android/data

echo nameserver `getprop net.dns1` > /data/mnt/etc/resolv.conf
ln -s /proc/mounts /data/mnt/etc/mtab

# You may need to re-run the earlier mount and for loop here if switching between adb shell and Termux.

chroot /data/mnt su -

The shm directory is required for example to avoid Chromium complaining it's out of memory. Mounting the android directory allows accessing the Android root filesystem from Linux. Fixing resolv.conf is necessary to get DNS lookups working during the setup. You may have to re-run the command when switching between mobile and wlan networks, or switch to using some public DNS server like Google's to keep it working longer term.

For some reason I cannot explain, all the mount commands seem to affect only Termux or adb but not both. So if you mount something in adb shell, it's not visible in Termux, and vice versa. Repeating the command in the other environment fixes this, so you may need to re-run the earlier for loop before the last chroot command.

The permissions are still wonky, the root user and apt-get have no Internet access. Let's fix them:

Code: [Select]
groupadd -g 3001 aid_net_bt_admin
groupadd -g 3002 aid_net_bt
groupadd -g 3003 aid_inet
groupadd -g 3004 aid_inet_raw
groupadd -g 3005 aid_inet_admin

gpasswd -a root aid_net_bt_admin
gpasswd -a root aid_net_bt
gpasswd -a root aid_inet
gpasswd -a root aid_inet_raw
gpasswd -a root aid_inet_admin

usermod -g 3003 _apt

Android has some extra layers of security based on groups, and adding the root user to those groups gives it additional privileges. Apt-get uses its own _apt user and moving it to the inet group is the easiest way to let it download packages. Now exit and re-enter the Devuan environment again to refresh the permissions and initialize apt-get:

Code: [Select]
exit
chroot /data/mnt su -

apt-get update

You now have a reasonable command line Linux setup that can be entered from Termux by running su, the mount and export commands from the above snippets, followed by chroot /data/mnt su -

A graphical desktop environment would be a nice extra. The Play Store has a free and working SDL-based X server called XServer XSDL. This way the native Android will handle graphical rendering. After installing and starting it, here's how to set up and start a minimal Xfce from inside the Devuan chroot:

Code: [Select]
apt-get install xfce4-panel xfdesktop4 xfwm4 xfce4-settings xfce4-session xfce4-terminal

export DISPLAY=:0 PULSE_SERVER=tcp:127.0.0.1:4713
startxfce4

You can get Chromium working like this:

Code: [Select]
apt-get install chromium

ln -s /var/lib/dbus/machine-id /etc/machine-id
/etc/init.d/dbus start

chromium --disable-gpu --no-sandbox

Remaining steps to figure out are setting up a user account and fixing X windows issues: keyboard layout and theme, especially widget and text sizes.
« Last Edit: February 07, 2020, 06:15:14 pm by jjrv »

NormMonkey

  • Full Member
  • ***
  • Posts: 110
    • View Profile
Installing Devuan Linux inside Android
« Reply #1 on: February 06, 2020, 12:54:50 pm »
Quote from: jjrv
This is a minimal hassle (relatively speaking) way to run Android and Debian style Linux simultaneously on the Cosmo, with reasonably high performance.

Android apps will keep working the same as always, for example to make calls and use a mobile-optimized browser, but you can also use Linux desktop apps, installed normally using apt-get.

...

I'm probably going to stick with this setup even if an official Linux distribution appears, although a desktop environment designed for the Cosmo would work better. Hopefully that would also be Debian-based without relying too heavily on systemd, allowing porting it to my setup for simultaneous access to Android apps.

OMG!  This is the awesomesauce I have been dreaming of!
  • Android for daily driver phone stuff like calls, messaging and whatnot.  
  • Linux for everything else that I use my home linux machine for, except now it's in my pocket.
  • Simultaneously!  No reboot!  No being phone-offline while in linux!  (even if linux telephony were not as terrible as it is, syncing call history and SMS and other messaging between droid and linux would be annoying)
  • Shared storage between linux and Android via plentiful SDCard, and not having to re-allocate precious internal storage between the two (linux may suffer a bit from running on a slower access-time device)
  • Rooted Android via Magisk should keep most security-conscious Android apps working.
Am I right in believing that PlanetC is planning to maintain a rooted Android image?

I may wait a bit for firmware updates to settle down and stabilize before I do this, but this is everything I'm looking for out of my Cosmo!

Zarhan

  • Sr. Member
  • ****
  • Posts: 370
    • View Profile
Installing Devuan Linux inside Android
« Reply #2 on: February 06, 2020, 02:04:45 pm »
Quote from: NormMonkey
I may wait a bit for firmware updates to settle down and stabilize before I do this, but this is everything I'm looking for out of my Cosmo!

Actually...to me this looks like it should be possible to survive firmware updates. Of course you need a new rooted image for every new FW version but nothing else. I mean, we are just installing the Devuan on an sd-card and accessing it from Termux.

Are network interfaces completely accessible from Linux side? Mostly I'm interested in running stuff like Wireshark/tcpdump... I guess they are.
« Last Edit: February 06, 2020, 01:58:08 pm by Zarhan »

jjrv

  • Newbie
  • *
  • Posts: 13
    • View Profile
Installing Devuan Linux inside Android
« Reply #3 on: February 06, 2020, 03:58:04 pm »
Glad you liked this solution!

Hopefully someone in the user community would maintain an up to date Magisk-rooted boot image. Planet is distributing official Google apps and is likely under a contract that makes it all sorts of inconvenient for them to supply any image with built-in support for circumventing Google's SafetyNet...

Either way, this Linux installation method should work on any kind of rooted Android, including an official Planet one.

Even without rooting there are Linux sandboxes for Android like UserLAnd and Andronix, but rooting avoids some workarounds they use that affect performance. Linux with actual root also gets full access to all partitions of SD cards, external SSD hard drives, and the data folders of all installed apps, which helps with many use cases.

There are still various configuration issues like UI themes and X server keyboard layout that need work and I'd be delighted if anyone can share improvements.

jjrv

  • Newbie
  • *
  • Posts: 13
    • View Profile
Installing Devuan Linux inside Android
« Reply #4 on: February 06, 2020, 04:20:19 pm »
Quote from: Zarhan
Quote from: NormMonkey
I may wait a bit for firmware updates to settle down and stabilize before I do this, but this is everything I'm looking for out of my Cosmo!

Actually...to me this looks like it should be possible to survive firmware updates. Of course you need a new rooted image for every new FW version but nothing else. I mean, we are just installing the Devuan on an sd-card and accessing it from Termux.

Are network interfaces completely accessible from Linux side? Mostly I'm interested in running stuff like Wireshark/tcpdump... I guess they are.

Just verified that tcpdump works and Chrome for Android -initiated traffic is clearly visible. Mobile data is using an interface called ccmni0 and wifi is wlan0.

ifconfig reports the following interfaces with all the usual info: ccmni0, lo, p2p0, wlan0.

Wireshark seems to work, but the UI is a mess (window doesn't fit on screen).

After installing wireless-tools, iwconfig wlan0 chan 6 works but iwconfig wlan0 mode monitor gives an error:
Error for wireless request "Set Mode" (8B06) :
    SET failed on device wlan0 ; Operation not supported.

It seems I cannot eavesdrop on other packets on the wlan, only those coming to / from the Cosmo.

I can do more tests if you have specific questions.
« Last Edit: February 06, 2020, 04:43:38 pm by jjrv »

Zarhan

  • Sr. Member
  • ****
  • Posts: 370
    • View Profile
Installing Devuan Linux inside Android
« Reply #5 on: February 07, 2020, 12:02:10 pm »
I followed your instructions and got Devuan running in my Cosmo.

Thanks a lot!

Only thing so far is that apt-get complains as below, but it doesn't seem to be any sort of blocker...

E: Can not write log (Is /dev/pts mounted?) - posix_openpt (2: No such file or directory)

jjrv

  • Newbie
  • *
  • Posts: 13
    • View Profile
Installing Devuan Linux inside Android
« Reply #6 on: February 07, 2020, 04:45:12 pm »
Quote from: Zarhan
I followed your instructions and got Devuan running in my Cosmo.

Thanks a lot!

Only thing so far is that apt-get complains as below, but it doesn't seem to be any sort of blocker...

E: Can not write log (Is /dev/pts mounted?) - posix_openpt (2: No such file or directory)

Sounds like /dev/pts is not mounted. Here's what the mount command prints for me:

/dev/block/mmcblk1p2 on / type ext4 (rw,relatime,seclabel,data=ordered)
tmpfs on /dev type tmpfs (rw,nosuid,relatime,seclabel,mode=755)
devpts on /dev/pts type devpts (rw,relatime,seclabel,mode=600)
proc on /proc type proc (rw,relatime,gid=3009,hidepid=2)
sysfs on /sys type sysfs (rw,relatime,seclabel)
/dev/block/mmcblk0p36 on /android type ext4 (ro,relatime,seclabel,block_validity,delalloc,barrier,user_xattr)
/dev/block/dm-1 on /android/data type ext4 (rw,nosuid,nodev,noatime,seclabel,noauto_da_alloc,resuid=10010,resgid=1065,error
=panic,data=ordered)

There's a for loop with mount commands in the first post that you may need to re-run as root in the Termux shell, outside Devuan chroot.

Just edited the first post to add: for some reason I cannot explain, all the mount commands seem to affect only Termux or adb but not both. So if you mount something in adb shell, it's not visible in Termux, and vice versa.
« Last Edit: February 07, 2020, 05:11:03 pm by jjrv »

Zarhan

  • Sr. Member
  • ****
  • Posts: 370
    • View Profile
Installing Devuan Linux inside Android
« Reply #7 on: February 08, 2020, 03:35:49 am »
Quote from: jjrv
Just edited the first post to add: for some reason I cannot explain, all the mount commands seem to affect only Termux or adb but not both. So if you mount something in adb shell, it's not visible in Termux, and vice versa.

That's actually a good point. I guess this is because termux by default affects it's application-local context.

Anyway, I rebooted phone and then hoped to get to Linux environment from within termux.

I created this "devuan.sh" so I could access the Devuan environment after phone has been rebooted. (Yeah, need to check if the bind mounts already exist, but now I have a bigger problem).

Code: [Select]
#!/bin/sh
mount /dev/block/mmcblk1p2 /data/mnt

for f in dev dev/pts proc sys; do mount -o bind /$f /data/mnt/$f; done

export TMPDIR=/tmp
export HOME=/root
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin:/system/bin:$PATH

mount -o bind / /data/mnt/android
mount -o bind /data /data/mnt/android/data

echo nameserver `getprop net.dns1` > /data/mnt/etc/resolv.conf
chroot /data/mnt /bin/bash

When I run "tsudo ./devuan.sh" I get
chroot: failed to run command '/bin/bash': No such file or directory.

However, if I instead use "su" followed by ./devuan.sh, it works. I have no idea why.

In a more general sense, what would be the best way to drop privileges back to "standard user"? Essentially, I want to create a "normal user" instead of running as root the whole time.  Especially if I'm going to keep the android structures accessible via /android I really don't want to be able to hose my entire system with a badly placed 'rm -rf /'.

If I issue 'id' before suing, I see that my uid is 10107(u0_a107). Whould creating a /home/u0_a107 with ownership rights to that account work? What's the correct way to drop privileges in android (e.g. setuidgid doesn't seem to exist).

jjrv

  • Newbie
  • *
  • Posts: 13
    • View Profile
Installing Devuan Linux inside Android
« Reply #8 on: February 08, 2020, 02:07:06 pm »
Quote from: Zarhan
I created this "devuan.sh" so I could access the Devuan environment after phone has been rebooted. (Yeah, need to check if the bind mounts already exist, but now I have a bigger problem).

Code: [Select]
#!/bin/sh
mount /dev/block/mmcblk1p2 /data/mnt

for f in dev dev/pts proc sys; do mount -o bind /$f /data/mnt/$f; done

export TMPDIR=/tmp
export HOME=/root
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin:/system/bin:$PATH

mount -o bind / /data/mnt/android
mount -o bind /data /data/mnt/android/data

echo nameserver `getprop net.dns1` > /data/mnt/etc/resolv.conf
chroot /data/mnt /bin/bash

When I run "tsudo ./devuan.sh" I get
chroot: failed to run command '/bin/bash': No such file or directory.

However, if I instead use "su" followed by ./devuan.sh, it works. I have no idea why.

Haven't looked into setting up a proper user account yet, but noticed that Internet access might not work with that script. I'm always using this as the last command: chroot /data/mnt su -
Otherwise you might not get membership of the inet groups. You can try the "groups" command with no arguments to make sure it's not just "root", and try pinging something.

I've got 3 scripts here. The first is to avoid having to separately type su:

Code: [Select]
#!/bin/sh

su -c ./mount.sh

The mount script is pretty much the same as yours.

Finally, I've got an "enter.sh" script with just the exports and chroot. If you unnecessarily repeat the mount commands a few times, somehow it loses the ability to create new ptys so you can't get any kind of Termux (or adb) shell open at all, and have to reboot. I guess a proper solution would be a single script that checks if they're mounted first.
« Last Edit: February 08, 2020, 02:10:14 pm by jjrv »

Zarhan

  • Sr. Member
  • ****
  • Posts: 370
    • View Profile
Installing Devuan Linux inside Android
« Reply #9 on: February 08, 2020, 02:54:38 pm »
Quote from: jjrv
Finally, I've got an "enter.sh" script with just the exports and chroot. If you unnecessarily repeat the mount commands a few times, somehow it loses the ability to create new ptys so you can't get any kind of Termux (or adb) shell open at all, and have to reboot. I guess a proper solution would be a single script that checks if they're mounted first.

You are right in your observation that pinging doesn't work if I chroot to /bin/bash instead of su -.

My script now has the mount check, it's below.

Code: [Select]
#!/bin/sh
if ! grep -qs '/data/mnt/' /proc/mounts; then
  echo "Mounting Devuan mounts"
  mount /dev/block/mmcblk1p2 /data/mnt
  for f in dev dev/pts proc sys; do mount -o bind /$f /data/mnt/$f; done
  mount -o bind / /data/mnt/android
  mount -o bind /data /data/mnt/android/data
fi

export TMPDIR=/tmp
export HOME=/root
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin:/system/bin:$PATH

echo nameserver `getprop net.dns1` > /data/mnt/etc/resolv.conf
chroot /data/mnt su -

Invoke with su -c devuan.sh.

Zarhan

  • Sr. Member
  • ****
  • Posts: 370
    • View Profile
Installing Devuan Linux inside Android
« Reply #10 on: February 09, 2020, 11:06:46 am »
I also tried X, with XSDL. Works fine, however, I spotted a slight security issue where I'm not sure how to go around it.

I guess you need to allow TCP sockets for communications between X server and clients, but is there some way to bind the X server process only to localhost?

When I start XSDL it says that you can connect to this server over wifi at the current IP address or on localhost. I would prefer to only run the local applications...

jjrv

  • Newbie
  • *
  • Posts: 13
    • View Profile
Installing Devuan Linux inside Android
« Reply #11 on: February 09, 2020, 02:16:25 pm »
Quote from: Zarhan
When I start XSDL it says that you can connect to this server over wifi at the current IP address or on localhost. I would prefer to only run the local applications...

Not sure if it actually uses TCP locally, because X11 apps keep working after entering this in the Devuan shell:

Code: [Select]
iptables -A INPUT -p tcp --dport x11 -j DROP
iptables -A INPUT -p udp --dport x11 -j DROP

Can't easily test at the moment whether that blocks X11 over wifi but if I omit the dport it certainly stops Android Chrome from loading any pages, so iptables itself seems to work.
« Last Edit: February 09, 2020, 02:35:41 pm by jjrv »

jjrv

  • Newbie
  • *
  • Posts: 13
    • View Profile
Installing Devuan Linux inside Android
« Reply #12 on: February 14, 2020, 05:03:56 pm »
Here are some extra tweaks to improve the Linux desktop experience...

When starting XServer XSDL, the first screen (white background, big Powered by SDL logo) has a button at the top "CHANGE DEVICE CONFIGURATION". Press it to open a menu. Mouse emulation -> Advanced features -> Relative mouse movement turns the touchscreen into a touchpad. Pressing OK allows you to then set the mouse speed and acceleration. I prefer fast speed with no acceleration.

Tap anywhere on the second screen (black background, centered text with the first line saying "Tap the screen to change" and the last line is a 3-second countdown). First you can choose the display resolution. Native 2160x1080 is probably best. On the next screen you can choose font scaling. X0.3 sets the display DPI to roughly 120 (use xdpyinfo to verify) and makes UI widget sizes more consistent, windows generally fitting better on the screen.

Everything is quite small, but that's the downside of using desktop-optimized applications on a tiny mobile screen. Zooming the screen helps interactions with small UI elements. If you enable "Magnify with triple-tap" (Android Settings -> Accessibility -> Magnification), you can triple-tap the screen with one finger for a 2x zoom and pan around with two fingers. Triple-tap again to zoom out.

There seems to be a double tap and hold to drag gesture, but it works very inconsistently. I decided to bind the alt key to a physical mouse button for improved dragging.
This can be done from the command line:
Code: [Select]
xmodmap -e "keycode 64 = Pointer_Button1"
xkbset m

This does have the unfortunate side effect of popping up the app bar. If you prefer a different key, the xev command shows the keycode of any key you press.

A remaining major problem is the inability to enter various special characters, mainly ones that would involve the shift key on a full size keyboard. There are some issues in the SDL library and / or X server, that would be easier to fix if the fn key was exposed as a meta key inside X but it currently isn't. Here are some pointers:

https://github.com/pelya/xserver-xsdl/issues/93
Characters behind the fn key and present in the *sym= statements here seem to be the ones that cannot be entered:
https://github.com/pelya/commandergenius/bl...stuff.h#L66-L86
So depending on the Cosmo's chosen keyboard layout some will be accessible using shift and work, others using fn and fail. Characters not mentioned in the *sym= statements are not affected and their fn key combos work.

Zarhan

  • Sr. Member
  • ****
  • Posts: 370
    • View Profile
Installing Devuan Linux inside Android
« Reply #13 on: July 03, 2020, 02:25:44 am »
Hi, did you ever find a way to drop privileges after getting to the Devuan chroot?