TipsAndTricks/DemystifyingTheLinuxYoctoKernel

Despite the existence of plenty of in-depth documentation out there on working with kernels in Yocto, most people seem to still view the subject as 'a riddle, wrapped in a mystery, inside an enigma'. [1][2]
This is the first in what should be a short series of articles dealing with Yocto kernels, focusing only on the bare essentials.
Let's start first with the kernel itself. When most people think of a kernel in Yocto, they tend to think of it as something that's wrapped inside a kernel recipe, which in turn is something that's wrapped inside the build system and generated into the final image. That's all true and valid, but all those extra layers (let's call them the mystery and the enigma for now) obscure the kernel of truth at the center (the riddle). Let's just look at the riddle and come back some other day to explain the mystery and the enigma.
At its heart, a Yocto kernel is just exactly the same thing as an upstream Linux kernel.
To make that point clear, let's take a quick look at a typical kernel development workflow outside of Yocto (don't let the phrase 'kernel development workflow' scare you off - for the purposes of this article it just refers to compiling and building and possibly configuring a kernel, which is something anyone dealing with a build system like Yocto should be comfortable with).
To modify code, configure, build, and boot a new kernel outside of Yocto, you'd typically do something like this [3]:
 $ edit the kernel source (or don't if you're just configuring or building)
 $ make menuconfig
 .
 .
 select/deselect new config items
 .
 .
 $ make bzImage
 $ scp arch/x86/boot/bzImage 10.0.0.18/mnt/bzImage
 .
 .
 reboot target and see changes
The same thing in Yocto would be:
 $ edit the kernel source (or don't if you're just configuring or building) [4]
 $ bitbake -c menuconfig virtual/kernel
 .
 .
 select/deselect new config items
 .
 .
 $ bitbake -c compile -f virtual/kernel
 $ scp tmp/work/core2-32-intel-common-poky-linux/linux-yocto/4.1.26+gitAUTOINC+9f68667031_9195020e57-r0/linux-core2-32-intel-common-standard-build/arch/x86/boot/bzImage 10.0.0.18:/mnt/bzImage
 .
 .
 reboot target and see changes
As you can see, the only differences in the Yocto version are trivial: in Yocto, you use 'bitbake' instead of 'make', and in Yocto, you have to deal with a godawful long and ugly path to the final kernel image. [5]
Even though it's very similar at its barest level, the Yocto version gives you one thing that the non-Yocto version doesn't - the ability to cross-compile for a different target, which is automatically hidden beneath the 'bitbake' command. In this example, we may happen to be building on the same type of host as we are targeting, for example, x86-64, but with the Yocto/bitbake version, we could build for any target and it would use essentially the same procedure.
Of course, this says nothing about saving your changes and allowing other users to access them, which is basically what the rest of the build system is all about, and which for now is a mystery we'll cover in a future article.
[1] Yocto kernel labs
[2] Yocto Kernel Development Manual
[3] This assumes that the target is network-connected and you've mounted the boot partition at /mnt on the target, e.g.:
 $ mount /dev/mmcblk0p1 /mnt
[4] In the Yocto version, the source you'd modify is located at something like tmp/work/core2-32-intel-common-poky-linux/linux-yocto/4.1.26+gitAUTOINC+9f68667031_9195020e57-r0/linux-core2-32-intel-common-standard-build/source/ (see [5] for context)
[5] This is nothing mysterious either. Just start at the build directory and follow the path to the kernel like so (this is just a typical example - there normally aren't many ways to get lost, making it look worse than it is):
 $ cd tmp
 $ cd work
 $ cd core2-32-intel-common-poky-linux
 $ cd linux-yocto
 $ cd 4.1.26+gitAUTOINC+9f68667031_9195020e57-r0
 $ cd linux-core2-32-intel-common-standard-build
 $ scp arch/x86/boot/bzImage target:/mnt/bzImage