Skip to content

Instantly share code, notes, and snippets.

@Tofee
Last active December 20, 2017 10:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tofee/f3a65d5ea391da20817d3746f0031357 to your computer and use it in GitHub Desktop.
Save Tofee/f3a65d5ea391da20817d3746f0031357 to your computer and use it in GitHub Desktop.
Tofe's Rough Porting Guide

Tofe's Rough Porting Guide

  1. Prepare the device
  • Download CM12.1 from get.cm -- might later be from LineageOS website
  • Download CWM or the latest recovery tool for the device
  • Unlock the bootloader -- on Hammerhead it just means booting to bootloader and doing "fastboot oem unlock".
  • Flash the recovery tool "fastboot flash recovery cwm-recovery.img"
  • Reset factory, and flash CM12.1 via adb sideload
  • Start the device, check that Android basics work well (wifi, bluetooth, sound...)
  • In the settings, click on the build number several times to activate the developper mode, and in that latter section activate the ADB connection. Also authorize root for apps and ADB.

--> That's all, the device is ready.

  1. Build the libhybris Android HAL
  • Get the base Android manifest from webos-ports: https://github.com/webOS-ports/android/tree/wop-12.1
  • Create a local manifest which is simply a link to the wop_targets.xml in .repo/manifests/
  • Adapt the local manifest with the device-specific projects. For Hammerhead, it means the following:
  <!-- Hammerhead -->
  <project path="device/lge/hammerhead" name="CyanogenMod/android_device_lge_hammerhead" revision="stable/cm-12.1-YOG7D" />
  <project path="kernel/lge/hammerhead" name="CyanogenMod/android_kernel_lge_hammerhead" revision="stable/cm-12.1-YOG7D" />
  • Synchronize the repos ("repo sync --force-sync"). This can take some time, as some of the projects are quite big.

  • Now build the libhybris HAL using the following steps (replace "hammerhead" with the targetted device):

. build/envsetup.sh
export USE_CCACHE=1
breakfast hammerhead
make -j4 luneos-hybris-camera
rm -rf out/target/product/hammerhead/{system,symbols}
make -j4 luneos-hybris-hal

The "rm -rf " line is here to cleanup a bit the build output directory, so that the luneos-hybris-hal archive only contains binaries relevant for libhybris usage. It shouldn't take very long. On a recent computer with SSD, it takes less than 10 minutes.

  • Now go to the output directory and create the prebuilt archive that LuneOS will use during its own build:
cd out/target/product/hammerhead/
tar --concatenate --file hal-droid-wop-12.1-20170116-0-hammerhead.tar luneos-hybris-hal.tar
tar --concatenate --file hal-droid-wop-12.1-20170116-0-hammerhead.tar luneos-hybris-camera.tar
bzip2 hal-droid-wop-12.1-20170116-0-hammerhead.tar

Put the archive in a place where the LuneOS build can find it (on a http server, for instance).

  1. Adapting the recipes

It is generally a good idea to start from a copy of an existing working target. In the meta-smartphone layer, one good example is the "mako" target.

a) Preparing the files

Duplicate all of the "mako" recipes and recipes' files for the target device, and rename "mako" to the target device name everywhere it appears.

Also adapt some basic content for the new files:

  • to know the mapping between partition names and their device number, one easy way is to issue the following command:
fdisk -l /dev/block/mmcblk0
  • for the base files, fstab has to match the correct partitions of the new target device. Adapt them for system, firmware and persist. Note that sometimes the firmware partition is named "modem".
  • similarly, adapt the partitions for the initramfs-boot-android recipe file name "machine.conf"

b) Configuring the machine

The machine configuration (which is located in meta-[vendor]/conf/machine/[device].conf ) is the entry point for the LuneOS build.

Hopefully it is fairly easy to adapt:

  • set the correct name for the new device kernel recipe (which provides virtual/kernel)
  • set the correct pixel width, height, orientation and density. These specs can often be found easily on Internet.
  • also fix the name of the recipes for android image and headers
  • adapt ANDROID_BOARD_BOOTIMAGE_PARTITION, ANDROID_BOARD_SYSTEMIMAGE_PARTITION_SIZE and ANDROID_BOARD_FLASH_BLOCK_SIZE. This can be found in the file "BoardConfig.mk" of the CM12.1 Android build (see step 1)
  • if needed, also set the KERNEL_IMAGETYPE to the needed kernel target. For Hammerhead for example, the "dtb-zImage" is needed.

c) Set the correct android HAL information in the recipes

  • adapt the android-headers-[device] recipe so that it uses the correct machine name and android API level. The latter should be "22" when using CM12.1.
  • adapt the android-system-image-[device] recipe so that it points to the file that was built at step 2.

d) Edit the package recipe

To have a correct final package, don't forget to include the following line in meta-webos-ports/meta-luneos/recipes-core/packagegroups/packagegroup-luneos-extended.bb:

