Hello everyone! This will be a thread to assist people with upstreaming their device's Android kernel. This thread will assume that you understand how to compile a kernel as well as working with git. If you need assistance with that, please refer to one of the following threads (or search for others):
The case for upstreaming
This section is necessary as many kernel developers have built up this false narrative that upstream breaks drivers and OEM code. That's not universally true, at all, and defies the very definition of a stable kernel. Please read this section if nothing else, it is the most important!
Every Android device runs a version of the Linux kernel. However, that version may not be the latest. For example, my primary device at the time of writing this, the Nexus 6P, is running a 3.10.73 on stock whereas the latest upstream offers is 3.10.107. Other phones are on something as early as 3.10.40 or 3.10.49. Largely, the reason for this is CAF (Code Aurora Forum, an open source collaborative project largely sponsors by Qualcomm) does not merge upstream updates into their kernels, thus OEMs do not do it either.
It's important to stay up to date with the latest from kernel.org as there are many security and bug fixes coming down from the mainline kernel that fix bugs that have been present since 2007 in some cases. As stated by Greg Kroah-Hartman, the second most influential kernel developer, "If you are not using a[n up to date] stable/longterm kernel, your machine is insecure" (source, at 17:10 but I recommend watching the whole thing).
A lot of naysayers will say a lot of the patches from upstream are irrelevant to the architecture of most phones (arm/arm64) or are for drivers we don't have; while that may be true, there are several patches that are relevant and as Greg said in the above video, if you think you can sort through what is relevant, good luck. I personally don't think I am better than the professionals that push this stuff for free, thus I add it all. Greg's even getting sponsored by Google to do this for Google's kernel/common (3.18, 4.4, and 4.9). He's even helping the Google Pixel kernel team upstream the kernel for Android O, as evident by the android-msm-marlin-3.18-o-preview-3 branch. If this were a pointless process, why would Google even be investing time in doing it, especially since 3.18 was end of life before this?
Others will say that upstream can cause instability. While I will concede there may be a few problem patches here and there (listed below), these are NOT the norm, at all. I will argue that if something breaks while adding upstream, you most likely did it wrong (didn't pay attention to conflicts, read the context of every patch, etc) and it's SUPER easy to come back from (see the section below regarding bisecting). Furthermore, read the stable kernel documentation, they are small fixes to real world problems. Follow the below process while paying attention and GUARANTEE you will have no issues.
As another example/point, merging upstream allows you to get ahead of Google's security upstream. The infamous Dirty COW vulnerability, the fix for which released in 3.10.104 (committed on October 20th), was added by Google in the December security update. Sure, you could just add that one patch but you still have to be paying attention to upstream and filtering. It takes less effort to merge it all than it does to pick and choose. Even looking at the December bulletin, there is another critical security bug that they say affects the Pixel devices. It was fixed in 3.18.37, almost six months before it was added by Google. The stable kernels are used by MANY OEMs in real world critical situations and have no issues. These patches are also paid for by a lot of OEMs (check the signoffs since 2015) pushed to the public for free; I personally think it is extremely stupid to pass up on these fixes.
The process is fairly simple but requires finesse when running into conflicts, which I will go over in the tips and tricks section.
1. Figure out which kernel version you are on
This can be done one of two ways: going into Settings > About Phone or opening up the Makefile within your kernel source and looking at the top.
There are four major kernel versions that are used to this day, along with the common chipsets that use them:
3.4 - MSM8974
3.10 - APQ8084, MSM8992, MSM8994
3.18 - MSM8996, MSM8996 Pro
4.4 - MSM8998
The last number in the version (or EXTRAVERSION in the Makefile) will tell you where you need to start. For example, if you are on 3.18.31, you'd be starting at 3.18.32. It's important to get the starting point right so you don't get a ton of conflicts right off the bat.
2. Fetch the latest kernel source from kernel.org
git fetch --tags https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git <branch>
The --tags flag allows you to easily cherry-pick/merge based on the tagged release commit, rather than digging for SHA-1 hashes.
3. Decide if you want to merge or cherry-pick the commits in
Next, you will need to choose if you want to merge the commits or cherry-pick. Here's the pros and cons of each and when you may want to do them.
NOTE: If your kernel source is in the form of a tarball, you will most likely need to cherry-pick, otherwise you will get thousands of file conflicts because git is populating the history based purely on upstream, not what the OEM or CAF has changed. Just skip to step 4.
Pros of cherry-picking:
- Easier to resolve conflicts as you know exactly what conflict is causing an issue.
- Easier to rebase as each commit is on its own.
Cons of cherry-picking:
- It takes longer as each commit has to be individually picked.
- Harder to see on first glance
This may be better for people who like to rebase or bisect a lot as each commit is applied to your own branch, rather than merged together.
Pros of merging:
- It's faster as you do not have to wait for all of the clean patches to merge.
- It's easier to see when a commit is from upstream as you will not be the committer, the upstream maintainer will be.
Cons of merging:
- Resolving conflicts can be a bit more difficult as you will need to look up which commit is causing the conflict, it will not directly tell you.
- Rebasing is difficult as you cannot rebase a merge, it will offer to cherry-pick all of the commit individually.
This is good for people who don't rebase or redo history often (like those who use Gerrit).
4. Add the commits into your source, one version at a time
git cherry-pick <previous_tag>..<current_tag>
git cherry-pick v3.10.73..v3.10.74
git merge <current_tag>
git merge v3.10.74
git add . && git merge --continue
Tips and tricks
1. How to resolve conflicts
While I cannot possibly teach you how to resolve every conflict given that a lot of that involves understanding C, I can give you some helpful hints about how I resolve conflicts.
- Figure out if you already have the commit: Some vendors like Google or CAF will attempt to look upstream for critical bugs, like the Dirty COW fix, and their backports could conflict with upstreams. You can run
git log --grep="<part_of_commit_message>"
- Read what the commit is trying to do and see if the problem is already fixed: Sometimes CAF may fix a bug independent of upstream, meaning you can either overwrite their fix for upstream's or discard it, like above.
Otherwise, it may just be a result of a CAF addition, in which case you just need to shuffle some things around.
I have a mirror of the kernel.org repository on GitHub, which can be easier for looking up commit lists and diffs for conflict resolution. I recommend going to the commit list view first and locating the problem commit to see the original diff to compare it to yours:
2. Enable rerere
Git has a feature called rerere (standing for reuse recorded resolution), meaning that when it detects a conflict, it will record how you resolved it so you can reuse it later. This is especially helpful for both chronic rebasers with both merging and cherry-picking as you will just need to run
git add . && git <merge|cherry-pick> --continue
It can be enabled by running the following command in your kernel repo:
git config rerere.enabled true
3. How to git bisect when running into a compiler or runtime error
Given that you will be adding a sizable number of commits, it's very possible for you to introduce a compiler or runtime error. Instead of just giving up, you can use git's built-in bisect tool to figure out the root cause of the issue! Ideally, you will be building and flashing every single kernel version as you add it so bisecting will take less time if needed but you can bisect 5000 commits without any issues.
What git bisect will do is take a range of commits, from where the issue is present to where it wasn't present, and then start halving the commit range, allowing you to build and test and let it know if it is good or not. It will continue this until it spits out the commit causing your issue. At that point, you can either fix it or revert it.
- Start bisecting:
git bisect start
- Label the current revision as bad:
git bisect bad
- Label a revision as good
git bisect good <sha1>
- Build with the new revision
- Based on the result (if the issue is present or not), tell git:
git bisect good OR git bisect bad
- Rinse and repeat steps 4-5 until the problem commit is found!
- Revert or fix the problem commit.
NOTE: Mergers will need to temporarily run git rebase -i <good_sha> to apply all the patches to your branch for proper bisecting, as bisecting with the merges in place will often times checkout onto the upstream commits, meaning you have none of the Android specific commits. I can go into more depth on this upon request but trust me, it is needed. Once you have identified the problem commit, you can revert or rebase it into the merge.
4. Do NOT squash upstream updates
A lot of new developers are tempted to do this as it is "cleaner" and "easier" to manage. This is terrible for a few reasons:
- Authorship is lost: It's unfair to other developers to have their credit stipped for their work.
- Bisecting is impossible: If you squash a series of commits and something is an issue in that series, it's impossible to tell what commit caused an issue in a squash.
- Future cherry-picks are harder: If you need to rebase with a squashed series, it is difficult/impossible to tell where an conflict results from.
Leave the updates unsquashed, you'll thank me later.
5. Subscribe to the Linux Kernel mailing list for timely updates
In order to get notified whenever there is an upstream update, subscribe to the linux-kernel-announce list. This will allow you to get an email every time a new kernel is released so you can update and push as quick as possible.
6. Commits known to cause runtime or build errors
- ASoC: compress: Fix compress device direction check - Introduced in 3.10.96, this will break sound altogether because Qualcomm sets both playback and capture capabilities on their CPUs as well as compress driver.
- move d_rcu from overlapping d_child to overlapping d_alias - Introduced in 3.10.76, if you have added sdcardfs from kernel/common, this will cause your build to error. Just replace d_u.d_child with just d_child.
- pinctrl: qcom: Don't clear status bit on irq_unmask - Introduced in 3.18.50, this reportedly breaks Dash Charging on OP devices and camera issues on other devices.
Custom kernels that are upstreamed
Jolla Kernel for the Nexus 5X by @jollaman999
B14CKB1RD Kernel for the Nexus 6 by @REV3NT3CH
Sigma Kernel for the Nexus 6 by @neobuddy89
Flash Kernel for the Nexus 6P by @The Flash
Electron Kernel for the Nexus 6P by @frap129
Lightning Kernel for the OnePlus One by @nikhil18
EAS Kernel for the OnePlus 2 by @ anupritaisno1
Haruhi Kernel for the OnePlus 2 by @ anupritaisno1
Kawori Kernel for the OnePlus 2 by @aviraxp
Dorimanx Kernel for the OnePlus 3/3T by @dorimanx
Carbonite Kernel for the OnePlus 5 by @adinkwok
DirtyCORE for the OnePlus 5 by @dabug123
Flash Kernel for the OnePlus 5 by @The Flash
Fusion Kernel for the OnePlus 5 by @jancsessz
Lightning Kernel for the OnePlus 5 by @nikhil18
Kirisakura Kernel for the Pixel XL by @Freak07
IceColdKernel for the Xiaomi Redmi Note 3 by @GreekDragon
Caesium Kernel for YU Yunique by @MSF Jarvis
ROMs with upstreamed kernels built in
- ABC ROM for the Nexus 6P
- AIM ROM for the OnePlus 2
- Carbon ROM
- Dirty Unicorns: Statement | Downloads/Support
- Haruhi ROM for the OnePlus 2
- Pure Nexus: Statement
- Vanilla Android:
I am more than happy to answer any questions regarding this process in this thread. You can use my 7.1.2-base branch as a reference for solving conflicts and seeing how the merge commit style looks. Additionally, if you feel any information is missing or can be improved upon, please let me know! I want this to be a collaborative effort.