[Nexus 5X Android Development] nathanchance:
Introduction

Hello all, I am bringing you this thread as a jumping off point to compiling kernels and working with upstream Linux. I will include a guide, some links, and some terms that will help you get started with modifying kernel source. This is also a good reference point for existing developers as I have consolidated all upstream patches into one repo. Let's get down into it!

What in the world is upstream Linux?

When an OEM sets up a device, they will pick a stable longterm branch from the Linux kernel to base their modifications around (drivers and such). In the case of Bullhead, they picked 3.10.73. Currently, the Linux kernel's 3.10 is updated to 3.10.105, as you can see on kernel.org. This means that Google is "missing" versions 3.10.74 to 3.10.105. Now, why does this matter? Well, the way that the Linux kernel runs its stable branches, the only things that get merged into there are bug fixes and security updates. That's it, there are no wonky features or unstable patches. The only way you get a patch into a stable branch is by having it be in the mainline branch first. Some developers have an aversion to adding upstream because they claim it is excessive and not necessary and they are partially right since not all the patches that come in are relevant to our architecture (arm64). However, upstream Linux is not unstable and by adding each version one at a time, you can verify this. I found only two patches between 3.10.73 and 3.10.105 that gave me issues and it is easy enough to either fix/revert them. Being up to date is good since you keep yourself protected from bugs and security issues that crop up. Google has been better about doing this lately with their monthly security updates but it never hurts to take matters into your own hands.

I suggest watching one of these talks given by Greg Kroah-Hartman, it is really interesting to see how the process goes:

https://www.youtube.com/watch?v=SPY0LyTU53w | https://www.youtube.com/watch?v=L2SED6sewRw

What did you do?

All I did was fetch the latest kernel.org patches from here and cherry pick them on top of the latest kernel source from Google.

I merge these patches by cherry-picking each version individually (3.10.73 to 3.10.74, 3.10.74 to 3.10.75, etc), that way I can verify that the kernel compiles fine and that there are no merge conflicts. Google will sometimes pick certain commits from upstream that are of a higher importance than others which can result in conflicts if you try to pick it again. Additionally, upstream might fix a bug one way and Google has done it another (which is not really good, Google should be pushing their fixes back to upstream so everything stays in sync).

What do I do with this?

I have created two repos below: one with the latest N security update branch with the latest upstream patches picked up on top of it (the bullhead-upstream branch) and another one with a plain AnyKernel source for you to modify (bullhead-stock is the most basic, bullhead-decrypt contains an fstab file that will disable both forced encryption and dm-verity). You are free to fork these or base other branches on them, that's the whole point of this post. I have verified that all the patches contain no major detectable issues. I would like some credit if you do use it but it's not required since the kernel is licensed under GPL :) Another reason I offer this is I have seen a lot of developers picking in upstream in patch sets, so you get one single commit for an upstream version. This is detrimental as you start to add your own patches as you cannot fully tell what was modified and for what reason without the individual commits. It might look cleaner but you don't get full history which hurts you in the long run.

Links

Kernel source: https://github.com/nathanchance/bullhead/tree/upstream-7.1.2

AnyKernel source: https://github.com/nathanchance/AnyKernel2/tree/bullhead-stock-decrypt

Toolchain source: https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/

How to compile

This will be a quick, step by step guide on how to compile this kernel from source. By using this process, you can start to make modifications to the kernel source and make a flashable zip.

Clone the kernel source, the AnyKernel source, and toolchain source

cd ~
mkdir Kernel && cd Kernel
git clone https://github.com/nathanchance/bullhead.git source
git clone https://github.com/nathanchance/AnyKernel2.git anykernel
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 AOSP-4.9

Explanation:

First command: make sure you are in your home directory (or whatever directory you want to hold the kernel folder we are about to make.

Second command: make a Kernel folder and move into it

Third command: clone the kernel source from my repo into a folder named source

Fourth command: clone the AnyKernel source from my repo into a folder named anykernel

Fifth command: clone the Google 4.9 toolchain into a folder named AOSP-4.9

AnyKernel is the name of the zip we are going to make which allows the kernel to be flashed over any ROM.

A toolchain is a set of compiler tools that allow us to compile the kernel on any computer architecture.

Make sure you are on the correct branches

cd source && git checkout upstream-7.1.2
cd ../anykernel && git checkout bullhead-stock-decrypt

Explanation:

First command: move into the source directory and checkout the branch "upstream-7.1.2", which has all of the necessary patches in it.

Second command: move into the AnyKernel directory and checkout the branch "bullhead-decrypt". If you don't want to disable forced encryption, use the "bullhead-stock" branch.

Tell the compiler what you are are compiling

export CROSS_COMPILE=${HOME}/Kernel/AOSP-4.9/bin/aarch64-linux-android-
export ARCH=arm64 && export SUBARCH=arm64
make clean && make mrproper
make bullhead_defconfig

Explanation:

First command: point the compiler to the location of your toolchain. If you have done anything different with the folder locations, you will need to modify the "${HOME}/Kernel/AOSP-4.9" part.

Second command: tell the compiler which architecture we are compiling for. In this case, our device is an arm64 device.

Third command: clean out any compiled files and remove our previous defconfig.

Fourth command: tell the compiler which options we want in the kernel using the bullhead_defconfig.

A defconfig is a file that will tell the compiler which features we want in the kernel. No computer ever uses all of the options in the kernel since there are different drivers for various devices.

Make the kernel!

make -j$(nproc --all)

Explanation:

make tells the compiler to make the kernel (duh) and the -j$(nproc --all) tells the compiler to use the maximum number of cores your computer has available

Make the AnyKernel zip

cp -v arch/arm64/boot/Image.gz-dtb ../anykernel/zImage-dtb
cd ../anykernel
zip -r9 stock-upstream.zip * -x README stock-upstream.zip

Explanation:

First command: copies the completed kernel (Image.gz-dtb) into the AnyKernel folder

Second command: moves us into the AnyKernel folder

Third command: makes the zip file (named stock-upstream.zip) in the AnyKernel folder.

If you ever want to do this again, run these commands and go straight to step 3:

cd source && git clean -fxd && git pull
cd anykernel && git clean -fxd && git pull

NOTE: This thread is aimed to be a breeding ground for kernel development, a place to jump off if you will. I am happy to answer how to questions about building kernels or flashing the one I have provided but this is not supposed to be a general Q&A thread. Please use another thread or create your own in Q&A if you need assistance.