Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Saturday, March 26, 2011

How to Pass Command Line Arguments to a Kernel Module

Generally the word command line arguments make you strike to argc/argv in C, here coming to Linux kernel modules approach is bit different and even easy to....!! lets go for a walk on this concept.

To allow arguments to be passed to your module, declare the variables that will take the values of the command line arguments as global and then use the module_param() macro, defined in linux/moduleparam.h to set the mechanism up.
Value is assigned to this variable at runtime by a command line arguments that are given like $ insmod mymodule.ko myvariable=5 while inserting/loading the module into kernel.

The variable declarations and macros should be placed at the beginning of the module for clarity.

In this post Loadable Kernel Module i have explained the basic concepts of kernel modules.

The module_param() macro takes 3 arguments: 
  • arg1 : The name of the variable.
  • arg2 : Its type
  • arg3 : Permissions for the corresponding file in sysfs. 
Example Code Snippet :

static int myint =51;
module_param(myint, int, 0);
MODULE_PARM_DESC(myint,"this is the int variable");

Integer types can be signed as usual or unsigned. 

MODULE_PARM_DESC() macro used for giving the description of variable.
Example for all the data types are given below:
static int dint;
module_param(dint, int, 0);
MODULE_PARM_DESC(dint,"this is the dynamic int variable");

static short myshort = 51;
module_param(myshort, short, 0);
MODULE_PARM_DESC(myshort,"this is the short variable");
static long int mylong = 45100;
module_param(mylong, long , 0);
MODULE_PARM_DESC(myshort,"this is the long int variable");

static char *mychar = "Smack Down";
module_param(mychar, charp, 0);
MODULE_PARM_DESC(myshort,"this is the characte string variable");

static int myarr[2] = {51,43};
static int arr_argc = 0;
module_param_array(myarr, int,&arr_argc, 0);
MODULE_PARM_DESC(myarr,"this is the array variable");

Example Code:

Code:
#include <linux/kernel.h> /*needed for priority messages in prink*/
#include <linux/init.h> /*needed for macros*/
#include <linux/module.h> /*needed for all modules*/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vamshi Krishna Gajjela");
MODULE_DESCRIPTION("Test Module Parameters");

static short myshort = 51;
static int myint = 451;
static int dint;
static long int mylong = 45100;
static char *mychar = "Smack Down";
static int myarr[2] = {51,43};
static int arr_argc = 0;
static int hello_world2_data __initdata = 3;

module_param(dint, int, 0);
MODULE_PARM_DESC(dint,"this is the dynamic int variable");

module_param(myshort, short, 0);
MODULE_PARM_DESC(myshort,"this is the short variable");

module_param(myint, int, 0);
MODULE_PARM_DESC(myint,"this is the int variable");


module_param(mylong, long , 0);
MODULE_PARM_DESC(myshort,"this is the long int variable");


module_param(mychar, charp, 0);
MODULE_PARM_DESC(myshort,"this is the characte string variable");


module_param_array(myarr, int,&arr_argc, 0);
MODULE_PARM_DESC(myarr,"this is the array variable");

int __init hello_world2_init(void){
 int i;
 printk(KERN_INFO "Vamshi : Entered2 : data = %d",hello_world2_data);
 printk(KERN_INFO "Value of the the short variable is = %hd",myshort);
 printk(KERN_INFO "Value of the the short variable is = %d",myint);
 printk(KERN_INFO "Value of the the dint variable is = %d",dint);
 printk(KERN_INFO "Value of the the short variable is = %ld",mylong);
 printk(KERN_INFO "Value of the the short variable is = %s",mychar);
 for(i=0;i<sizeof(myarr)/sizeof(int);i++){
  printk(KERN_INFO "arr[%d] = %d\n",i,myarr[i]);
 }
 return 0;
}
void __exit hello_world2_exit(void){
 printk(KERN_INFO "Vamshi : Exited2 ");
}

module_init(hello_world2_init);
module_exit(hello_world2_exit);





Note: Copying the code directly into your source.c file will also copies the invisible characters and finally you will left out with stray errors, i recommend you to type the code and that even becomes a practice.

Makefile:
obj-m := hello_world2.o
all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


Building module Sequence Steps:



Click to Download Code

