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 2.8.7.0 - 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 samsung_msmxxxx or 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 lineage_frescoltekor_defconfig.

So far so good. What’s next?

Tweaking the defconfig

Next, I enabled the frescoltekor defconfigs.

CONFIG_SEC_FRESCO_PROJECT=y
CONFIG_SEC_LOCALE_KOR_FRESCO=y
CONFIG_MACH_FRESCOLTEKTT=y

When you do this, remember to turn off the hltekor defconfigs (or whatever device you’re basing your defconfig off of).

# CONFIG_SEC_H_PROJECT is not set
# CONFIG_SEC_LOCALE_KOR_H is not set
# CONFIG_MACH_HLTEKTT is not set

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 hltekor flags):

# CONFIG_BCM2079X_NFC_I2C is not set
CONFIG_SEC_NFC_I2C=y
# CONFIG_SEC_NFC is not set
CONFIG_NFC_PN547=y

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:

CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 6 of arch/arm/crypto/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 28 of arch/arm/mach-msm/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 55 of mm/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 40 of fs/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 15 of crypto/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 36 of block/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 22 of lib/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 24 of drivers/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 6 of sound/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 6 of arch/arm/oprofile/built-in.o is not in EXIDX output section
/home/users/ideaman924/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 37 of net/built-in.o is not in EXIDX output section
drivers/built-in.o:leds-max77803.c:function max77803_led_get_en_value.part.0: error: undefined reference to 'led_flash_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_get_en_value.part.0: error: undefined reference to 'led_torch_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_probe: error: undefined reference to 'led_torch_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_probe: error: undefined reference to 'led_flash_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_probe: error: undefined reference to 'camera_class'
drivers/built-in.o:temphumidity_shtc1.c:function max77803_led_en: error: undefined reference to 'led_flash_en'
drivers/built-in.o:temphumidity_shtc1.c:function max77803_led_en: error: undefined reference to 'led_torch_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_remove: error: undefined reference to 'camera_class'
Makefile:889: recipe for target '.tmp_vmlinux1' failed
make: *** [.tmp_vmlinux1] Error 1
ideaman924@buildbox:~/android_kernel_samsung_msm8974$

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?

Porting TWRP

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.