Distribution

Reference rootfs

To make development and porting easier the halium team provides the reference rootfs. It is based on Ubuntu 16.04 and includes the following:

  • systemd
  • lxc
  • lxc-android
  • libhybris
  • ofono
  • ofono-scripts

This reference rootfs is built using the live-build tool. Documentation on how you can build it locally using rootfs-builder is available at https://github.com/halium/rootfs-builder/tree/ubuntu


Deployment

There are various parts which need to be deployed on the device:

  • boot.img
  • rootfs
  • udev rules
  • lxc container configuration
  • system.img
  • vendor.img (for newer devices)
  • android ramdisk

boot.img

The boot.img is based on hybris-boot. This boot.img is built inside the android tree.

boot.img has really simple functionality: Mount the data partition, and the rootfs.img inside to /target,

mount $DATA_PARTITION /data
mount /data/rootfs.img /target

and switch to the target rootfs and run the init (systemd)

exec switch_root /target $INIT --log-target=kmsg &> /target/init-stderrout

rootfs.img

The rootfs is provided by the distribution in tar.gz format. The installation tool extracts the contents and puts them into the ext2 or ext4 rootfs.img. This rootfs.img will be mounted by the hybris-boot later on.

Following are the minimal requirements of the such a rootfs

  • systemd as the main init
  • lxc

Depending upon required functionality, you may need

  • ofono (for calling and mobile data)
  • libhybris
  • NetworkManager
  • Pulseaudio

udev rules

The rootfs.img contains the udev rules. They are device specific and generated from the ueventd*.rc file from the device tree. Instructions for getting these rules installed can be found at Add udev rules.

You can either,

  1. copy them to /lib/udev/rules.d/ during the initial installation of the rootfs or
  2. deploy all the supported udev rules in /usr/lib/lxc-android/, and have a systemd service to copy the device udev rule before starting udev service.

lxc container configuration

This is most important bit. It starts the android init. This is required to start the android binary daemons etc.

There are two parts of the lxc container configuration:

  • config
  • pre-start.sh

They are provided at : https://github.com/Halium/lxc-android/blob/master/var/lib/lxc/android/

The configuration file specifies the following options:

  • lxc.rootfs
  • lxc.network.type
  • lxc.devttydir
  • lxc.tty
  • lxc.pts
  • lxc.arch
  • lxc.cap.drop
  • lxc.pivotdir (deprecated)
  • lxc.hook.pre-start
  • lxc.init_cmd
  • lxc.aa_profile (optional, only for distribution using apparmor)
  • lxc.autodev

The pre-start hook is used to extract and configure the android rootfs before booting into it.

system.img and vendor.img

These are the android libraries and the vendor binary blobs. They are generated by building the android tree and they are deployed to the userdata partition at installation time.

Android rootfs

The android rootfs is provided by halium. It is generated by the android build system. The android rootfs contains what is usually contained inside the initrd of android’s boot.img. This is extracted by the android lxc container’s pre-start hook before starting the container. It is located at /system/boot/android-ramdisk.img.


Startup sequence

  • fastboot starts the kernel and loads the initrd
  • initrd mounts the userdata partition and rootfs.img from it
  • After mounting rootfs.img it will start the systemd init from the rootfs
  • The rootfs is expected to mount the /system, /vendor and other android mount points before local-fs.target
  • After the local-fs target, the lxc container is started
  • lxc pre-start hook will bind mount the mounted android partitions inside the android rootfs
  • Once the android container is started the host system will start udev and other system daemons
  • At this point the scope of halium is over and userspace services like sddm, mir, lipstic etc can be started