Use Cases of Module Parameters:
  • When there is a need to change the irq line of the module then its the best way to pass the irq number as command line argument using module parameter concept.
  • Base address of the register map of a module can be passed at module load time using insmod based on this command line arguments.


Sunday, March 20, 2011

Hello world Kernel Module.

Kernel module basics are explained in the previous post, and that would help you a lot if you are a beginner, I advise you to go through it first. Here is the link: Kernel module basics.
Hope you have gone through the post on kernel module basics, now it’s simple to write and even easy for me to explain.  Till 2.4 kernels the module init/initialization function is called “init_module” which is called when the module is loaded into kernel using insmod and clean-up/exit function as “cleanup_module” called when the module is unloaded from kernel using rmmod. As of Linux 2.4, you can rename the init and clean-up functions of your modules; they no longer have to be called init_module() and cleanup_module()respectively. This is done with the module_init() and  module_exit() macros. These macros are defined in linux/init.h. The only caveat is that your init and cleanup functions must be defined before calling the macros, otherwise you'll get compilation errors. 


The module_init() macro defines which function is to be called at module insertion time (if the file is compiled as a module), or at boot time: if the file is not compiled as a module the module_init() macro becomes equivalent to __initcall(), which through linker magic ensures that the function is called on boot.
The function can return a negative error number to cause module loading to fail (unfortunately, this has no effect if the module is compiled into the kernel). For modules, this is called in user context, with interrupts enabled, and the kernel lock held, so it can sleep.

This module_exit() macro defines the function to be called at module removal time (or never, in the case of the file compiled into the kernel). It will only be called if the module usage count has reached zero. This function can also sleep, but cannot fail: everything must be cleaned up by the time it returns.


Code: hello_world.c
 

#include <linux/kernel.h> /* Needed for Macros*/
#include <linux/module.h> /* Needed for all kernel modules*/
#include <linux/init.h> 
#include <linux/version.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("This is a my First Test Module...!");
MODULE_AUTHOR("GVK51");


static int __init my_start_init(void){

        printk(KERN_INFO "Hello World module loaded...!\n");
        return 0;
}

static void __exit my_remove_exit(void){

        printk(KERN_INFO "Hello World module Un-loaded...!\n");  

}

module_init(my_start_init);
module_exit(my_remove_exit);

Makefile:

obj-m   :=      hello_world.o

all:
        make -C /lib/modules/$(shell uname -r)/build/ M=$(shell pwd) modules

clear:     

        make -C /lib/modules/$(shell uname -r)/build/ M=$(shell pwd) clean
Note: Copying the code directly into your source.c file will also copies the invisible characters and finally you will left out with stray errors, i recommend you to type the code and that even becomes a practice. In this post Loadable Kernel Module i have explained all the basic concepts of modules, module loading and unloading and utility commands.
Building module Sequence Steps:
Click to Download Code

Wednesday, March 9, 2011

Non-Printing characters Removal.

There are many characters that print nothing still take space in your document. You use many of these characters every day, but probably don't think of them as characters (as such). The list of non-printing characters that Word uses includes the following:
  • Column breaks
  • Hidden text
  • Newline characters
  • Optional hyphens
  • Page breaks
  • Paragraph marks
  • Section breaks
  • Spaces
  • Tabs
Here I will show you how does these non-printing characters creep into your document, how to view them and how to remove them.

For example: you copy this peace of code below, a simple kernel module and try to compile it with the Makefile and if you really want to prove your self try even to remove those compilation errors...!

Code for test.c:

#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>/* Needed for KERN_INFO */
#include <linux/init.h> 
#include <linux/version.h>

MODULE_LICENSE(“GPL”)
MODULE_DESCRIPTION(“This is a basic test moudle)
MODULE_AUTHOR(“Vamshi Krishna Gajjela)

int init_module(void)
{
printk(KERN_INFO "My first test module loaded.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO “Test module unloaded\n");
}

Makefile:

obj-m += test.o

all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

after compilation you will end up with stray errors like this, shown in the below image, and these stray errors are because of non printing characters.




















Viewing Non-Printing characters:

To view the non-printing character use the following command as below :

$ cat --show-nonprinting test.c






















Removing Non-Printing characters:

To remove the non-printing character use the following command as below :

$ cat  'test.c' | tr -dc [\\n,[:print:]]> new_test.c

