For the past couple of weeks, I’ve been trying to port the Samsung Galaxy Note 3 Neo over to support modern TWRP versions and ROMs. Right now, the device only has a couple of ROM zips and TWRP builds that are all dirty-ported - as in, the images were unpacked and patched by hand. Which means they all run like absolute crap. The TWRP build is old - made back in the KitKat era with a version tag of 184.108.40.206 - and poorly ported, resulting in broken graphics and buttons.
Tip #0 - compiling is always better than patchwork porting, because you can get reproducible results every time you build, rather than a hodge-podge of things that may break at any time.
Porting Finding the kernel
First off, I spent way too much time thinking I would have to use the GPL kernel dump from Samsung, and tried to figure out exactly what kernel revision Samsung based their kernels off of. Because Samsung only provides you with a tarball and not the
git repository, you need to run a script to brute-force-find the revision. But that takes too long!
Luckily, @Jackeagle from Team Bliss pointed out LineageOS already has a kernel for Samsung MSM8974 devices. Oh, so that’s compatible? Let’s use it!
Tip #1 - most SoC kernels (think
oneplus_msmxxxx) are compatible with your device. Someone might have done the hard work of finding the revision for you!
I forked the repository over to my GitHub and copied the
lineage_hltekor_defconfig file so that I could start with
So far so good. What’s next?
Tweaking the defconfig
Next, I enabled the
When you do this, remember to turn off the
hltekor defconfigs (or whatever device you’re basing your defconfig off of).
Tip #2 - On Samsung devices at least, there are accompanying
X_PROJECT flags that must be enabled/disabled along with your device flags.
Then I tried a build. The build failed. That’s OK. What did I fail on? I2C issues. @pivcer from Team Bliss told me I was missing the proper NFC I2C flags. So I enabled them (while disabling the
Tip #3 - read the error messages! Often, it will tell you what variable is missing or what is double-defined. Then you have to
grep -r "variable_name" . in the source and find what module the code is in, then figure out what flags you need to enable/disable in the defconfig to get it to properly build.
Then I tried rebuilding. The build failed. OK, what’s next?
Weirdly, I ran into a situation where the build system wouldn’t find a defined variable:
I spent a long time debugging this, but ultimately whittled it down to one module that wasn’t being built. This module was the Qualcomm MSM camera module, and it wasn’t being built because the configuration file left out my device flag. Adding the device flag solved the issue.
Tip #4 - Sometimes, your kernel tree may ship broken. Then it is up to you to make patches like the above. Don’t assume the kernel will work because it’s a GPL dump direct from the manufacturer or because it’s heavily used by a ROM team!
So with those patches, the build succeeded and I got a
zImage file. Yay! What’s next?
I followed much of the same procedure for TWRP. I forked the
hltekor device tree and based my modifications off of that. I copied the prebuilt kernel that I built earlier and tried a build.
If you try this yourself, you will probably get errors. That’s OK. Read what the errors are on about and make tweaks to your makefiles.
Yes, this is a very boring process. It took me weeks because I was getting so disappointed at the constant build failures. I really thought I would never finish.
When I finally got TWRP to compile fully it was really exciting, although not as exciting as when I fixed that stupid camera module bug detailed above in the kernel.
So what’s next?
Fin (for now)
Unfortunately, this is where my attempt draws to an end. Once I tried flashing the images, the phone wouldn’t boot with the new custom kernel I built.
My wild guess is some of the
hltekor touchscreen drivers are conflicting with the Note 3 Neo hardware (the Note 3 Neo has a 720p panel while the Note 3 has the 1080p panel, so maybe they have different touchscreen chips and panel configurations).
To help debug, I tried pulling
/proc/last_kmesg, but it didn’t provide any useful information. I’m guessing the kernel isn’t even getting loaded properly, which is pretty weird because even if it’s a driver issue it should still get me something. I’ve looked around for a debug cable I can use to possibly get serial access, but because I don’t have access to my soldering kit right now I guess it will have to wait.
So this is as far as I will get for now. If you want to try this process yourself, all of the device and kernel trees are available on my GitHub. Please do let me know via email if you find a fix!
Thanks to the MSM8974 kernel maintainers and the
hltekor maintainers over at LineageOS for the base tree, and thanks to the members over at the Linux Kernel chat over at Telegram and the team members at Team Bliss for helping me with the kernel compilation.