Reference rootfs

To make development and porting easier, halium team provides the reference rootfs which is based on Ubuntu 16.04. It 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


There are various parts which needs 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 is based on hybris-boot, this boot.img is built inside the android tree.

boot.img have really simple function,

Mount the data partition, and the rootfs.img in it 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 is provided by the distribution, in the tar.gz format, installation tool will extract and put the rootfs in 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 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

rootfs.img contains the udev rules which are device specific and is generated from the ueventd*.rc file from 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 rootfs
  2. Deploy all the supported udev rules in the /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, which 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/

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

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

system.img and vendor.img

This is the android libraries and vendor binary blobs, this is generated by building the android tree, they are deployed to the userdata partition at installation time.

Android rootfs

Android rootfs is provided by the halium, this is generated by the android build system, 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 container. This is located at /system/boot/android-ramdisk.img.

Startup sequence

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