Now the source code is redirected to the new file "new_test.c" which is free from non-printing characters.

Note: Hey this may even remove the double quotes so go through for any such errors in your new_test.c .

Wednesday, March 2, 2011

What is a Kernel Module ?

Modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. 
Example: one type of module is the device driver, which allows the kernel to access hardware connected to the system. 
 Without modules, we would have to build monolithic kernels and add new functionality directly into the kernel image. Besides having larger kernels, this has the disadvantage of requiring us to rebuild and reboot the kernel every time we want new functionality.


  • kernel modules are object files that contain kernel code. 
  • They can be loaded and removed from the kernel during run time.
  • They contain unresolved symbols that are linked into the kernel when the module is loaded.
  • kernel modules can only do some of the things that built-in code can do , they do not have access to internal kernel symbols.dep
 Kernel Module Utilities:

lsmod      : lists the modules already loaded into kernel.

rmmod    : Removes or unloads a module one at a time.

insmod    : Insert or load a module.

depmod   : Creates the data base of module dependencies. This is created based         on the information present in /lib/modules/module.dep file.

modprob : Inserts a module and its dependencies based on information from modules.dep file.

modinfo  : List the information about the module like author, version tag, parameters etc. 

Writing a simple kernel module:

Here I am explaining how to write a simple kernel module that doesn't have any functionality. 
Every Kernel modules must have at least two functions:
"start" (initialization) function called init_module()
It is called when the module is loaded using insmod into the kernel.


"end" (cleanup) function called cleanup_module()
It is called just before it is removed using rmmod. 



Kmod is a subsystem that allows the loading and unloading of modules.

Issues to be considered in writing a kernel module:
  • Module code should not invoke user space Libraries or API’s or System calls.
  • Modules are free to use kernel data types and GNU-C extensions for linux kernel.
  • Following path contains the list of header files that can be included in module programs./lib/modules/2.6.32.generic/build/include/linux.
Code for test.c:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("This is a my First Test Module...!");
MODULE_AUTHOR("GVK51");

int init_module(void){

        printk(KERN_INFO "My first Test module loaded...!\n");
        return 0;
}

void cleanup_module(void){
        printk(KERN_INFO "My first Test module Un-loaded...!\n");    

}


Note: Copying the code directly into your source.c file will also copies the invisible characters and finally you will left out with stray errors, i recommend you to type the code and that even becomes a practice.


module.h : module management subsystem, its an interface file for Kmod functions.
kernel.h   : resolves kernel symbol calls, it provides access to global symbol table.
init.h        : describes the sequence of initialization.
version.h : It binds a module to a particular version of kernel.
printk     : printk is printf for kernel programs, as said earlier modules can’t use stdlib due to user space/ kernel space issues. Most of C library is implemented in kernel. with in printk “KERN_INFO” is a macro found in kernel.h that defines the priority to printk logs. There are 8 such macros as shown below.

0- highest priority 7-lowest priority

KERN_EMERG "<0>" /* system is unusable */
KERN_ALERT "<1>" /* action must be taken immediately */
KERN_CRIT "<2>" /* critical conditions */
KERN_ERR "<3>" /* error conditions */
KERN_WARNING "<4>" /* warning conditions */
KERN_NOTICE "<5>" /* normal but significant condition */
KERN_INFO "<6>" /* informational */
KERN_DEBUG "<7>" /* debug-level messages */

MACROS :
      MODULE_LICENSE() : declares the module's licensing
      MODULE_DESCRIPTION() : to describe what the module does
      MODULE_AUTHOR() : declares the module's author
  • In modules the comments are achieved with macros so that information of module sits along with the code so that debugging becomes easy. i.e., comments are not stripped out.
  • License macro is mandatory even if it is free or proprietary.
  • Modules can comprise of any number of functions and data elements which form module body.
Building a Module:
Kernel source has two types of make files:
  1. src/Makefile called as top/primary Makefile
  2. Each branch in kernel source has a Makefile called as kbuild Makefile.
So to build a module we have to write a Makefile that follows the rules followed by kbuild. To learn more on how to compile modules, see file linux/Documentation/kbuild/modules.txt.

Makefile:

obj-m   :=      test.o
all:
        make -C /lib/modules/$(shell uname -r)/build/ M=$(shell pwd) modules

clear:     

        make -C /lib/modules/$(shell uname -r)/build/ M=$(shell pwd) clean

from a technical point of view the first line is really necessary, the "all" and "clean" targets were added for convenience, and make sure that after "all:" give a tab and write the command as its a convention in writing Makefile.
Now you can compile the module test.c using make command. Here is the list of command I am executing the corresponding output is show in below image highlighted with blue arrow.
Note: You should be the root user or should have requisite permissions to load and unload modules.
$ ls    (to list the files in the current directory)
$ make      ( to build the module, this will generate many files)
$ ls      (to list the files in the current directory)
$ insmod test.ko      ( loading the module)
$ dmesg     ( to see the messages printed by printk)
$ modinfo test.ko      (this display the module informatio, we have put in macros)
$ rmmod test     ( unloading the module)
$ dmesg      ( to see the messages printed by printk)

You are finally done...!

Sunday, February 27, 2011

Difference between Microkernel and Monolithic kernel.

This post explains the two main kernel architectures of operating systems: the monolithic kernel and the micro kernel. Starting with an introduction about the term ”kernel” itself and its meaning for operating systems as a whole, it continues with a comparison of benefits and disadvantages of both architectures.

Kernel: kernel is the indispensable and therefore most important part of an operating system. Roughly, an operating system itself consists of two parts: the kernel space (privileged mode) and the user space (unprivileged mode). Without that, protection between the processes would be impossible.
There are two different concepts of kernels:
·         monolithic kernel.
·         μ-kernel (micro kernel).

Monolithic kernel: The older approach is the monolithic kernel, of which Unix, MS-DOS and the early Mac OS are typical represents of. It runs every basic system service like process and memory management, interrupt handling and I/O communication, file system, etc. in kernel space see Figure 1 (click here for Anatomy of Linux Kernel). It is constructed in a layered fashion, built up from the fundamental process management up to the interfaces to the rest of the operating system (libraries and on top of them the applications). The inclusion of all basic services in kernel space has three big drawbacks.
·         The kernel size increase.
·         Lack of extensibility.
·         The bad maintainability. 


Figure 1: Monolithic Kernel base Operating System.
Bug-fixing or the addition of new features means a recompilation of the whole kernel. This is time and resource consuming because the compilation of a new kernel can take several hours and a lot of memory. Every time someone adds a new feature or fixes a bug, it means recompilation of the whole
 kernel. (click here: “ How to Compile Kernel Source”)

To overcome these limitations of extensibility and maintain-ability, the idea of μ-kernels appeared at the end of the 1980’s. 

Microkernel: The concept (Figure 2) was to reduce the kernel to basic process communication and I/O control, and let the other system services reside in user space in form of normal processes (as so called servers). There is a server for managing memory issues, one server does process management, another one manages drivers, and so on. Because the servers do not run in kernel space anymore, so called ”con-text switches” are needed, to allow user processes to enter privileged mode (and to exit again). That way, the μ-kernel is not a block of system services anymore, but represents just several basic abstractions and primitives to control the communication between the processes and between a process and the underlying hardware. Because communication is not done in a direct way anymore, a message system is introduced, which allows independent communication and favors extensibility.


Figure 2: MicroKernel base Operating System.

Currently, there are two different generations of μ-kernels. The first generation was a more or less a stripped-down monolithic kernel. Because of performance drawbacks concerning process communication, several system services like device drivers, communication stacks, etc. found their way back into kernel space. This resulted in an even bigger kernel than before, which was slower than its monolithic counterpart. 

            Research in the field of μ-kernels prove, that it is not the best solution to create a hybrid kernel 1 , but a pure micro kernel, which has to be very small in size. So small, that it fits into the processor’s first level cache as a whole. Second generation μ-kernels like the L4 are highly optimized, not just referring to the processor family, but also to the processor itself 2 , which results in a very good I/O performance.

In a simple way we can say like this :

Monolithic Kernel (Macro Kernel): Kernel Image = (Kernel Core+Kernel Services). When system boots up entire services  are loaded and resides in memory.
Example: Windows and Unix.

Micro kernel : Kernel Image = Kernel Core. Services are build in to special modules which can be loaded and unloaded as per need.