RDEPENDS_${PN}_append_hammerhead = " ${LIBHYBRIS_RDEPENDS} ${MEMNOTIFY_RDEPENDS}"

e) nyx-modules

There is a machine specific part for the nyx-module recipe in meta-webos-ports: the corresponding machine's cmake file has to be in the src/machines directory when running cmake. To fix that, one can put in place the following bbappend:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI_append_hammerhead = " \
  file://hammerhead.cmake \
  "

do_configure_prepend_hammerhead() {
  # install additional machine specific nyx configuration before CMake is started
  cp ${WORKDIR}/hammerhead.cmake ${S}/src/machine
}

The content of the cmake file can be inspired by the one from mako: https://github.com/webOS-ports/nyx-modules/blob/webOS-ports/master/src/machine/mako.cmake

f) luna-next configuration

To have a working UI, you'll need to check several points:

  • Adapt/Create the luna-platform.conf file for the target device
  • You will also need to create an additional configuration file for the luna-next-conf recipe. The easiest is to duplicate an existing one (for example, mako/environment.conf) and adapt the content if needed. Typically, one will need to set the touch event input. To do so, adb on the device and do a "cat /dev/input/eventX" changing X, until you see some garbage on the terminal when touching the device's screen.
  1. Port the Android CM12.1 kernel for the LuneOS build

a) Patch the kernel so that the Android kernel can be built using bitbake. This require several modifications, but most of them can usually simply be cherry-picked from one of our existing LuneOS device kernels.

For example, the needed commits can be picked from https://github.com/shr-distribution/linux/commits/mako/3.4/cm-12.1, from 3ec083d to HEAD.

b) Adapt the kernel recipe

The CMDLIND and RAMBASE information can also be found in the "BoardConfig.mk" file of the Android source tree. For the rest, simply point to the place where the adapted Android kernel for LuneOS (with the modifications done in (a) ) is stored.

c) Create the configuration of the device kernel for LuneOS

This part can be difficult, as each device has different needs, but the following process can help.

Begin by copying the Android defconfig (usually found in arch/arm/configs of the Android source tree) into the kernel recipes' files.

This defconfig has to be adapted so that all the functionalities in LuneOS work well (systemd, lxc...). One good way to do that is to use the defconfig checker available at https://github.com/webOS-ports/meta-webos-ports/blob/master/meta-luneos/scripts/verify_kernel_config and to fix the needed options.

Tip: the main things to activate are the "namespace" capabilities, modules, AutoFS, and to disable most of SELinux to keep a basic AppArmor.

  1. Try the build

First, try to compile only the kernel with "bb virtual/kernel". If there are some errors, check again the defconfig options.

Then, simply try the complete build, and fix the mistakes along the way.

  1. Tips

a) Issues on boot

If the boot image leads to a kernel panic, hangs, or reboots, here are some ways to debug it:

  • if the reboot happens quickly (no adb yet for instance), one can go to the bootloader menu at the next reboot (On Nexus4/5, hold Vol- during reboot) and boot into recovery. Then, with adb, look at the /proc/last_kmsg file: it should contain the last messages output during boot.
  • for an easier debug, it is also possible to flash the recovery image in the boot partition, and start the LuneOS kernel with "fastboot boot zImage.fastboot" from the bootloader menu.
  • if it is needed to rebuild the fastboot image, it is faster to just do "bb initramfs-android-image", it will avoid rebuild the whole rootfs.
  • if the boot goes further, adb shows up, but it reboot before one can analyze the situation, it's maybe a systemd issue. On LuneOS the journal is volatile by default. But it is possible to make it permanent: go to recovery, mount the data partition, and go to the /data/luneos directory. Then delete the /var/log symlink and create the /var/log/journal directory. On next reboot, the journal will now be permanent, and eventually analyzed with journalctl on the dev machine.
  • otherwise, when nothing shows up but adb is available and it doesn't reboot, go into the adb shell and analyze systemd's journal.

b) Issues with Android hybris HAL

It is very possible that some things won't be working straight away. Here are for example what needed fixing for hammerhead:

  • GPRS modem not working: in the logs, we see things like
pil-q6v5-mss fc880000.qcom,mss: mba: Failed to locate mba.mdt

That sort of log tends to indicate an issue with firmware loading. In this case, the /var/lib/lxc/android/pre-start.sh was to be blamed, because the /etc directory wasn't available within the lxc container.

  • Errors concerning audio in the logs: on hammerhead, it is important that the acdb data (usually present in /etc on Android) can be accessed from outside of the LXC container. So links from /etc/acdbdata to /system/etc/acdbdata were needed. Same goes for /etc/audio_effects.conf and /etc/audio_policy.conf.
  • Errors in logcat concerning /dev and /sys : indeed, in /var/lib/lxc/android/pre-start.sh, we didn't mount /dev nor /sys within the LXC container, leading to some errors in the Android daemons.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment