Okay, so here we are getting some linux kernel smell. In this post, we will be compiling linux kernel version 3.7 (mainline) . You may be compiling your kernel or atleast thinking of it, because of a number of reasons;
ex- you did a cool hack into kernel source code and wanna try it out working
OR you are working in Embedded Linux environment and doing some development for architecture
OR simply kernel compilation sounds cool!! You can have big talks in front of Girls and your friends or something like that.
Irrespective of the reasons, what matters is if you are doing, then you should do it right and with proper understanding. So we approach like this,
Download the kernel source code
unzip/extract it to some folder of your choice. You must have permissions for that.
We won’t do editing in the source code, just compiling with basic settings/configuration.
We can download the code for linux kernel 3.7 from here
Simply extract the folders form the bunzipped format using tar
$ tar jxvf linux-3.7.tar.bz2
Change the directory to that folder and you are going to see some real stuff
Directories and a few files. Kernel code is beautifully managed by awesome guys and open source advocates and volunteers.
Arch directory contains architectures specific code. If you moves in it then you are going to see various architectures folders and inside them code which is specific to them.
Documentation : this one contains a lot GOLDEN reading material giving most accurate info for the code.
Drivers: this directory contains drivers code which gets compiled as per the architecture via nice play of Makefiles. (actually its not nice.. 😛 )
Include/Lib : contains header files and library files needed for kernel compilation. We will be discussing about the files when we will be reaching to device drivers.
mm & fs : conatins memory management and file system specific code. How the memory management is done, slab allocators, virtual memory, pages and other scary things you may have heard of are in here. Code of file systems like ext2,ext3,ext4,btrfs,jffs2 etc are into the fs directory.
Also, there is one CULPRIT I should say, the MAKEFILE which actually do all the black Magic here. We will just try to know the basics of Makefile in one line that it can execute a few lines of code conditionally. We can make targets i.e. specific lines of code to be executed. The top lines of the kernel Makefile will let you know the exact kernel version you are going to use.
Once entered into the linux kernel folder, we just need to do three simple steps to compile the kernel.
1. Configure the kernel
Configuring the kernel means to put and select those features which you want in your kernel. for ex- I want USB support, ext3 support, some wireless drivers support, etc etc. So, that all is done in the configuration step. There are a few ways to configure the kernel i.e.
$ make <the_wayto_configure>
where, the_wayto_configure refers to some specific words like “config”, “menuconfig”, “kconfig”, “gconfig”, “silentconfig”, “randomconfig”, “allyesconfig” & “defconfig” etc.
all of them do the kernel configuration for us but just the way differs. “config” will be doing it using command line program. I quit when I used it, it is so lenghty!!!!
gconfig and xconfig are gtk and Qt based front end for selecting the options.
allyesconfig will simply enable all the options.
defconfig will make the default configuration automatically enough for running a system.
menuconfig is the one that is based on ncurses library and allows to select the configuration options in terminal only.
So, we are going to use the menuconfig here or one can use defconfig if dont want to bother with the selection process, default setting are just fine.
$ make menuconfig
$ make defconfig
Going through the menu using arrow keys and space bar for selections and then exiting will save the changes and will generate the .config file. .config file is the one which contains all the information related to the kernel i.e. which all things are going to be in the kernel that is about to be compiled.
If one opens it text like this is seen, this is just an example and a few lines out of it.CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not set
# CONFIG_XZ_DEC_TEST is not set
Once our .config file is generated, the work on our end is completed i.e. the real work was just to select and manage what all is needed for the kernel, rest of the things is managed by the kernel build system.
2. Make <ing> the kernel
Now since we have the .config file we just need to start the building process, which is actually managed by the Makefile but for the time now, we wont bother with it.
yes, make just make will do the work, iff we are doing a native build and that too normally.
Native build is building on the machine for the machine itself. Cross compiling is compiling for target machine on some host machine. (Making it simple and not considering Cross-canadian here).
We can put options like which architectue, toolchain to be used and also the number of threads that can be used concurrently so as to speed up the process. But my personal experience has been bad with multiple threads, so I dont prefer using it.
If the build process is successfully completed then you wil be getting an bzImage ready in your architecutre folder under x86/boot section or whatsoever your host architecture was. Rest, i will be continuing in the next post!!