We have another type of kernel integration technique called
Modular, this is derived from best of micro and monolithic kernel) In
Modular kernel integration:  Kernel Image = (Kernel core + IPC service modules +Memory  module +Process Management module). All other modules are loadable kernel modules.
Example: Linux kernel

Stay tuned for more information :-)



Tuesday, February 22, 2011

What are Possible Task States ?

All informations about one process is stored in struct task_struct. It includes the status, flags, priority, and many more information about one task. The task_struct of the currently running process is always available through the macro current.
 
Possible task statuses are:

TASK_RUNNING

(R) The process is able to run and contributes to the system load. The scheduler decides which processes really receive CPU time.

TASK_UNINTERRUPTIBLE 
(D) The process waits for some event. It will not be considered by the scheduler. The process cannot do anything while it is waiting (it cannot even be killed). This is usually used by device drivers while the process is waiting for some hardware to respond. Such a process contributes to the system load even though it will not receive CPU time; some other part of the system is considered to be working on behalf of the process.

TASK_INTERRUPTIBLE
(S) The process waits for some event as in TASK_UNINTERUPTIBLE but it can be woken up by a signal. This should be used when the action can be interrupted without side effects. A process in this state is considered asleep and does not contribute to the system load.
 
TASK_STOPPED
(T) The process is stopped by a signal (Ctrl-Z)
 
TASK_ZOMBIE
(Z) The process has exited but there are still some data structures around that could not yet be freed. The zombie will usually be freed when the parent calls wait4() to get the exit status.


Monday, February 21, 2011

What is Linux Driver Model ?

The Linux Device model is built around the concept of busses, devices and drivers. All devices in the system are connected to a bus of some kind. The bus does not have to be a real one; busses primarily exist to gather similar devices together and coordinate initialization, shutdown and power management.

When a device in the system is found to match a driver, they are bound together. The specifics about how to match devices and drivers are bus-specific. The PCI bus, for example, compares the PCI Device ID of each device against a table of supported PCI IDs provided by the driver. The platform bus, on the other hand, simply compares the name of each device against the name of each driver; if they are the same, the device matches the driver.

Binding a device to a driver involves calling the driver’s probe() function passing a pointer to the device as a parameter. From this point on, it’s the responsibility of the driver to get the device properly initialized and register it with any appropriate subsystems.

Devices that can be hot-plugged must be un-bound from the driver when they are
removed from the system. This involves calling the driver’s remove() function passing a pointer to the device as a parameter. This also happens if the driver is a dynamically loadable module and the module is unloaded. All device driver callbacks, including probe() and remove(), must follow the return
value.


How "container_of" macro works, & an Example

Here iam giving a small code snippet that gives and idea about working of "container_of", this posed me little difficulty in understanding, after google-ing i got some examples and after working on that i wrote a simple C application that depicts its working. here i have defined two macros "offsetof" and "container_of" which i have extracted from "kernel.h" header. 
       Please interpret this code and try some trick to understand "container_of".

container_of macro is defined in linux/kernel.h

syntax: container_of( pointer, container_type, container_field );

This macro takes a pointer to a filed name container_field, within a structure of type container_type, and returns a pointer to the containing structure .

simply this is a convenience macro that may be used to obtain a pointer to a structure from a pointer to some other structure contained with in it.


Code :

#include <stdio.h>
#include <stdlib.h>

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({            \
 const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 (type *)( (char *)__mptr - offsetof(type,member) );})

struct test1 {
 int a;
};

struct test2 {
 int b;
 struct test1 z;
 int c;
};

int main()
{
 /* existing structure */
 struct test2 *obj;
 obj = malloc(sizeof(struct test2));
 if(obj == NULL){
       printf("Error: Memory not allocated...!\n");
 }
 obj->z.a = 51;
 obj->b = 43;
 obj->c = 53;
 
 /* pointer to existing entry */    
 struct test1 *obj1 = &obj->z;

 struct test2 *obj2 = container_of(obj1, struct test2, z);

 printf("obj2->b = %d\n", obj2->b);

 return EXIT_SUCCESS;
}

Note: Copying the code directly into your source.c file will also copies the invisible characters and finally you will left out with stray errors, i recommend you to type the code and that even becomes a practice.

for more information check out this : http://www.kroah.com/log/linux/container_of.html

Sunday, February 6, 2011

Exporting System Call Table in 2.6.x Kernel

