B2G OS is traditionally built on top of AOSP. However this does not mean we must use only AOSP. Several forks of AOSP exist which aim to support a wider range of hardware. CyanogenMod, the most popular fork of AOSP, includes thousands of additions, modifications, and hacks to support hundreds of retail Android devices. This article explains how to port Firefox using CyanogenMod.
When we build B2G OS on top of CyanogenMod we unlock the potential of supporting the same number of devices that CyanogenMod does. Due to the sheer number of devices supported by CyanogenMod, it is highly likely that you already have a device that we could build for!
If you have never built CyanogenMod for your device then we strongly suggest you learn how to do so before porting B2G OS. This serves two purposes; You will learn how to use the tools necessary for porting B2G OS, and you will verify the quality of the CyanogenMod port.
More explicitly: this guide assumes your device is unlocked and has CyanogenMod installed on it. This guide will not teach you how to root and/or unlock your device, nor how to set up your build machine nor how to use git to solve merge failures.
A summary of the steps are as follows:
- Download the source code
- Modify device repos
- Modify kernel
- Build and install
Download the source code
We have several useful tools for building B2G OS, all contained in a single repository. Download these tools via
git to create your working directory.
git clone https://github.com/cm-b2g/B2G.git && cd B2G
Now we need to make repo executable .
chmod a+x repo
Now we need to download the source code.
config.sh initializes the
repo tool using the
base-l-cm.xml manifest found in the
b2g-manifest repository. This XML file is a list of OS specific repositories needed to build B2G OS. It then uses the
repo tool to download all of the source code.
Downloading all of these repositories, many of which are several gigabytes, will take a while so we recommend doing this overnight on a slow connection, or just before lunch on a faster connection.
If you have slow internet connection you can specify number of jobs repo will do at the same time by following these steps .
- nano config.sh
- Change " sync_flags="" " to " sync_flags="-j#" " - replace # with number of jobs you want repo to do at the same time - I use 1 to make it stable and fast as possible .
- Then press "ctrl+x" then then "y" then "Enter" to save changes .
This step also creates a
.config file which you will edit later.
Local manifest for your device
The above manifest does not contain any device specific repositories, which is different from a typical manifest. We need to create a
local_manifest.xml with all of the repositories for your device. The quickest way to do this is to use
breakfast, an automated tool written by CyanogenMod to create a local manifest and download the additional repositories directly from CyanogenMod’s GitHub account.
. build/envsetup.sh && breakfast 123
123 with your device’s codename.
If your device is not officially supported by CyanogenMod, but there is an unofficial port, you can create the
local_manifest.xml manually in the
.repo/local_manifests folder An example is given below.
<?xml version="1.0" encoding="UTF-8"?> <manifest> <remote name="xyz" fetch="git://github.com/xyz/" revision="cm-12.1" /> <project name="device_oem_123" path="device/oem/123" remote="xyz" /> <project name="device_oem_1xx-common" path="device/oem/1xx-common" remote="xyz" /> <project name="kernel_oem_1xx" path="kernel/oem/1xx" remote="xyz" /> <project name="vendor_oem" path="vendor/oem" remote="xyz" /> </manifest>
Remember to run
repo sync when you have created your manifest!
Modify the device repos
Part of a device’s configuration is found in XML overlay files used by the AOSP build system to set default options in Android apps. B2G OS does not use these so we need to reimplement some of these options, such as on screen home button, emulated storage etc.
We can set most sane default options by including two files from
vendor/cm. The first line should be added to the top of
device.mk and the second line should be added to the bottom of
# Extra mk import at the top of device.mk $(call inherit-product, vendor/cm/config/common_full.mk) # Extra mk import at the bottom of BoardConfig.mk include vendor/cm/BoardConfig.mk
More options are still needed, as many are highly device specific. Below is a list of common device specific additions and deletions. This list is not exhaustive, but adding the two lines above and setting everything below will give you a functional system.
# for Gecko to use the correct resolution assets # Valid options are: 1.5 | 2 | 2.25 GAIA_DEV_PIXELS_PER_PX := 2.25
# for Gecko to use the correct boot animation # Valid options are: hvga | fwvga | qHD | 720p | 1080p BOOTANIMATION_ASSET_SIZE := 1080p
# for Gecko to support separate internal storage partition # This is for legacy devices only. You must prvide your own volume.cfg file GECKO_BOARD_SEPARATE_STORAGE_PARTITON := true
# for Gecko to support virtual home button PRODUCT_PROPERTY_OVERRIDES += \ ro.moz.has_home_button=0
# for Gecko to support usb mass storage # You may need to add mass_storage to init.oem.usb.rc PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \ - persist.sys.usb.config=mtp + persist.sys.usb.config=mass_storage
# for Gecko to support NFC PRODUCT_PROPERTY_OVERRIDES += \ ro.moz.nfc.enabled=true PRODUCT_PACKAGES += \ nfcd
# Changes in init.device.rc -on property:init.svc.bootanim=running -on property:init.svc.bootanim=stopped -on property:service.bootanim.exit=1 +on property:sys.boot_completed=1
Modify the kernel
We need to enable some extra security features in the kernel for B2G OS. These features were not present in Android kernels until Marshmallow so many devices will need some extra patches backported to the kernel. For reference see Bugzilla: 790923.
It is enough to cherry-pick the patches to your kernel; the build system will automaticaly enable the new features. For a working example see the LGE MSM8994 kernel.
Build and Install
.config file created earlier? Now we need to replace
cm-porting with your device codename.
$ grep -r PRODUCT_NAME device/oem/123
Note: don’t use the value in
cm.mk, use the one in
device.mk, it should be something like
full_123. You can do the replacement manually, or simply with
$ sed -i "s/cm-porting/full_123/g" .config
Now it’s time to start the build!
This will take anywhere from 30 minutes to a couple of hours depending on your PC, so now might be a good time to go to the shop and buy some popcorn.
Install B2G OS via fastboot
If your device supports
fastboot then you can simply flash the partition images directly:
cd out/target/product/123/ fastboot flash boot boot.img fastboot flash recovery recovery.img fastboot flash system system.img fastboot flash userdata userdata.img
Install B2G OS via recovery
If you device does not support fastboot then you can use the
update.zip instead. This can be installed to the device by copying the zip to an sdcard or via
adb sideload. Enter recovery according to your device specific method then:
adb sideload out/target/product/123/fota/fullimg/update.zip
Is something not working? It’s time to roll up your sleeves!
First try to determine if the feature is working in CyanogenMod. It may simply be a missing configuration for B2G OS.
If the feature is not working on CyanogenMod then it means you need to implement that feature to your port. It would be nice if you push your fix back upstream too!
Most devices produced since mid 2015 have a 64bit SoC inside. B2G cannot be built as a 64bit executable, but fortunately 32bit executables work. We can force B2G to build as 32bit with two patches found in Bug #1245088.
After that you just need to set:
BUILD_MULTILIB_GECKO_AS_2ND_ARCH := true
Some parts of Android were removed from the build process as they are not needed. If your camera blob complains about missing functions, check frameworks/base to see if the functions were removed. It may be possible to bring them back.
The device may not see certain access points if they are on an unofficial / illegal channel. Do not do this! if you can, you'll need to change the channel your router broadcasts on.