Fri 25 May 2018

Filed under Gentoo

Tags android gentoo gsoc


As we now have preinit and the crucial UART console available, we can start bringing up the real GNU/Linux system--Gentoo Linux in this case. This article will focus on the following topics:

  • Filesystem structure and mounting procedure (in details)
  • Launch sequence to bring up OpenRC
  • Crafting a preinit initramfs
  • Tweaks in Gentoo to get ready to start Android in LXC later on

Filesystem Structure and Mounting Procedure

We won't be changing the partition table, as altering that will prevent fastboot flash commands from working properly, and we won't be able to recover unless we re-flash the EMMC chip if we messed the partition table up. The partition we'll use for GNU/Linux root is userdata, but not the entire filesystem--we can retain compatibility with stock Android boot.img by preserving userdata as the partition to be mounted for Android /data. The Gentoo root filesystem sits at userdata:/gnu, and gets binded to / in preinit.

After OpenRC boots, userdata, system, vendor, persist, and cache gets mounted to their mountpoints under /var/lib/android for launching Android later on. This is done by the localmount service in OpenRC's sysinit runlevel, by reading /etc/fstab in Gentoo root. These partitions later get bind-mounted into Android's LXC rootfs, which will be the topic for my next article.

Launch Sequence to Bring up OpenRC

Once kernel finishes its early initializations, preinit, a busybox sh script, gets called. The source is available here in the preinit repository. Preinit basically does the following:

  • Mount pseudo-filesystems for preinit's proper functioning
  • Mount userdata partition at /mnt/userdata
  • Bind-mount /mnt/userdata/gnu to itself, making it a mountpoint, which was mandatory for switch_root
  • exec switch_root into /mnt/userdata/gnu and call /sbin/init

This procedure does not differ much from standard initramfses, except that the desired root is not the filesystem root. We can add other things into preinit later on to support alternative root layouts, e.g. LUKS.

Crafting a Preinit initramfs

As we're not launching anything other than /init, and, unlike Android, we have a real root filesystem instead of the entire root on tmpfs, we can safely trim unnecessary components inside the initramfs. What we really need in the initramfs is as follows:

  • init: busybox sh script (duh)
  • busybox: static executable
  • symlinks to busybox applets under /bin
  • mountpoints

The complete initramfs layout can be found in the preinit repository. Repack boot.img with the Makefile rules at the root of preinit repository. Remember to turn SELinux to permissive in kernel commandline: though OpenRC won't respect that commandline option, Android init will load the policies and enforce it later on, and as we're not SELinux-ready now, that would certainly break things.

Boot the phone into fastboot mode, but don't hurry to flash that boot.img as the boot partition yet--use the following commandline to boot the new boot.img temporarily, so that we still have the regular Android boot.img for debug and further actions that require a working Internet connection:

fastboot boot <modded boot.img>

Attach the UART cable to see what's going on. If the kernel can't launch init, double-check that the init script is executable, and the shebang line is correct. Also check if the symlinks to busybox are placed correctly. If everything goes as expected, you should see our dear Preinit and OpenRC waving hello to you:

[   12.602544] new_era: Preinit started
mount: /etc/mtab: No such file or directory
mount: /etc/mtab:[   12.606728] new_era: Trying to mount /dev/mmcblk0p44 on /mnt/userdata...
 No such file or directory
[   12.735390] EXT4-fs (mmcblk0p44): mounted filesystem with ordered data mode. Opts: (null)
mount: /etc/mtab: No such file or directory
[   12.743008] new_era: Setting up /mnt/userdata/gnu as mountpoint...
mount: /etc/mtab: No such file or directory
[   12.767932] new_era: Cleaning up mounts, switching root to /mnt/userdata/gnu, and launching /sbin/init...
mount: /etc/mtab: No such file or directory
mount: /etc/mtab: No such file or directory
mount: /etc/mtab: No such file or directory
INIT: version 2.88 booting

   OpenRC 0.34.11 is starting up Gentoo Linux (aarch64)

 * /proc is already mounted
 * Mounting /run ...
 * /run/openrc: creating directory
 * /run/lock: creating directory
 * /run/lock: correcting owner
 * Caching service dependencies ...

Tweaks in Gentoo to get ready to start Android in LXC later on

Though the system is up and running, we need to tweak a few things to make it suit our later launching Android in LXC. In case a shell is not yet available on serial console (which is most likely the case by default), boot into Android and chroot into Gentoo root as described in this article to configure the following.

You'll notice that we don't have a getty on the serial console: sysvinit does not start getty on ttyHSL0 by default. Edit /etc/inittab in Gentoo root, comment out tty* lines (which Android devices definitely don't have) and add the following line:

s0:12345:respawn:/sbin/agetty -L 115200 ttyHSL0 vt100

Remove udev from sysinit runlevel. It inteferes with Android's ueventd, and sometimes it takes ages for udev to process the uevents from the kernel. keymaps and termencoding are useless as well, as we'll only use a serial console, on which these services don't make sense.

for a in {udev,keymaps,termencoding}; do rc-update del $a boot; done

Though we do not have networking by now, add sshd to the default runlevel. Add syslog-ng as well.

for a in {sshd,syslog-ng}; do rc-update add $a default; done

Reboot. The system should now be running properly. In the next article, we'll boot back into Android to install LXC in Gentoo root, and we'll then launch Android in LXC.


Sat 05 May 2018

Filed under Gentoo

Tags gentoo linux virtualization

The story

After struggling with HiDPI issues on native GNU/Linux and battery life issues on macOS, I resorted to using Windows 10 as the main operating system on my laptop. Though there's WSL, it's not running Gentoo and has a severely degraded performance. As crossdev is really easy to …

Read More

Fri 04 May 2018

Filed under Gentoo

Tags android gentoo gsoc


Chrooting is usually a key part in installing a GNU/Linux system, and there's no difference here in my GSoC 2018 work. In this article we'll build a Gentoo chroot with CHOST=aarch64-unknown-linux-gnu, set up ssh connection to it, and install some necessary tools.

Preparation work

First of all …

Read More

Mon 05 February 2018

Filed under Gentoo

Tags gentoo lvm sparc

The story

My SPARC Enterprise T5120 came with two 10000 RPM SAS HDDs, both with a labeled capacity of 146GB. Gentoo was installed on the first hard drive, and thanks to the old SILO that was in charge of booting the system up, I have to keep a single-large-root partition …

Read More

Thu 07 September 2017

Filed under Gentoo

Tags system gentoo freebsd


Now that we have successfully upgraded Gentoo FreeBSD from 9.1 to 10.3, we need to upgrade it to 11.0 in order to catch up the latest FreeBSD system. The major steps consist of the following:

  • Upgrading world
  • Changing to the new profile
  • Upgrade the kernel
  • Upgrade …
Read More

KireinaHoro (jsteward) 's place © KireinaHoro Powered by Pelican and Twitter Bootstrap. Icons by Font Awesome and Font Awesome More