[Nexus 4 General] Nicknoxx:
A beginners guide to building and modifying a nexus 4 lollipop* kernel from source.

*currently 5.0.1​

Disclaimer

I am not a developer, nor am I an expert. All the information in here I have gleaned from other sources, credited where possible, so it may not be correct and almost certainly isn't the 'best' way to do things. But it works for me. I hope it works for you but there's no guarantee. Use at your own risk

Assumptions

You have access to a computer running Ubuntu - other distros will probably work but this is the one I'm using. You'll need a basic understanding of the Linux command line including, but not limited to, ls, cp, cd, mkdir, make, ~, sudo, nano and so on.

You'll need to know how to use adb & fastboot to copy stuff into and out of your Nexus 4

A basic undersanding of Git is REALLY helpful if you want to modify your kernel. You'll be able to get by using the comands listed but you really need to have a basic understanding of what Git does if you're going to proceed.

CONTENTS

Initialise your build environment

Downloading the sources

Toolchain

Building

Creating a boot.img

A bit more about Git

Modifying kernels (how I got DT2W working)

Making a flashable zip

Initialise your build envronment

The information for this stage came from: here

I installed Ubuntu 14.04.1 LTS from a scratch. I used VM ware on a Windows laptop but any Linux environment can probably be made to work. So, to start, do an update just to be sure, then install the packages you'll need.

# sudo apt-get update
# sudo apt-get install bison g++-multilib git gperf libxml2-utils
# sudo apt-get install libncurses5-dev:i386
# sudo apt-get install lib32ncurses5-dev
# sudo apt-get install build-essential kernel-package

Downloads

Most of the really helpful information I've used came from here

I've updated the information slightly and changed the device from Flo to Mako but Pete's page is well worth reading for more background information than I've included here.

To download the source into a 'kernel' folder

# mkdir ~/android
# cd ~/android/
# git clone https://android.googlesource.com/kernel/msm.git kernel
# cd kernel/
# git branch -a

will show you all the current branches of Mako kernels, choose the one you want and checkout that one.

# git checkout android-msm-mako-3.4-lollipop-release

Now you need to find out exactly which kernel to build. The 'official' method is here

but that involves a significant download for just a few bytes so I suggest you use the following trick. Go to the pre-built kernel you want to copy here

and you wll see the first line after the header is:-

"16e203d lowmemorykiller: enhance debug information"

You need to make a note of the first seven characters, in this case 16e203d.

Next you need to use Git to create a new branch for our specific kernel. I've called it 'android-lollipop-release'.

# git checkout -b android-lollipop-release 16e203d

This will extract the source for the kernel we're going to build.

Toolchain

I'm using the stock toolchain (thanks [MENTION=4217103]zaclimon[/MENTION]) but will add an alternative suggested by [MENTION=4914494]aviz1911[/MENTION] as time allows.

I'm going to install the toolchain in /usr/local/share but there are other places you could sensibly put it.

# cd /usr/local/share
sudo git clone [url]https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7[/url]

Export the path to the toolchain and check it works. Note these exports only work for the current session, if you want to add permanently put it in your .bashrc or .profile

# export PATH=$PATH:/usr/local/share/arm-eabi-4.7/bin
# cd ~

Test it works with

# arm-eabi-gcc --version

Now you need to tell the system we want to cross compile.

# export ARCH=arm
# export SUBARCH=arm
# export CROSS_COMPILE=arm-eabi-

Building

Now you're ready to start.

#cd ~/android/kernel
# make mako_defconfig

You'll get some warnings like this which you can ignore

warning: (ARCH_MSM_KRAITMP && ARCH_MSM_CORTEX_A5) selects HAVE_HW_BRKPT_RESERVED_RW_ACCESS which has unmet direct dependencies (HAVE_HW_BREAKPOINT)

# make menuconfig

this is where you can make some changes if you like, we're going to change just the name. Choose General Setup ---> then select

(-perf) Local version - append to kernel release

and change perf to anything you like, I'll use dt2w

Save and exit

# make -j2

where 2 is twice the number of cores on your machine - there's just one processor on my VM but could be many more on yours. It takes more than half an hour on my machine. Then you should see

Kernel: arch/arm/boot/zImage is ready

Ta Daaaaa - you have built a kernel - now you need to pack it for testing on your phone.

Creating a boot.img

Again I'm going to use Pete's blog post as my guide but omit some details and just get the job done. I'm not going to explain all the steps, you'll have to investigate yourself if you want to understand more.

# cd ~/android
# git clone https://github.com/pbatard/bootimg-tools.git bootimg-tools
# cd bootimg-tools/libmincrypt/
# gcc -c *.c -I../include
# # cd ../mkbootimg
# gcc mkbootimg.c -o mkbootimg -I../include ../libmincrypt/libmincrypt.a
# sudo cp mkbootimg /usr/local/bin/
# gcc -o unmkbootimg unmkbootimg.c
# sudo cp unmkbootimg /usr/local/bin/

You need an original boot img to copy so you can insert your new kernel into it. Download the factory image.

# mkdir ~/android/boot
# cd ~/android/boot
# wget https://dl.google.com/dl/android/aosp/occam-lrx22c-factory-86c04af6.tgz
# tar -xvf occam-lrx22c-factory-86c04af6.tgz
# cd occam-lrx22c/
# unzip occam-lrx22c-factory-86c04af6.zip
# cp boot.img ../
# cd ~/android/boot

Now it's time to unpack the original boot image. unmkbooting will tell you all the parameters you need to repack the boot image with your new kernel inside.

# unmkbootimg -i boot.img
kernel written to 'kernel' (6009416 bytes)
ramdisk written to 'ramdisk.cpio.gz' (490557 bytes)
To rebuild this boot image, you can use the command:
mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x80208000 --ramdisk_offset 0x81800000 --second_offset 0x81100000 --tags_offset 0x80200100 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=mako lpj=67677 user_debug=31' --kernel kernel --ramdisk ramdisk.cpio.gz -o boot.img

# cp ~/android/kernel/arch/arm/boot/zImage ~/android/boot/

Repack your new boot image with your new kernel using the information from unmkbootimg

mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x80208000 --ramdisk_offset 0x81800000 --second_offset 0x81100000 --tags_offset 0x80200100 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=mako lpj=67677 user_debug=31' --kernel zImage --ramdisk ramdisk.cpio.gz -o new_boot.img

Nore that kernel has been changed to zImage and output file has been changed new_boot.img Now it's time to test your new_boot.img by rebooting your phone into bootloader and reboot with the new img.

DO NOT FLASH THE NEW IMAGE.

fastboot boot new_boot.img NOT fastboot flash boot new_boot.img

If all has gone well your phone will now boot with your new kernel. If something has gone wrong just reboot the phone and you'll be back to where you started. If it has all worked then you can flash the new boot image and use that.