Wednesday, January 8, 2014

Build your very own KitKat ROM for the Galaxy Nexus


Annoyed that Google refused the update the very capable Galaxy Nexus to KitKat? Well now you can easily compile your own ROM.

To start, build Android 4.3 Jelly Bean for your Galaxy Nexus from the instructions given in my previous blog post. 

Once you have 4.3 working on your phone without any issues, download the source for 4.4.2 from AOSP into a new folder, say kitkat.

First, get all the Galaxy Nexus specific makefiles from 4.3.
To do this, copy device/samsung/maguro and device/samsung/tuna to your kitkat folder into the same folders.

Now open device/samsung/tuna/libsensors/Android.mk.

Change LOCAL_C_INCLUDES += hardware/invensense/libsensors
to LOCAL_C_INCLUDES += hardware/invensense/60xx/libsensors


In KitKat, Google changed the directory structure for the driver code, so this is necessary.

In 4.4, Google change the API for sensors and added the following two new fields -

/* number of events reserved for this sensor in the batch mode FIFO.
 * If there is a dedicated FIFO for this sensor, then this is the
 * size of this FIFO. If the FIFO is shared with other sensors,
 * this is the size reserved for that sensor and it can be zero.
 */
uint32_t        fifoReservedEventCount;

/* maximum number of events of this sensor that could be batched.
 * This is especially relevant when the FIFO is shared between
 * several sensors; this value is then set to the size of that FIFO.
 */
uint32_t        fifoMaxEventCount;


You can see the change in sensors.h.
To incorporate these changes, open device/samsung/tuna/libsensors/sensors.cpp, and change the line

 { "GP2A Light sensor",
          "Sharp",
          1, SENSORS_LIGHT_HANDLE,
          SENSOR_TYPE_LIGHT, powf(10, 125.0f/ 24.0f) * 4, 1.0f, 0.75f, 0, { } }
to

  { "GP2A Light sensor",
          "Sharp",
          1, SENSORS_LIGHT_HANDLE,
          SENSOR_TYPE_LIGHT, powf(10, 125.0f/ 24.0f) * 4, 1.0f, 0.75f, 0, 0, 0, { } }




At this point, you can build the source, and flash the images to your Galaxy Nexus to get a working
KitKat ROM, but WiFI will not work, and you will have many graphics glitches.

To fix WiFI, open device/samsung/tuna/init.tuna.rc and modify the following lines -

Change the line
service p2p_supplicant /system/bin/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-I/system/etc/wifi/wpa_supplicant_overlay.conf -N \
-ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \
-I/system/etc/wifi/wpa_supplicant_overlay.conf \
-e/data/misc/wifi/entropy.bin -puse_p2p_group_interface=1

To

service p2p_supplicant /system/bin/wpa_supplicant \
        -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
        -I/system/etc/wifi/wpa_supplicant_overlay.conf \
        -O/data/misc/wifi/sockets \
        -N -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \
        -I/system/etc/wifi/p2p_supplicant_overlay.conf \
        -puse_p2p_group_interface=1 \
        -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0

And the line

service wpa_supplicant /system/bin/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-I/system/etc/wifi/wpa_supplicant_overlay.conf \
-e/data/misc/wifi/entropy.bin

To

service wpa_supplicant /system/bin/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
-I/system/etc/wifi/wpa_supplicant_overlay.conf \
        -O/data/misc/wifi/sockets \
        -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0



Note that you will still have graphics glitches in places where the Chrome WebView is used, but you can minimize these by downloading a newer kernel from CyanogenMod, or get TinyKernel for Galaxy Nexus.


Tuesday, November 5, 2013

Building Android from Source for the Galaxy Nexus

This is the first in a series of posts on building the Android firmware for Galaxy Nexus as available from Google at source.android.com. When I first tried to do this, I had to look at a lot of guides and forum posts to get everything working on my Galaxy Nexus. Although the Galaxy Nexus will be obsolete in a few months, the general principles described here are the same for any Nexus device.

Downloading the Source

This is best described at this relevant page from Google. Only gotchas are that if you decide to do this on a Linux system other than ubuntu, you will have to spend a fair bit of time in looking up the required packages and downloading it. I have built AOSP on CentOS,RHEL and OpenSuSe without much effort, so it is definitely possible to get a build up and running on any modern and well-supported Linux distribution.

Folder Structure of the Android Source

When you first run the repo init command, an empty repository is created with links to the individual Android projects in git. To see this list, open .repo/manifest.xml. In case of other Android distributions like CyanogenMod or AOKP, this manifest.xml is modified with additional entries for the specific apps in the ROM distribution.

/system - This is where all the apps are contained.
/external - This contains external libraries like OpenSSL, wpa_supplicant (for WiFi) or other third-party open-source libraries. There are typically compiled into .so object files and copied to /system/lib on the device.
/vendor - This is the folder which contains the specific files for each device. For eg. /vendor/samsung would contain all the specific files made by Samsung. ROM distros like CyanogenMod contain a /vendor/cm folder where all CM-specific packages are stored.
/out - This is where the output files are stored after a successfull build. To go to the target folder for the device you are building, type cd $OUT or cd $ANDROID_PRODUCT_OUT (This will work only after the target device has been set using lunch)
/build - This contains a bunch of Makefiles that define Android's Make-language, i.e the many keywords that are used in the .mk files scattered across the Android source. PRODUCT_IDs are VERSION_IDs are also defined in  makefiles here.
/packages - This is where the source for all the Android Apps (atleast the ones included in AOSP) resides.


Understanding the Android Build System

To start with, a bunch of makefiles in the build directory are included, which define keywords like all-files-under-dir and call-dir and other such keywords which are further used
in other makefiles, effectively creating a whole new language for use in Makefiles.

These Makefile keywords enable very useful constructs - For eg. The Galaxy Nexus (maguro) makefile inherits from the tuna Makefile, so that all the devices which use the same board as the Galaxy Nexus
(mainly the different variants of the Galaxy Nexus), can all inherit from the tuna makefile.

Special shout out to build/core/version_defaults.mk, which is the Makefile where the version info that you see in Settings->About is pulled from.

Getting the device specific drivers

To build for a device, you will need the drivers for peripherals like wireless, camera, gps, etc. which are usually not open-sourced by the individual manufacturers. For nexus devices, theses are usually provided as binary blobs from the Nexus Proprietary Binaries' page.

If you have ever wondered why your (non-nexus) Android device is not supported or is buggy running ROMs like CyanogenMod, the reason is that the appropriate binaries for the peripherals were not released for your device, so the device maintainers for the ROM needed to copy source from related devices containing same (or similar peripherals).

Download all the required binaries for the Galaxy Nexus from the above page, copy them to your vendor/ folder, and then extract them.
All the proprietary files needed for a fully functional build are contained in proprietary_files.txt. If you compare the entries in this file versus all the files from the driver packages that you just extracted, you will notice that there are a couple of files missing. These are - 
  • ducati-m3.bin
  • gps.omap4.so
  • sirfgps.conf

You can obtain these files off your devices with adb pull or you can download them from an online repository like The Muppets which contains the proprietary drivers for various devices.

Once you have obtained these files, the next step is to make appropriate entries in the Galaxy Nexus makefile, so that these binaries are copied to the system image.

Add these entries to PRODUCT_PACKAGES in vendor/samsung/maguro/device-partial.mk
sirfgps \
ducati-m3 \
gps.omap4
And then, describe the files that you have just added in vendor/samsung/maguro/proprietary/Android.mk

include $(CLEAR_VARS)
LOCAL_MODULE := sirfgps
LOCAL_MODULE_OWNER := samsung
LOCAL_SRC_FILES := sirfgps.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .conf
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)
LOCAL_MODULE := gps.omap4
LOCAL_MODULE_OWNER := samsung
LOCAL_SRC_FILES := gps.omap4.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/hw
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)
LOCAL_MODULE := ducati-m3
LOCAL_MODULE_OWNER := samsung
LOCAL_SRC_FILES := ducati-m3.bin
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .bin
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware
include $(BUILD_PREBUILT)


Now, in vendor/samsung/maguro/BoardConfigVendor.mk, change PRODUCT_RESTRICT_VENDOR_FILES to false. This will to instruct the build to pick up the proprietary drivers located in the vendor folder.

Compiling

Now that all the setup steps are taken care of, we can get down to work and start the actual compile process. To start, in the root folder, execute

source build/envsetup.sh

This pulls in some of the device specific makefiles and sets up a make target for each device.
After this is done, execute

[vineet1@vineet1-1 aosp]$ lunch

You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_x86-eng
     3. aosp_mips-eng
     4. vbox_x86-eng
     5. full_maguro-userdebug
     6. aosp_manta-userdebug
     7. aosp_mako-userdebug
     8. aosp_hammerhead-userdebug
     9. aosp_grouper-userdebug
     10. aosp_deb-userdebug
     11. aosp_flo-userdebug
     12. aosp_tilapia-userdebug
     13. mini_armv7a_neon-userdebug
     14. mini_mips-userdebug
     15. mini_x86-userdebug

Which would you like? [aosp_arm-eng] 5

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.4
TARGET_PRODUCT=full_maguro
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9
HOST_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-2.6.32-358.el6.x86_64-x86_64-with-centos-6.4-Final
HOST_BUILD_TYPE=release
BUILD_ID=KRT16M
OUT_DIR=out
============================================



From the menu that is displayed, choose full_maguro-userdebug
Once that is done, run make -jn (where n = 2x the number of CPUs in your system). This will kick off the build process.

This should take a while, depending on your system. If it completes successfully, the next step is to generate a zip file which we can use to flash to your device.

make updatepackage.

This wil generate a file named like full_maguro-img-eng-<username>.zip
Flash this file onto your phone with fastboot update -w to erase the existing system on your device, and reflash your newly built system image.

Thats it! Check Setting->About phone and verify the version numbers.