[OnePlus 3 ROMs, Kernels, Recoveries, & Other Devel] bedalus:
I realise this isn't very exciting (yet) but I'm posting here to keep a public log of this kernel development from scratch.

About me: I developed for the Nexus S ages ago! Left XDA but have since returned, hoping to keep things more low key.

Github commits

Commit fb944f9:

I just want to go over the build script a little for anyone who might like a little insight into the development process.

echo -e "Making OnePlus 3 kernel\n"
export PATH=$PATH:/opt/toolchain/lin531/bin/
export ARCH=arm64
export SUBARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make msm-perf_defconfig

make -j5

# modules
find ./ -type f -name '*.ko' -exec cp -f {} ../zip/system/lib/modules/ \;

# copy zImage
cp -f arch/arm64/boot/Image.gz-dtb ../zip/kernel/zImage
ls -l ../zip/kernel/zImage
cd ../zip
zip -r -9 op3_vN.zip * > /dev/null
mv op3_vN.zip /mnt/c/Users/bedal/Downloads/

I've got my cross compiler located at /opt/toolchain which I believe is pretty standard. The cross compiler is Linaro, although there are many other choices available. I've selected Linaro because they are a large professional organisation, and contribute a lot to development on ARM architectures. ARCH is short for Architecture, as you can see in the top lines. The export command just passes the target architecture to the compiler, so we can build binaries that will execute on ARM chips.

It's also worth noting that we are cross compiling since we are developing on a different platform to our target. In fact I'm using bash for Windows on a 64 bit Lenovo laptop! This is an AMD64 architecture, which used to be commonly known as x86_64.

make -j5

This sets the build off, then

find ./ -type f -name '*.ko' -exec cp -f {} ../zip/system/lib/modules/ \;

...is just a handy bit of code to find any modules and move them to the necessary spot in my 'zip' subfolder. As it happens I'm building only the WiFi module, as the wifi code appears to have a problem running when built into the kernel binary.

The rest of the code is fairly trivial. The zip file that you flash in Recovery is just the new kernel binary, plus the wifi module, plus a script that extracts your existing ramdisk from your ROM's boot partition, discarding the old kernel binary in favour of the new one, before re-integrating and flashing back to the boot partition. I may go into that in more detail in a later post.

Commit e5403fd:

I want to just briefly mention the file: sound/soc/codecs/tfa9890/tfa_container.c

In order to better ensure that the kernel works correctly, the compiler will report anything it sees as an error and stop compiling. When I first tried to build the kernel, one of the first errors I got was with this file. The warning the compiler gave me was something like 'in procedure blah-blah, an if statement will always evaluate to TRUE'. So why is this a problem? Because clearly the developer used an if statement so that a choice could be made. If the condition specified in the if statement evaluates to TRUE, do one thing, if not (ie FALSE) then do some other thing. So the compiler suggests caution, because clearly an if statement can only pick the first option if the condition is always going to be TRUE.

[COLOR="Red"]if (!prof->list[i].type == dscRegister) {[/COLOR]
[COLOR="SeaGreen"]if (prof->list[i].type == dscRegister) {[/COLOR]

My solution (above) shows the line that was removed in red, and the replacement in green, and it should be pretty obvious that the exclamation mark was removed, and no other changes were made.

The reason that I bring up this specific change is that I've seen other solutions to this problem in other dev's source code, and while they may trick the compiler into believing the problem is solved, really the problem is worse. Generally speaking, it is in fact possible, indeed probable that code will make it through the compiler just fine, even though when executed it will cause a fatal error (an error that cannot be recovered from, ie a crash). So what's up with this code?

The exclamation mark is shorthand in C for 'NOT'. NOT reverses a boolean value, ie Y becomes N, N would become Y, and TRUE -> FALSE and of course FALSE -> TRUE!

We can see in the code that it appears to be trying to invert the logic of a list type. Let's pretend it's a shopping list. So what would 'NOT shopping list' be? One thing that's not a shopping list? Or all the things that aren't shopping lists? It's a nonsensical proposition, and I think some developers have looked at the code and thought, 'huh, that's in the wrong place,' and have fixed it by taking it out of the brackets.

if !(prof->list[i].type == dscRegister) {

If you remember your high-school maths, the contents of brackets are always evaluated first. The fixed (wrongly) code now tests if one list type now matches another. That's fine, if it's a match then we get TRUE. If not then FALSE. Now we know if whether it's one or the other, the '!' will flip it. Then the if statement will progress to the next bit of code, doing whichever thing is required based on the outcome of the test.

That's all well and good. The compiler can see this and compile it without throwing an error. The problem is that the '!' shouldn't be there at all. If this wrong-code is ever executed, because the '!' has flipped the logic, the wrong path will be taken.

Any other devs who are reading this and know this may be the method they used to fix the compiler warning should take a good look at the code in that one file. It should be obvious that the '!' shouldn't have been there at all, and was probably a typo at the original development stage that wasn't picked up by their compiler (older compilers couldn't spot as many different kinds of problem).

Any discussion will be most welcome. This is the sort of thing I feel should be going on at XDA but seems to be conspicuously lacking in the development forums!