FORUMS
Remove All Ads from XDA

[GUIDE] How to Build and Package a Kernel [D2]

1,523 posts
Thanks Meter: 5,078
 
Post Reply Email Thread
This thread aims to be a comprehensive guide to building and packaging kernels for US Variant Samsung Galaxy SIIIs
In my opinion, a kernel is a great way to get into building things for your device and its pretty easy to do too.


Intro
Quote:

What is a kernel?
http://en.wikipedia.org/wiki/Kernel_(computing)

This guide is for US SGSIII's (d2att,d2cri,d2mtr,d2spr,d2tmo,d2usc,d2vzw,others? )
It may be possible to adapt this to other devices, but I am not responsible for anything that happens should you try to do this.

This guide assumes you have a general knowledge of the Linux operating system. If you've never used it, you might consider playing around
with it for awhile before attempting this guide.


Prerequisites
Quote:

On all devices you must be rooted, on Verizon SGS3 (d2vzw) you must also have the unlocked (VRALE6) bootloader installed.
This is not the thread for figuring out how to do this. You can use the forum's search function to figure out how to do this on your device.

You'll need a computer or a virtual machine running ubuntu. You may be able to figure out how to get this working on other distributions,
but since ubuntu is generally the most accepted distribution to use for building android things, I'll stick to using that here.
At the time of this writing, I'm using ubuntu 12.10, 64-bit.

You'll need to install some packages on your ubuntu machine:

Code:
sudo apt-get install build-essential git zip unzip
On 64-bit you'll also need some multilib and 32-bit compatibility packages:
Code:
sudo apt-get install gcc-multilib g++-multilib lib32z1-dev

Setting up the Build Environment
Quote:

Next, you'll need a toolchain which is used to actually build the kernel. You may download one of these:
GCC 4.4.3: Download || Mirror
GCC 4.6: Download || Mirror
GCC 4.7: Download || Mirror
If you aren't sure, go for 4.4.3 or 4.6.
4.7 requires some code changes to work. The original kernel developer may or may not have made these changes.

Here is what I needed to do in order for 4.7 to build, boot and have wifi work:
https://github.com/invisiblek/linux-...3fc15ae71fbdea
https://github.com/invisiblek/linux-...c4dae81ddfd0a6

The toolchains are also available in the android NDK.
*** There are many toolchains out there, some of you may know of the Linaro toolchain which is aimed to optimize your binary even further ***
*** If you choose to use a different toolchain, that is fine. Keep in mind that you may run into issues depending on the toolchain you use ***


You can check what your currently running kernel was built with by issuing these commands:

Code:
adb root
adb shell cat /proc/version
It should return something like:
Quote:

Linux version 3.4.0-cyanogenmod-gc4f332c-00230-g93fb4aa-dirty (dp@build-vm) (gcc version 4.7 (GCC) ) #134 SMP PREEMPT Thu Feb 28 00:22:41 CST 2013

This shows my particular kernel here was built with GCC 4.7

You can use wget to download one of the links from above, in this instance we'll download version 4.4.3 from the first link:
Code:
wget http://invisiblek.org/arm-eabi-4.4.3.tar.bz2
Extract this to somewhere you will remember, probably your home directory.
Code:
mkdir arm-eabi-4.4.3
tar -xf arm-eabi-4.4.3.tar.bz2 -C arm-eabi-4.4.3/


Obtaining Source
Quote:

Find someone's source to use as a base. This can be a source archive from Samsung, a kernel tree from CyanogenMod, or any other developer around that makes kernels for your device.

TIMEOUT

Quote:

