Most of the smartphones have quite powerful processors (better than even raspberry pi 4 has), 2 or more gigabytes of RAM and some storage that is faster than a lot of SD cards. Wouldn't it be nice if you could host a site, game server or media storage on an old smartphone instead of buying a raspberry pi? I'm here to tell you that it's not too hard. Of course smartphones don't have as much I/O as raspberry pi, lack of fast USB 3.0 and ethernet is a limiting factor. But wifi 802.11a can easily pass 100mbit and more which is enough for me.

You may know that android uses a modified version of linux kernel. That is handy and we can run some linux programs in terminal app (like termux). There are even apps like Linux Deploy that allow you to run desktop linux distro inside chroot container, but that still has limitations: no systemd support, no docker support, incomplete hardware access.
A while back I got to know about Postmarket OS. It's a linux distribution made to run on some smartphones. Sadly, there aren't that many supported devices, but don't let that stop you. On Postmarket OS wiki page are some guides that can help you.
But today I'm gonna talk about running arch linux arm on smartphones with Quallcomm CPUs (Redmi 5 Plus in this example). Most of the instructions are applicable to any CPU vendor though.


Part 1. Preparations and boot.img
First of all, you will need to unlock the bootloader. The procedure varies from manufacturer to manufacturer, but most of the time it's quite easy. I'm gonna assume that you've already done that step.
Now we need to find what partitions your device has. You can do that step either in TWRP's terminal or with rooted android terminal. Run

# ls -l /dev/block/bootdevice/by-name

We need to take note of boot and userdata partitions. On some phones firmware is stored on a separate partition. To find it, run

# mount | grep firmware

At this point we can start preparing kernel to boot our linux distribution. Find kernel sources for your device and clone them to some directory on your PC.

git clone https://github.com/M0Rf30/kernel_xiaomi_vince.git

We also need to download a toolchain for cross compilation. Linaro toolchain should work in most of the cases. Download and extract it to some directory.

After that, open a terminal in kernel sources directory

export ARCH=arm64
export CROSS_COMPILE=/path_to_toolchain/bin/aarch64-linux-android-
mkdir out

Making an output directory is not strictly necessary, but sometimes kernel sources have quirky build scripts and that might help.

make O=out vince_defconfig

Replace "vince_defconfig" with the defconfig for your device codename. All available configs can be found in arch/arm64/configs/ directory.

Now you need to check if your kernel has the correct configuration for our purpose. Refer to postmarket os kernel configuration instructions. To run docker you need to enable some additional flags, I recommend using a script to check kernel config after a successful boot. Don't forget to include "O=out" in every make command to specify the output directory.
After that, we're ready to build the kernel.

make O=out -j$(nproc --all)

If all gone well, you should have the kernel binary (Image.gz-dtb) in the out/arch/arm64/boot/ directory.

Now we need to build boot.img. Download the example ramdisk image and unpack it with initrd tools if you want to know what's inside.

# unpack_ramdisk initrd.img

You need to run it as root, because some files inside ramdisk have root owner.

Take a look inside init and init_functions. By default, it tries to find a partition with filesystem that has "root" label, mount it and start init. You might want to uncomment the part where the firmware partition is mounted, but you can skip that step if you copy the firmware to the linux root partition.

Install abootimg tool and use it to extract/build a boot.img. You need to get bootimg.cfg file from your old boot.img or from twrp recovery image for your device.

abootimg -x boot.img
rm zImage initrd.img

Copy initrd.img you downloaded and Image.gz-dtb to this directory, and run

abootimg --create newboot.img -f bootimg.cfg -r initrd.img -k Image.gz-dtb

Flash that image to your device with TWRP or fastboot

fastboot flash boot newboot.img

Part 2. Rootfs.

For this step, you might want to use an easy method: extract a premade rootfs from a premade rom for Redmi 5 Plus.
If you chose to do so, download the rom and extract the rootfs.tar.gz file.

Get an empty SD card, format it with ext4 and mount it

# mkfs.ext4 -L 'root' /dev/sdc1
# mount /dev/sdc1 /mnt/

Now extract the rootfs.tar.gz onto said SD card

# tar -xzf rootfs.tar.gz -C /mnt/

At this point it is necessary to put your phone's firmware inside /mnt/usr/lib/firmware/postmarketos/

Add your ssh key to /mnt/home/ilya/.ssh/authorized_keys to connect with ssh.

It's recommended to enable usb_networking.service.

cd /mnt/etc/systemd/system/sysinit.target.wants/
# ln -s /etc/systemd/system/usb_networking.service ./usb_networking.service

Now we can unmount the SD card.

# umount /mnt
# sync

Insert the SD card into the phone, and it should boot to the GUI (i3-wm with onboard). You can connect to WiFi by adding your network to /etc/wpa_supplicant/wpa_supplicant-wlan0.conf.
If you connect the phone to PC with USB cable, it should detect as a network interface. You should be able to use ssh.

To run docker, you need to check the kernel config. In addition to all the generally necessary flags, you should enable "devicemapper" and "overlay" flags.

A hard way would be to get the arch linux arm generic rootfs and add all the needed files.
It's important to create symlink to /lib/systemd/systemd in the root of the rootfs.
Take a look at the files in /etc/systemd/system/, /etc/udev/rules.d/ directories of example rootfs and refer to Postmarket OS wiki articles.
It's also possible to make audio work, that requires writing an alsa ucm config. I'm not gonna talk about it in this post and will make an additional post upon request.


0 Comments latest

No comments.