System call table was exported till 2.4 kernels, because of security reasons and preventing kernel crash from malicious applications system call table is no more exported. Here is the patch to export system call table.
                Hey...! patch is not something strange programming concept :), its just to edit few source files in kernel to export system call table. 

+ symbol implies the line of code to be added.
 - symbol implies the line of code to be removed.

Here is the patch....! (I am implementing for i386 architecture, as most of desktops are with this architecture)

1) open the file: /src/linux-2.6.32.21/arch/i386/kernel/entry.s

-.section .rodata,"a"
+.section .data,"aw"
 #include "syscall_table.S"

 syscall_table_size=(.-sys_call_table)
2) open the file: /src/linux-2.6.32.21/kernel/kallsyms.c
 
__initcall(kallsyms_init);

 EXPORT_SYMBOL(__print_symbol);
+
+extern void *sys_call_table;
+EXPORT_SYMBOL(sys_call_table);
 
After modifications save changes to above files and rebuild the kernel so that System Call Table is exported in the next boot.

Read Me: I have ever read somewhere on the Internet, implementing a new system call is not the right way to control a module. The right way is to use ioctl() instead. More importantly, it is a silly thing to expose `sys_call_table' for modules to fiddle with it. For experimentation its not big deal.....! have fun exporting sys_call_table.





 




Tuesday, February 1, 2011

How to Invoke System Call in Application


System call can be invoked in application in two different ways. Here to depict this I am writing a C application test.c for both the ways.

Using inline assembly code:
Int this method, you have to know the id of the system call which you would like to invoke. Here in Exercise1, we have added a system call with id: 337, and now I am trying to invoke it in this below example.
  • First move the id of system call to the accumulator register (eax).
  • Raise an interrupt, for context switch to kernel mode. Here int 0x80 raises a Trap interrupt.
  • Now, move the return value into the accumulator.

test.c
_______________________________________________________________________
#include<stdio.h>
int main(){
printf(“Entered main function…!\n”);

/*here starts system call*/
__asm__(“movl $337, %eax”);
__asm__(“int $0x80”);
__asm__(“movl %eax, -4(%ebp)”);

printf(“System call invoked, to see type command: dmesg at your terminal\n”);
printf(“Exiting main….!\n);

return 0;
}
_______________________________________________________________________


Using syscall:
In this we have to include sys/syscall.h header and the code is as follows. mycall is the name of the system call to be invoked, and it is the one we have added in Exercise1.
synatx for syscall :
int syscall(int number, ...);Click here for complete description.
test.c 
_______________________________________________________________________
#include<stdio.h>
#inclide<sys/syscall.h>
int main(){
printf(“Entered main function…!\n”);

/*here starts system call*/
syscall(“SYS_mycall”);

printf(“System call invoked, to see type command: dmesg at your terminal\n”);
printf(“Exiting main….!\n);

return 0;
}
_______________________________________________________________________

Compile and run it.

$ gcc test.c –o test
$ ./test
Entered main function…!
System call invoked, to see type command: dmesg at your terminal
$ dmesg | tail
New sys call invoked by ./test app


Please leave comment :-)                                                Queries are at free of cost

How To Build Linux Kernel

Here we compile kernel source to generate a new kernel image and this new image is used at the next boot of the system.
(Mainline kernel is called as vanilla kernel)
Note: I am assuming that you, as a root user in source directory, at /usr/lib/linux-2.6.32 (linux-2.6.32 name of the kernel source directory that we obtained after unzipping). It’s a convention to place the unzipped source directory at /usr/lib but it can be any where, but to build you have to be in the source directory.

Step1: Assign kernel version tag.
To do so open the Makefile in the source directory at the path /usr/lib/linux-2.6.32/Makefile and at the top of the file you will find the field EXTRAVERSION, edit as follows

$ Vim Makefile

Modify: EXTRAVERSION = .firstbuild
*save the above changes to file.

Step2: Choose kernel configuration.

To do so type that following command. This will generate a configuration file “.config”. Any file that starts with “.” is a hidden file, to list the hidden files use option 'a' with 'ls' command.
$ make menuconfig (this pumps kernel info onto console, wait until prompt returns)

Because the Linux source code is available, it follows that you can configure and custom tailor it before compiling. Indeed, it is possible to compile support into your kernel for only the specific features and drivers you want. Configuring the kernel is a required step before building it. Kernel provides multiple tools to facilitate configuration. The simplest tool is a text-based command-line utility.
$ make config

This utility goes through each option, one by one, and asks the user to interactively select yes, no, or (for tristates) module. Because this takes a long time, unless you are paid by the hour, you should use an ncurses-based graphical utility.
$ make menuconfig

To make very simple use oldconfig option.
$ make oldconfig
Ultimately they generate .config file.
Note: refer to man pages on make, type “make help” at your terminal.

Step3: Compile the source to create kernel image (raw) and modules.
$ make
This takes around 30 min on a normal desktop, to speed up, create threads if yours is a multicore machine. To build the kernel with multiple makes jobs, use
$ make -jn
Here, n is the number of jobs to spawn. Usual practice is to spawn one or two jobs per processor.

Step4: Install the modules on file system.
To do so type the following command.
$ make modules_install
This copies the modules into disk space and adds folder at /lib/modules/[name].
Here name will be 2.6.32.firstbuild

Step5:
As an example, on an x86 system using grub, you would copy arch/i386/boot/bzImage
to /boot, name it something like vmlinuz-version

$ cp arch/x86/boot/bzImage /boot/vmlinuz-2.6.32.firstbuild

Step6:

The build process also creates the file System.map in the root of the kernel source tree. It contains a symbol lookup table, mapping kernel symbols to their start addresses. copy System.map to /boot, name it something like System.map-version

$cp System.map /boot/System.map-2.6.32.firstbuild

$mkinitramfs –o /boot/initrd.img-2.6.32.firstbuild  2.6.32.firstbuild
here 2.6.32.firstbuild is the name of folder that was automatically created at /lib/modules

Step7: Update Grub

$ update-grub

If you open the file grub.cfg at the path /boot/grub/grub.cfg the ###BEGIN/etc/grub.d/10_linux ### segment should look like this
$ gedit /boot/grub/grub.cfg

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Ubuntu, with Linux 2.6.32.firstbuild' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,1)'
search --no-floppy --fs-uuid --set f57b34e4-1bf6-4135-993f-3db8881340d0
linux /boot/vmlinuz-2.6.32.firstbuild root=UUID=f57b34e4-1bf6-4135-993f-3db8881340d0 ro quiet splash
initrd /boot/initrd.img-2.6.32.firstbuild
}

menuentry 'Ubuntu, with Linux 2.6.32.firstbuild (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod ext2
set root='(hd0,1)'
search --no-floppy --fs-uuid --set f57b34e4-1bf6-4135-993f-3db8881340d0
echo 'Loading Linux 2.6.32.firstbuild ...'
linux /boot/vmlinuz-2.6.32.firstbuild root=UUID=f57b34e4-1bf6-4135-993f-3db8881340d0 ro single
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-2.6.32.firstbuild

}
Note1: In "/boot/grub/grub.cfg" you will find fields like "timeout = -1" Change it to "timeout = 10", so that even if your new image crashes you have chance to select the generic image in the next Restart.
 
Note2: If the ###BEGIN/etc/grub.d/10_linux ### segment doesn’t start with your new image then you manually cut and paste the above two blocks of code from this segment and paste it below ###BEGIN as very first line.
Restart your system.


Note3: Make sure that while executing Step4 all the modules are copied, if this process stops with few modules copied, like less than a count of 10, then its clear that build was not complete, this can be a reason that you were not as root user while building the kernel and even if the error still persists, chmod 777 kernel-source/* directory. and start all the above steps.


Note4: If you encounter kernel-panic after you restart with grub updated with new kernel configuration then above Note3 can be a solution or else the source is not downloaded completely.



The above process can be simple given as :


First you should be the root user and then go to source folder and then edit the Makefile “EXTRAVERSION” filed in source directory to “.firstbuild”, and execute these commands in sequence. Make sure that you are in root.
$ make oldconfig
$ make
$ make modules_install
$ cp arch/x86/boot/bzImage /boot/vmlinuz-2.6.32.firstbuild
$ cp System.map /boot/System.map-2.6.32.firstbuild
$ mkinitramfs –o /boot/initrd.img-2.6.32.firstbuild 2.6.32.firstbuild
$ update-grub