This is a good spot to stop and take note that the Linux kernel is licensed under the GNU General Public License (GPL): http://www.gnu.org/licenses/gpl-2.0.html
What does this mean you ask? It means that if you plan to share your kernel with the community (if it's good, please do so!) then you MUST share your
source code as well. I am not liable for what you choose to do once you start building kernels, but know this: if you share your kernel and do not
provide source code for it, you will get warnings from XDA for a determined amount of time, after that you may have your threads closed, deleted and
possibly your user account terminated. This is extremely important!

Also, you may run into more problems than just XDA. There are organizations out there that do take action if you consistently refuse to comply with the GPL.
I recommend you read this: http://www.gnu.org/licenses/gpl-2.0.html so that you are familiar with what legalities you are getting yourself into.

The main thing to remember is to share your source code if you decide to share your built kernel.

In this instance, we will use CyanogenMod's kernel source for the US Galaxy S3's. You may browse the source code here:
https://github.com/CyanogenMod/andro...nel_samsung_d2
You'll notice that the branch there is cm-10.1
This is the default branch of this repository on github. This means that if you intend to build this branch, you'll need to use it on CM version 10.1. Most
likely it will not function on another version.

To obtain the source code:
Code:
git clone https://github.com/CyanogenMod/android_kernel_samsung_d2
This will take a little while, be patient.

When done, you'll have a directory called android_kernel_samsung_d2, cd into this directory.
Code:
cd android_kernel_samsung_d2
Next, you'll need to set up a couple environment variables. These tell the system two things:
1. What CPU architecture to build for, in this case arm
2. Where to find the toolchain we downloaded earlier, so that the system can cross compile for arm

Code:
export ARCH=arm
export CROSS_COMPILE=~/arm-eabi-4.4.3/bin/arm-eabi-
You'll need to set these variables on each new session. You can modify your Makefile in the root of your kernel tree in order to have these set permanently.


Building
Quote:

At this point you can make any changes to the source code that you want. If this is your first time, I recommend not making any changes and make sure you have a
sane build environment before adding any complications.

When you build a kernel, you need to choose a defconfig. This is a specialized configuration file, specifically tailored for your device.
CyanogenMod names their defconfigs for their devices like so: cyanogen_<device>_defconfig and they are located in arch/arm/configs/

Code:
ls arch/arm/configs/cyanogen*
In this example, we will build for d2vzw.

Set up your tree to build for the d2vzw:
Code:
make cyanogen_d2vzw_defconfig
(do this in your kernel's root directory, in this example it was android_kernel_samsung_d2/ )

Now you are ready to build:
First, determine how many cpu's your computer has. You'll use this number to determine how many jobs the compiler command will use. The more jobs you can use, the more
cpu threads the compile will take advantage of, thus you'll get faster builds. If you don't know, just assume you'll use the number 2. We'll use 2 as an example here.

Code:
make -j2
Where 2 is the number of CPU cores your build system has.

And now we wait...until it's done compiling...

You'll know it successfully compiled when you have this line when it stops:
Quote:

Kernel: arch/arm/boot/zImage is ready


PROTIP:
Quote:

If it stops somewhere other than "zImage is ready" then you had build errors. Try running the 'make' command with no options after it. This will run the compile on a single thread
and will cause it to stop compiling as soon as it hits an error. When you run it on multiple threads, it definitely goes much faster, but if an error occurs, the console doesn't stop
until it finishes all of its threads. Causing you to have to scroll up and search around for an error

Now, assuming the build completed successfully, you have two things you are concerned with: A zImage (the kernel binary itself) and your kernel modules, which get built based
on what was configured in your defconfig.

You'll find your zImage at: arch/arm/boot/zImage
Code:
ls arch/arm/boot/zImage
The modules are scattered all over the place, depending on where the source existed that they were compiled from. We can easily search for them using this command:
Code:
find . -name "*.ko"
If both of the previous commands completed, you are now ready to package your kernel up for testing.

Move up a directory before continuing.
Code:
cd ..


Packaging
Quote:

You may know of an awesome developer by the name of koush.
Well, once upon a time, koush created a rather simple zip, called AnyKernel, that would flash a kernel on a device, regardless of what ramdisk the kernel has on it.
I've taken his zip and modified it for d2 devices and to work with the newer recoveries out there.
This has a script in it that will dump your current boot.img (kernel+ramdisk), unpack it, replace the kernel, repack it and flash it.
It'll also copy any modules to the proper directory (/system/lib/modules) and set permissions appropriately.
You can get a zip here: Download || Mirror
(You can get it here as well: https://github.com/invisiblek/AnyKernel )
(Everyone is invited to use this zip, it'll probably make your life easier to not have to worry about the ramdisk. Enjoy!)

IMPORTANT

Quote:

This AnyKernel package is for US variations of the Galaxy S3.
NOT the international (I9300) or any other device.
There are checks in the updater-script that will ensure you are running a d2 device before it does anything.
If you were to remove these checks, and not modify the partition that it flashes to later, you could end up with a brick.
If you intend to adapt this package for another device (please, do this! its a very handy script!), make sure you know it well, or ask someone to help you determine your device's
partition scheme before using it.

The risk here is due to the fact that the script doesn't know your device's partition scheme. It is configured specifically for the d2 devices. Flashing it on something else, who's boot
partition is somewhere else, might cause a bad flash to the bootloader partition (bad bad news if this happens).

Just be careful if you want to use this on another device. You won't run into problems if you use this on a d2 device.

EDIT: I made modifications that should make this less likely, but please, if you intend to use this on a different device (which is completely fine!) make sure you configure
the scripts to flash to the proper partitions.

Download and extract one of the above, we'll again use the first link for this example:
Code:
wget http://invisiblek.org/AnyKernel_samsung-d2.zip
unzip AnyKernel_samsung-d2.zip -d AnyKernel/
Now we'll copy our newly compiled zImage (still referring to the same kernel directory we used above, your repo might be called something different)
Code:
cp android_kernel_samsung_d2/arch/arm/boot/zImage AnyKernel/kernel/
cp `find android_kernel_samsung_d2 -name "*.ko"` AnyKernel/modules/
Finally we are ready to zip this up and test out flashing it.
Code:
cd AnyKernel
zip ../MyAwesomeKernel.zip -r *
cd ..
You'll now have a file named MyAwesomeKernel.zip which you should be able to flash via custom recovery (TWRP or CWM)


Extra Credit/Protips
Quote:

Learn to use git. It's very powerful and great way to store your code.

Learn to use adb. It's an invaluable tool for any android developer.

Touchwiz and AOSP-based kernels are different. This means you cannot take CyanogenMod's source, build a kernel and expect it to work on a Touchwiz-based ROM.

Build a ROM next: http://wiki.cyanogenmod.org/w/Build_for_d2vzw

Crackflash your own stuff!

ALWAYS NANDROID!


Source code for all of my projects can be found here: http://github.com/invisiblek
The Following 21 Users Say Thank You to invisiblek For This Useful Post: [ View ]
 
 
28th February 2013, 05:09 AM |#2  
FAQ

Q: How do I update my source tree to the latest that is available from where I downloaded it?
A: This can be handy if, for instance, you are building a CyanogenMod kernel and they added some patches, after you downloaded the source, that you want to include in your next build. You'll want to cd to your kernel tree and issue a git pull:
Code:
cd android_kernel_samsung_d2
git pull
You may then continue with the building instructions.
This may, however, have other problems if you've made changes to files. You might run into conflicts. I won't cover fixing any of this here, its not in the scope of this thread.


Q: I'm using X as a kernel base, but Y has a patch that I really like. How do I get it in my kernel easily?
A: I'll let you check Google for this answer, but I'll give you a hint use: git cherry-pick
The Following 5 Users Say Thank You to invisiblek For This Useful Post: [ View ]
28th February 2013, 01:34 PM |#3  
sbreen94's Avatar
Recognized Contributor / Recognized Developer
Thanks Meter: 22,790
 
Donate to Me
More
Nice tutorial bro! Always good to learn something new everyday
28th February 2013, 02:00 PM |#4  
Account currently disabled
Thanks Meter: 16
 
More
Really is a good thread,thanks
28th February 2013, 04:33 PM |#5  
Rath1on's Avatar
Senior Member
Thanks Meter: 208
 
Donate to Me
More
This guide would have made things too easy for me.

Too easy, indeed. haha

Great job, invisiblek! AnyKernel is the beez neez.
The Following User Says Thank You to Rath1on For This Useful Post: [ View ] Gift Rath1on Ad-Free
12th June 2013, 10:41 AM |#6  
spc_hicks09's Avatar
Recognized Contributor
Flag Marion, OH
Thanks Meter: 1,838
 
Donate to Me
More
Ok so this is a noob question but I gotta ask anyway lol. Ok so I cloned the kernel source, I made my edits, now how do I push all this to my github?

I already have a github account, I already made a new repo for the kernel. Here's a link to my github if you need it...

https://github.com/ghicks12/d2vzw_kernel.git
12th June 2013, 12:06 PM |#7  
GideonX's Avatar
Senior Member
NYC
Thanks Meter: 3,803
 
More
Quote:
Originally Posted by spc_hicks09

Ok so this is a noob question but I gotta ask anyway lol. Ok so I cloned the kernel source, I made my edits, now how do I push all this to my github?

I already have a github account, I already made a new repo for the kernel. Here's a link to my github if you need it...

https://github.com/ghicks12/d2vzw_kernel.git

git remote add origin git_location_you_created_on_github.git
git push -u origin somebranch

The -u is for first time run only, you can just git push afterwards.

Sent from my SCH-I535
The Following User Says Thank You to GideonX For This Useful Post: [ View ] Gift GideonX Ad-Free
12th June 2013, 07:50 PM |#8  
spc_hicks09's Avatar
Recognized Contributor
Flag Marion, OH
Thanks Meter: 1,838
 
Donate to Me
More
Quote:
Originally Posted by GideonX

git remote add origin git_location_you_created_on_github.git
git push -u origin somebranch

The -u is for first time run only, you can just git push afterwards.

Sent from my SCH-I535

Thanks! When I run

Code:
git remote add origin https://github.com/ghicks12/d2vzw_kernel.git
I get this back:

Code:
fatal: remote origin already exists.
I'm editing a CM based kernel, not sure if that matters or not?
12th June 2013, 09:11 PM |#9  
GideonX's Avatar
Senior Member
NYC
Thanks Meter: 3,803
 
More
That just means you added the remote already. Just issue the push command then.

Sent from my SCH-I535
The Following User Says Thank You to GideonX For This Useful Post: [ View ] Gift GideonX Ad-Free
6th August 2013, 06:18 PM |#10  
Senior Member
Thanks Meter: 36
 
More
Why is this happening? I don't know what i did wrong

kevinflathers@ubuntu:~/cm$ make VARIANT_DEFCONFIG=cyanogen_d2att_defconfig
scripts/kconfig/conf --silentoldconfig Kconfig
drivers/media/video/msm/Kconfig:123:warning: choice value used outside its choice group
drivers/media/video/msm/Kconfig:128:warning: choice value used outside its choice group
***
*** Configuration file ".config" not found!
***
*** Please run some configurator (e.g. "make oldconfig" or
*** "make menuconfig" or "make xconfig").
***
make[2]: *** [silentoldconfig] Error 1
make[1]: *** [silentoldconfig] Error 2
make: *** No rule to make target `include/config/auto.conf', needed by `include/config/kernel.release'. Stop.
kevinflathers@ubuntu:~/cm$
16th August 2013, 01:20 AM |#11  
mikejr83's Avatar
Senior Member
Thanks Meter: 125
 
More
Hey. I'm having some problems with some GIT terminology and procedures. I'm a .NET developer and I use TFS and SVN on a daily basis. Forgive me if this is complete off basis from what you'd do with GIT.

What I want to do is merge one branch into another branch. In other words I want to take the latest kernel source from my favorite dev and merge in the latest from cyanogen's 4.3 d2 branch. Is this a rebase thing? It doesn't seem like cherrypicking to me.
Post Reply Subscribe to Thread

Guest Quick Reply (no urls or BBcode)
Message:
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes