[AT&T Samsung Galaxy Note II] garyd9:
Now that we have a copy of a factory boot image, we'll unpack that image into it's component parts. There are three tools used for manipulating boot images that we should download and place somewhere on our path. The following commands, copied into a terminal window on our build machine, will take care of that:

cd ~/bin
wget https://github.com/garyd9/kernel-howto-misc/raw/master/mkbootfs
wget https://github.com/garyd9/kernel-howto-misc/raw/master/mkbootimg
wget https://github.com/garyd9/kernel-howto-misc/raw/master/unpackbootimg
chmod a+x mkbootfs
chmod a+x mkbootimg
chmod a+x unpackbootimg

Before going on, it's important to give credit where due: The three boot image utilities were compiled from sources in the cyanogenmod 10 repository. mkbookimg and mkbootfs appear to originate from AOSP, and unpackbootimg appears to originate from Koush (of ClockworkMod fame.) The sources for cyanogenmod can be found at https://github.com/CyanogenMod.​

The three tools are:

unpackbootimg

- used to unpack a full boot/kernel image into the ramdisk, kernel, and other files containing certain parameters.

mkbootfs

- used to combine or archive a directory structure into a ramdisk image. (The same thing can be accomplished with the cpio utility)

mkbootimg

- used to combine a kernel and initramfs image into a boot image that can be installed on a device.

To unpack the parts of the stock boot image, open a terminal window on your build machine and copy the following commands. As always, if paths or filenames have been changed from this guide, the commands should be altered to correspond to those changes.

cd ~/kernel-howto
mkdir stockbootimg
unpackbootimg -i boot_orig.img -o stockbootimg
ls -l stockbootimg

Here, the -i parameter is used to specify "boot_orig.img" as the image to unpack, and the -o parameter specifies that the results of unpacking the image should be placed in a sub-directory called "stockbootimg".

In the list of commands above, the last one just will list the files unpacked in the "stockbootimg" sub-directory. At this point, the only one of those files that is significant to us is the one named "boot_orig.img-ramdisk.gz." That file is the actual compressed ramdisk image used as the initramfs in the stock kernel. The file ending with "zImage" is the actual stock kernel, and the remaining files contain boot image values that are beyond the scope of this guide. (If someone is planning on manipulating things like the page size or base address, they likely have a skill/knowledge level far exceeding the audience of this document.)

There's really nothing special about the compressed ramdisk image. It's simply a directory structure archived with the "cpio" utility and compressed with gzip. In fact, if you copy the following command to your terminal window, you'll be able to see what's inside:

gunzip -c ~/kernel-howto/stockbootimg/boot_orig.img-ramdisk.gz | cpio -it

Later, we'll extract the files from the stock initramfs and make some changes. For now, however, we'll just use the compressed ramdisk as it is and combine it with the kernel we built earlier. (Normally when rebuilding the kernel, the kernel modules in the initramfs are replaced with ones from the new kernel compile, but we'll skip that step for now.)

Assuming you've already built the kernel (as described a few sections ago), the finished kernel should exist as ~/kernel-howto/linux_kernel_sgh-i317/arch/arm/boot/zImage. The following command will combine that kernel we compiled with the stock initramfs image we just unpacked:

cd ~/kernel-howto
mkdir first_bootimg
mkbootimg --kernel ~/kernel-howto/linux_kernel_sgh-i317/arch/arm/boot/zImage --ramdisk ~/kernel-howto/stockbootimg/boot_orig.img-ramdisk.gz -o first_bootimg/boot.img

The "--kernel" and "--ramdisk" parameters should be pretty obvious, and the "-o" parameter specifies where to put the final boot image. There are several other parameters for mkbootimg, but none of them are needed here as the defaults work fine. In most cases, the values for the parameters can be found by examining the files unpacked after running unpackbootimg.

We now have a fully functional kernel that we can install on our device and test with. Connect your phone to the build machine, and run the following commands to copy the new boot image to your phone (but not yet installed it.) This uses adb to first create a new sub-directory to place the image, and then to push the new image into that location

adb shell mkdir /sdcard/first_bootimg
adb push ~/kernel-howto/first_bootimg/boot.img /sdcard/first_bootimg/boot.img

WAIT! DON'T INSTALL THIS KERNEL IF YOU DON'T HAVE A BACKUP. THIS KERNEL WON'T WORK PROPERLY AND YOU WILL NEED TO RESTORE A BACKUP KERNEL FOR FULL FUNCTIONALITY

The first step to installing a new kernel should always be to ensure that a backup has been made of the device. Once a good backup has been made, there are actually multiple ways to install the kernel. Each, however, just copies the boot image to the devices boot/kernel patition device node. This was identified in an earlier section and for the SGH-i317 is /dev/block/mmcblk0p8. To do this manually, and assuming the device is already connected to the build machine, get a rooted adb shell and copy the following command making any required change to the device node. Make sure to be in a rooted adb shell first!

dd if=/sdcard/first_bootimg/boot.img of=/dev/block/mmcblk0p8 bs=4096

That's it - it's installed. We can unplug our device and reboot the new kernel into existance.

If a person is using a Samsung device that's supported by Mobile ODIN (developed by Chainfire), they can also use that program to install the boot image directory by simply selecting it as the kernel to flash. This actually tends to be a bit safer than using the 'dd' command, as there's no risk of typing the wrong device node filename. However, the boot image MUST be named "boot.img" for this to work.​

When it is done rebooting, you'll be using your new kernel. As we haven't made any changes to the kernel at this point, the only way to tell the difference will be to go into Settings (on the device), and tap "About device" The line for the "Kernel Version" should now include the username you use on your linux build machine. In this particular case, there's another way to determine if we're using the new kernel: Try using the "soft" keys (the 'menu' and 'back' keys on either side of the home button.) They don't work.

Welcome to the Wonderful World of Kernel Development. There's a reason why those soft keys don't work, and we'll discuss that reason (and a resolution) in the next section. For now, we should just restore our kernel backup and wait for the next section to be posted.

After a fully functional kernel is restored, copy the following commands into a terminal window with the device connected to clean up the mess:

adb shell rm -r /sdcard/first_bootimg
cd ~/kernel-howto
rm -rf first_bootimg