Boot into a different linux distro natively on Android with init.rc manipulation of your system/boot partitions (Graphics may not be included)

Supporter
Joined
Nov 22, 2018
Messages
1,054
For building your own custom distro for your device, I used chroot-distro; magisk required
  • Boot into android and set up your device
  • Check your storage to confirm it's been sliced in half (or however you sliced it)
  • Connect to wifi and download magisk from your home screen, web browser; download termux, chroot-distro and UPDATE-Busybox.Installer.v1.36.1-ALL-signed from osm0sis
  • Install termux, update termux (pkg update && upgrade or something like that) go to magisk and install both chroot-distro and busybox installer, restart after installing the second one. You may also need to install busybox within termux (I had a weird bug where busybox from magisk wasn't detected like a week before my device just refused to charge at least 20% in 12 hrs before it turned worse than that)
  • Now use termux to install chroot-distro to your created partition
---> Move required files to root of SD Card (if you're using scripts for this)

-----> restart termux

------> ls -la /storage/

-------> su

--------> GRANT

---------> sh /storage/XXXX-XXXX/scriptname.sh
  • create a script that can install packages, device nodes, etc or do it manually (alpine.sh/debian.sh)
  • Or in TWRP/OrangeFox; extract a pre-existing ext4 distro to your newly split partition (see any script with 77* for install examples)
  • You can modify files after extracting to that distro, along with repackaging back to a ext4.img (move.sh, folder.sh, any 88*.sh) or as a tar.gz (untested in twrp, but tested in termux, just change to the partition location instead of current path).
  • No systemd distros unless you're gonna run it in a container because your kernel allows it (PID 1 is init second_stage in recovery). Also don't if you have "4GBs" or less. Just run termux with chroot-distro instead, same ram performance (most android devices runs on ram)
  1. If it does have the namespace kernels (or you can rebuild that example kernel [lucky f#*k] look into libhybris distros).
Modify a new boot.img/vendor_boot.img/whatever_usesrecovery.img
  • Now you need to modify your recovery .img ramdisk to boot into the newly installed partition (I used Android_boot_image_editor, again!)
  • You can inspect some of the files within the partitions that are accessible (That payload thing you may have done earlier)
  • You may need to use the 1.36 busybox and move it to your /system/bin folder (bash is great too).
  • Also take some /system/bin files that you may think about using with your init.rc to help boot into your ext4 linux partition (also take other arm64 binaries, osm0sis has a repository full of them)
  • Again, get the ueventd.rc for both system and vendor, combine them into a new ueventd.rc for your /system/etc if you see that /system/etc/init/hw/init.rc or /init.recovery.common.rc references them.
  • /system has exec command (at least for my system-as-root experience), but if you try to overlay or bindmount improperly it will crash on you (Unless you use Alpine, more on that below)
  • init.rc is your friend, change your /system/bin/recovery to /system/bin/realrecovery (thanks BlackSeraph and turtle) to test how your services are being used by init.rc and how your kernel operates
  • Mount the linux partition with init.rc and make their paths accessible by creating the partitions folders in the ramdisk and in init.rc
Now this part is going to sound like I'm promoting Alpine. I'm kinnnnnnda am (donate if you end up using their distro or like, any other ones):
  • Using overlayfs and bindmount method works perfectly with Alpine. The fallen 3Plus uses system-as-root, and when I bind mount the overlayfs merging of the extracted system.img from the super partition and android-rootfs.img from alpine's lxc, It easily unmounted /system and remounted the merged combination of systems (see Alphybris.zip, See! There's more!)
  • Debian immediately stops the device from running when copying that method. So glibc can't touch bionic. Musl can. I easily got internet access via script (not like I can see what I'm doing) using the iw pkg downloading from alpine's package manager. While Debian was the reason I was able to test the drm because Alpine's weston is build different (Alphybris doesn't come with it)
  • You need to put certain files within your ramdisk while also relying on the bindmount (I put /lib/ld-musl-aarch64.so.1 in my ramdisk, dunno if that helped but I was having issues discovering that alpine uses host's path and not chroot path before doing overlayfs and bindmounts and left it there)
  • Create new scripts to run as services to load everything you need with on property (see my alp_* and and_* along with my init.recovery.common.rc and init.rc)
  • "Always be testing" - The Full Nerd Network.
  • Use your /system/bin/recovery as a script to test. The shebang line at the top uses the available binary in the ramdisk. What does that mean? Well you can use if you can open and close your boot.img and put any arm64 binary in it anywhere that makes sense:
  1. #!/system/bin/sh
  2. #!/system/bin/toybox
  3. #!/system/bin/busybox
  4. #!/bin/sh
  5. #!/bin/bash
  6. #!/and/many/more
At the end of the script, apply a fallback to the real recovery as the lack of watchdog doesn't restart the device and you'll just be stuck with a bootlogo. Use:

exec /system/bin/realrecovery "$@"
  • Change /system/bin/recovery to /system/bin/realrecovery (thanks BlackSeraph and turtle for GarlicOS again) to test how your services are being used by init.rc. If you bind mount to the recovery /system with a system.img, change realrecovery back to recovery, as it will now detect the stock recovery that came with that system.img

End of part 1 (I couldn't post this because it was too long apparently)
 
Supporter
Joined
Nov 22, 2018
Messages
1,054
Part 2; Now, here's your graphical nightmare.
  1. You got your /dev/nodes. That means you know what belongs to graphics
  • You gotta problem to solve.
Got /fb*? Lucky fk. There's a bunch of framebuffers binaries built explicitly for you to use for various arm64 distros. Go be successful everywhere.

*those represents numbers.

If you have /dev/dri/card0, that's drm. Oof. You need to launch a seat(d). Weston can use drm backend if you have no /dev/tty after launching a seat. No gpu access though unless you got specific kernels that use it

Can you rebuild your kernel based on it's available distribution and your device accepts it? fcky fck fck. Rebuild your kernel. If your GPU falls under MESA, make sure you can use those kernel configs (if not, upgrade your kernel and import the existing kernel config) Go be successful.

Have more than 5GB? You can use devices built with libhybris. Even without DEVTMPFS and VT missing, as long as you have the required kernel configs for lxc those are easily modifiable as long as that distro you're using is openrc, as it uses runlevels. systemd is something I never touched again once I realized it needed PID 1 no matter what

What about a hacky way? Well, you can run HALs individually* from my tests.
  • But Libhybris requires surfaceflinger
  • Libhybris requires system_server
  • system_server requires zygote
  • So you're booting to Android instead of using selective HALs while running a different distro, what's the point?
My hacky way came to an end. The RP3+ is fine as an Android machine as long as you don't, have, issues.
  • Got it from Amazon instead of their main site. Why? Insurance baby, and I'm cashing in on it to get my payout now but Asurion (I don't recommend btw) is making me put in work just to get a claim in. As someone who worked customer service and sold insurance for a few years, I get it and it fcking sucks. Battery won't even charge unless I'm at some company using their outlet (Starbucks/Barnes&Noble tested, stealing internet not buying things because 2025 sucked and everything's passed due). Also it charges at 1% per hour at either location.
 
Supporter
Joined
Nov 22, 2018
Messages
1,054
Finishing failure:
The only thing I haven't tested with that hacky attempt with Libhybris built with Alpine is with vndservicemanager to see if that will crash the HALs that worked by themselves before I tried to run surfaceflinger without system_server running. Running my advanced_init_diagnostics_test shows it tries to run vndservicemanager in recovery's ramdisk from it's init.rc (I assume that's the _natv stock init.rc).
[ 3.096697] init: Parsing directory /system/etc/init...
[ 3.096745] init: Parsing file /system_ext/etc/init...
[ 3.096766] init: Unable to read config file '/system_ext/etc/init': open() failed: No such file or directory
[ 3.096778] init: Parsing file /product/etc/init...
[ 3.096790] init: Unable to read config file '/product/etc/init': open() failed: No such file or directory
[ 3.096812] init: Parsing file /odm/etc/init...
[ 3.096826] init: Unable to read config file '/odm/etc/init': open() failed: No such file or directory
[ 3.096838] init: Parsing directory /vendor/etc/init...
[ 3.097772] init: processing action (SetupCgroups) from (<Builtin Action>:0)
[ 3.097800] audit: type=1400 audit(1762662833.955:3): avc: denied { read } for pid=234 comm="init" name="bin" dev="rootfs" ino=6996 scontext=u:r:vendor_init:s0 tcontext=u:eek:bject_r:rootfs:s0 tclass=dir permissive=1
[ 3.099209] init: processing action (SetKptrRestrict) from (<Builtin Action>:0)
[ 3.099403] init: processing action (TestPerfEventSelinux) from (<Builtin Action>:0)
[ 3.099507] init: processing action (early-init) from (/system/etc/init/hw/init.rc:3)
[ 3.100654] audit: type=1400 audit(1762662833.959:4): avc: denied { add_name } for pid=1 comm="init" name="prefetch_cluster" scontext=u:r:init:s0 tcontext=u:eek:bject_r:sysfs:s0 tclass=dir permissive=1
[ 3.100694] audit: type=1400 audit(1762662833.959:5): avc: denied { create } for pid=1 comm="init" name="prefetch_cluster" scontext=u:r:init:s0 tcontext=u:eek:bject_r:sysfs:s0 tclass=file permissive=1
[ 3.100831] init: Command 'exec -- /system/bin/linkerconfig --target /linkerconfig/bootstrap' action=early-init (/system/etc/init/hw/init.rc:16) took 0ms and failed: Could not start exec service: Cannot find '/system/bin/linkerconfig': No such file or directory
[ 3.100887] init: Command 'copy /linkerconfig/bootstrap/ld.config.txt /linkerconfig/default/ld.config.txt' action=early-init (/system/etc/init/hw/init.rc:18) took 0ms and failed: Could not read input file '/linkerconfig/bootstrap/ld.config.txt': open() failed: No such file or directory
[ 3.101122] init: starting service 'ueventd'...
[ 3.102822] init: cpuset cgroup controller is not mounted!
[ 3.104796] init: processing action (wait_for_coldboot_done) from (<Builtin Action>:0)
[ 3.137047] ueventd: Parsing file /system/etc/ueventd.rc...
[ 3.137355] ueventd: Parsing file /vendor/ueventd.rc...
[ 3.137379] ueventd: Unable to read config file '/vendor/ueventd.rc': open() failed: No such file or directory
[ 3.137392] ueventd: Parsing file /odm/ueventd.rc...
[ 3.137406] ueventd: Unable to read config file '/odm/ueventd.rc': open() failed: No such file or directory
[ 3.137416] ueventd: Parsing file /ueventd.ums512_1h10.rc...
[ 3.384870] init: Wait for property 'ro.cold_boot_done=true' took 280ms
[ 3.384990] init: processing action (MixHwrngIntoLinuxRng) from (<Builtin Action>:0)
[ 3.385023] init: /dev/hw_random not found
[ 3.385051] init: processing action (SetMmapRndBits) from (<Builtin Action>:0)
[ 3.385449] init: processing action (KeychordInit) from (<Builtin Action>:0)
[ 3.385489] init: processing action (init) from (/system/etc/init/hw/init.rc:28)
[ 3.387117] init: Command 'symlink /system/bin /bin' action=init (/system/etc/init/hw/init.rc:41) took 0ms and failed: symlink() failed: File exists
[ 3.387204] init: Command 'symlink /system/etc /etc' action=init (/system/etc/init/hw/init.rc:42) took 0ms and failed: symlink() failed: File exists
[ 3.387396] init: Command 'mount cgroup none /acct cpuacct' action=init (/system/etc/init/hw/init.rc:44) took 0ms and failed: mount() failed: Device or resource busy
[ 3.400620] audit: type=1400 audit(1762662834.259:6): avc: denied { write } for pid=1 comm="init" name="watermark_scale_factor" dev="proc" ino=7994 scontext=u:r:init:s0 tcontext=u:eek:bject_r:proc_watermark_scale_factor:s0 tclass=file permissive=1
[ 3.400633] audit: type=1400 audit(1762662834.259:7): avc: denied { open } for pid=1 comm="init" path="/proc/sys/vm/watermark_scale_factor" dev="proc" ino=7994 scontext=u:r:init:s0 tcontext=u:eek:bject_r:proc_watermark_scale_factor:s0 tclass=file permissive=1
[ 3.403323] init: Command 'copy /dev/cpuset/cpus /dev/cpuset/foreground/cpus' action=init (/system/etc/init/hw/init.rc:190) took 0ms and failed: Could not read input file '/dev/cpuset/cpus': open() failed: No such file or directory
[ 3.403358] init: Command 'copy /dev/cpuset/mems /dev/cpuset/foreground/mems' action=init (/system/etc/init/hw/init.rc:191) took 0ms and failed: Could not read input file '/dev/cpuset/mems': open() failed: No such file or directory
[ 3.403678] init: Command 'copy /dev/cpuset/cpus /dev/cpuset/background/cpus' action=init (/system/etc/init/hw/init.rc:193) took 0ms and failed: Could not read input file '/dev/cpuset/cpus': open() failed: No such file or directory
[ 3.403707] init: Command 'copy /dev/cpuset/mems /dev/cpuset/background/mems' action=init (/system/etc/init/hw/init.rc:194) took 0ms and failed: Could not read input file '/dev/cpuset/mems': open() failed: No such file or directory
[ 3.404101] init: Command 'copy /dev/cpuset/cpus /dev/cpuset/system-background/cpus' action=init (/system/etc/init/hw/init.rc:200) took 0ms and failed: Could not read input file '/dev/cpuset/cpus': open() failed: No such file or directory
[ 3.404131] init: Command 'copy /dev/cpuset/mems /dev/cpuset/system-background/mems' action=init (/system/etc/init/hw/init.rc:201) took 0ms and failed: Could not read input file '/dev/cpuset/mems': open() failed: No such file or directory
[ 3.404435] init: Command 'copy /dev/cpuset/cpus /dev/cpuset/restricted/cpus' action=init (/system/etc/init/hw/init.rc:206) took 0ms and failed: Could not read input file '/dev/cpuset/cpus': open() failed: No such file or directory
[ 3.404470] init: Command 'copy /dev/cpuset/mems /dev/cpuset/restricted/mems' action=init (/system/etc/init/hw/init.rc:207) took 0ms and failed: Could not read input file '/dev/cpuset/mems': open() failed: No such file or directory
[ 3.404758] init: Command 'copy /dev/cpuset/cpus /dev/cpuset/top-app/cpus' action=init (/system/etc/init/hw/init.rc:210) took 0ms and failed: Could not read input file '/dev/cpuset/cpus': open() failed: No such file or directory
[ 3.404793] init: Command 'copy /dev/cpuset/mems /dev/cpuset/top-app/mems' action=init (/system/etc/init/hw/init.rc:211) took 0ms and failed: Could not read input file '/dev/cpuset/mems': open() failed: No such file or directory
[ 3.409268] init: Command 'start logd' action=init (/system/etc/init/hw/init.rc:312) took 0ms and failed: service logd not found
[ 3.409356] init: Command 'start lmkd' action=init (/system/etc/init/hw/init.rc:318) took 0ms and failed: service lmkd not found
[ 3.412250] init: Command 'start servicemanager' action=init (/system/etc/init/hw/init.rc:348) took 0ms and failed: service servicemanager not found
[ 3.412837] init: Command 'start vndservicemanager' action=init (/system/etc/init/hw/init.rc:350) took 0ms and failed: service vndservicemanager not found
[ 3.412851] init: processing action (init) from (/init.recovery.common.rc:73)
[ 3.413136] audit: type=1400 audit(1762662834.271:8): avc: denied { setcheckreqprot } for pid=1 comm="init" scontext=u:r:init:s0 tcontext=u:eek:bject_r:kernel:s0 tclass=security permissive=1
[ 3.414019] init: Command 'symlink /storage/sdcard0 /mnt/sdcard' action=init (/init.recovery.common.rc:93) took 0ms and failed: symlink() failed: File exists
[ 3.414179] init: Command 'symlink /system/etc/bluetooth /etc/bluetooth' action=init (/init.recovery.common.rc:94) took 0ms and failed: symlink() failed: File exists
[ 3.424759] audit: type=1400 audit(1762662834.283:9): avc: denied { add_name } for pid=1 comm="init" name="idVendor" scontext=u:r:init:s0 tcontext=u:eek:bject_r:sysfs_android_usb:s0 tclass=dir permissive=1
[ 3.424772] audit: type=1400 audit(1762662834.283:10): avc: denied { create } for pid=1 comm="init" name="idVendor" scontext=u:r:init:s0 tcontext=u:eek:bject_r:sysfs_android_usb:s0 tclass=file permissive=1
[04:34:01]

When you bust that TWRP boot.img open, that uses vndservicemanager.

So, does that mean for android during my alphybris tests of being able to load HALs individually, could I use vndservicemanager to see how to configure graphics since TWRP did it (still draws to the screen I believe [been a while since I examined twrp files within boot.img] based on the files that relate to drawing/graphics) Again, my device is sort of shit with it's lack of longevity. Bought in June/July 2023, only used in 2024 really for Year of the Arcade and now in 2025 for PC gaming for Year of the Fans it's been showing that it can't take a charge (only after a factory reset with SPD Flash Tool it acts like it's "normal", but it goes back to a shit battery state after like a week) so I couldn't test that as I now GIVE UP! Maybe you can? Have fun with that. I was going to test Debian with the hwclock modification after the Alphybris failure but then I had an even larger device failure with it's inability to charge at a good rate.

Or for a DRM setup (no GPU):
So yeah, you can run many commands with binaries and scripts using other distros or the current android distro in normal boot or recovery. But you're doing it, blind. With your only output being sent to the sdcard or a partition you mount and make accessible for that script while running. That you can only access when booted to normal Android or taking out your sdcard or having access to UART that can access the console if your bootloader/cmdline allows it. So yeah, you can run arm64 programs with ease and even if you don't have graphical utility, maybe you will script a bunch of phones like someone did with a bunch of PS4s https://www.techpowerup.com/284422/...-mining-farm-with-3800-playstation-4-consoles

*​

  • Perplexity has a tendency to change models while in use (and hiding that it did it!) and push comet browser which is a security nightmare if you're using it on a browser
  • It's also unfortunately the best LLM search engine for a power user who's a fact checking, proof reading machine:
  1. You can use every "official popular model" that's VC backed or just flushed the stock market empty for a few days for tech companies.
  2. When you force web search with your selected model, you can see what it uses as a search query AND see the sources it used which you can use instead of it's response
  • POE's better if you're using local documentation, here's an example but web search is left to individual users and a few poe distributors and they're specific models instead of every model you use to search the web.
  • While I said POE is better (on discord they've admitted to why they changed their subscription to points for cost and kept being honest about why do what they do instead of you know, on your website where it's more easily accessible), they're still another company. You're still kinda fcked when you're not looking. Also, electricity and water for basic living.
  • I'm done with Spreadtrum/Unisoc and Retroid
  • Lack of open source documentation and access, I'm good. What's that mean? For any future device, find out it's board and see it's available open source tools and documentation, and methods to access it to modify it to your leisure.
Why? Well, OWN YOUR DEVICE. LIKE ACTUALLY, FULLY, OWN, IT.
  • Unless you want to be known as the one who made it available for full access. Or die feel pain trying. Enjoy one of the most, monetizable times of the year. Later.
 

Users who are viewing this thread

Top