Showing posts with label Kernel. Show all posts
Showing posts with label Kernel. Show all posts

Friday, March 26, 2010

Linux kernel Versions:

 

Linux_kernel_diagram

Linux kernels are numbered using an even/odd system. An even-numbered

kernel—for example, Linux 2.2—is called a called stable kernel.

Changes are generally made to a stable kernel only to fix bugs and problems.

An odd-numbered kernel—for example, Linux 2.3—is called a development

kernel. Development kernels are works-in-progress and sometimes contain

bugs, some of which are serious. Most Linux users work with stable kernels,

reserving spare computers for testing development kernels.

At the time I’m writing this post , Linux 2.6.33.1 is the latest stable kernel.

You can download it from HERE .

Thursday, December 24, 2009

Linux Kernel Diagram

 

Linux_kernel_diagram

Monday, September 28, 2009

Load and Unload Kernel Modules

Load and Unload Kernel Modules

Linux allows the Kernel to be configured at run time, to enable or disable different services as you see fit. This way you don't have to compile a monolithic kernel, and can save some memory usage. Some modules you'll only need for a short time, others you'll need all the time. You can configure your Linux machine to load kernel modules on startup so you don't have to remember to do that when (if) you reboot.

Module Commands

There are a few commands that allow you to maniuplate the kernel. Each is quickly described below, for more information say `man [command]`.

  • depmod - handle dependency descriptions for loadable kernel modules.
  • insmod - install loadable kernel module.
  • lsmod - list loaded modules.
  • modinfo - display information about a kernel module.
  • modprobe - high level handling of loadable modules.
  • rmmod - unload loadable modules.

The usage of the commands is demonstrated below, it is left as an excerise to the reader to fully understand the commands.

Using Module Commands

Below the different kernel module commands are demonstrated

# Show the module dependencies.
depmod -n

# Install some module
insmod --autoclean [modnam]

# This lists all currently loaded modules, lsmod takes no useful parameters
lsmod

# Display information about module eepro100
modinfo --author --description --parameters eepro100

# Removing a module (don't use the example)
rmmod --all --stacks ip_tables


Module Configuration Files



The kernel modules can use two different methods of automatic loading. The first method (modules.conf) is my preferred method, but you can do as you please.




  • modules.conf - This method load the modules before the rest of the services, I think before your computer chooses which runlevel to use


  • rc.local - Using this method loads the modules after all other services are started



Using 'modules.conf' will require you to say `man 5 modules.conf`. Using 'rc.local' requires you to place the necessary commands (see above) in the right order.



Sample modules.conf



# modules.conf - configuration file for loading kernel modules
# Create a module alias parport_lowlevel to parport_pc
alias parport_lowlevel parport_pc
# Alias eth0 to my eepro100 (Intel Pro 100)
alias eth0 eepro100
# Execute /sbin/modprobe ip_conntrack_ftp after loading ip_tables
post-install ip_tables /sbin/modprobe ip_conntrack_ftp
# Execute /sbin/modprobe ip_nat_ftp after loading ip_tables
post-install ip_tables /sbin/modprobe ip_nat_ftp


Sample rc.local



#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

/sbin/insmod ip_tables
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_nat_ftp


Conclusion



You should see/know that modules are necessary. They can be loaded via 'modules.conf' or 'rc.local', but 'modules.conf' load them first and 'rc.local' loads them last. Using the various module commands you can add, remove, list or get information about modules.



source: http://edoceo.com/liber

Thursday, September 17, 2009

Overview of the linux kernel

Overview of the linux kernel

Abstract

This article discusses the basic kernel features of the linux kernel.It starts from the history of the linux kernel to basic operataing designs required for a kernel and how linux implements it in a nutshell.Then it concludes by promising future articles on different layers of the linux kernel and also an articles on Linux kernel 2.6 features,Future of Linux which will be contributed by different members of the lkg_india group.

Audience

I myself being a kernel newbie,has intended to write the article in such a fashion that it will be understood by anyone who has used the computer.It can also be read by experienced kernel developers so as to refresh their thoughts and also suggest/crticise the mistakes in the article.This article is dedicated for free for the benefit and education of all. That a person seeking knowledge should have the opportunity to find it.Thanks to every other document written with the same vein which has made this article possible.

Intoduction

To start off immediately what does kernel mean?Well thats what this blog is for,for us to understand what the kernel is.Hopefully future articles in the blog will make us understand the kernel completely and clearly.Well here is the literal meaning of the word "kernel" straight from dict.org

"The central, substantial or essential part of anything;the gist; the core;"

This is how the Online dictionary of computing defines the word kernel

"The essential part of Unix or other operating systems, responsible for resource allocation,low-level hardware interfaces, security etc"

Operating System

Any computer system includes a basic set of programs called the operating system. The most important program in the set is called the kernel.The other programs are less crucial utilities; they can provide a wide variety of interactive experiences for the user as well as doing all the jobs the user bought the computer for but the essential shape and capabilities of the system are determined by the kernel.

Is kernel the entire operating system?

No,as discussed above.The kernel is the core component of the operating system.The operating system contains the Kernel plus other systen utilities which use the kernel to provide higher level house keeping tasks.Technically speaking,Linux is only the kernel,as it does not provide system utilities like file system utilities,compilers,editors,the graphical user interface which are provided by any other operating system.So linux users typically rely on commercial ditributions like Suse,Red Hat etc., to have the entire operating system.Having known the what a Operating system and what the kernel is,let us know something about the history of the Linux kernel.

Linux,the revolutionay open source kernel

Linux was intially developed by Linus in Aug 1991.As a source of inspiration listed below is his mail on the famous comp.os.newsgroup

"----- Message from "Linus Benedict Torvalds"

on Mon, 26 Aug 1991 02:27:08 +0530 -----

Subject: What would you like to see most in minix?

Hello everybody out there using minix-

I'm doing a (free) operating system (just a hobby, won't be big

and professional like gnu) for 386(486) AT clones. This has

been brewing since april, and is starting to get ready. I'd like

any feedback on things people like/dislike in minix; as my OS

resembles it somewhat (same physical layout of the file-sytem

due to practical reasons)among other things.

I've currently ported bash (1.08) an gcc (1.40), and things seem to work.

This implies that i'll get something practical within a few months, and I'd

like to know what features most people want. Any suggestions are welcome,

but I won't promise I'll implement them :-)

Linus Torvalds torvalds@kruuna.helsinki.fi"

As seen from the mail there was an effort by the FSF(Free Software Foundation) headed by Richard Stallman to build a complete free professional Operating System. So lets talk about FSF before proceeding further.

FSF - RICHARD STALLMAN

The FSF was founded by Richard Stallman in 1984.Its also know as the GNU software project which was launched to built a complete free operating system.When richard started working for writing a free OS he felt that he should use a free editor to write programs for the Operating system,then he wrote the GNU emacs editor.Then they needed a free compiler to compile their C programs,thereby was born the GNU Compiler collection(gcc).Later when linus released Linux kernel free and it became popular,it was adopted by FSF as their kernel.So GNU utilities were used with the Linux kernel to make the complete Operating System.Now Linux remains as one of the most popular Open source operating system in the world.

Features of the Linux Kernel

I.Monolithic kernel with module support

The linux kernel is monolithic with module suport.So now let us try to decipher the meaning of the previous sentence and why linux adopted a monolithic kernel with module strategy.

Monolithic kernel

A monolithic kernel is a single large complex "do-it-yourself" kernel program which is composed of several different logical entities(kernel layers).Each kernel layer is integrated in to the large kernel program and runs in kernel mode(more on kernel mode later)on behalf of the current process.

Microkernel

A micro kernel consists of a small set of important fucntions in the kernel generally a simple scheduler,synchronisation primitives.Several System processes that run on top of the kernel to implement other OS layer functions like memory allocators,device drivers,system calls,file system etc., These kernel layers cordinate together by message passing between them.Therby because of the message passing the microkernel is slower than the monolithic kernel.

Monolithic Vs Microkernel

Monolithic Kernel is faster than microkernel as stated above.However,Microkernel has some theoritical advantages over the monolithic kernel.They are as follows,

1.The microkernel occupies less RAM,since system processes(as disscussed above) that are not doing their functionalities are swapped out or destroyed.

2.The architecture of the microkernel forces the programmers to adopt a modularized approach

as different layers of the kernel are independant of each other.Moreover,the different layers interact with each other through clear well defined software interfaces.

3.Moreover, an existing microkernel operating system can be fairly easily ported to other architectures, since all hardware dependent components are generally encapsulated in the microkernel code.

Modules,the linux way

Modules are a kernel feature that effectively achieves many of the theoretical advantages of microkernels without introducing performance penalties. A module is an object file whose code can be linked to (and unlinked from) the kernel at runtime. The object code usually consists of a set of functions that implements a filesystem, a device driver, or other features at the kernel's upper layer. The module, unlike the external layers of microkernel operating systems, does not run as a specific process. Instead, it is executed in Kernel Mode on behalf of the current process, like any other statically linked kernel function.

Advantages provided by a monolithic kernel with modules

1.Less main memory usage

A module is linked to the kernel when its functionality is needed and unlinked when its no longer used.This mechanism is done automatically by the kernel and is transparent to the user.

2.Modularized approach

Modules force the programmers to intoduce well defined software interfaces for interaction.

3.Platform independence

A module does not depend on a fixed hardware platform.A module like device driver is infact specfic to the device but not to the hardware platform(x86,sparc etc..,)

4.Faster

Since the module is linked in to the kernel,it is faster like the monolithic kernel as there is no message passing as in microkernel.Infact there is small time we lose for linking and unlinking of the modules which is less than that of the time required for message passing in microkernels.

II.Linux Filesystem

Files are a basic abstraction provided by the operating system along with processes(more about processes later).A file is an information container structured as a sequence of bytes.From the user's point of view, files are organized in a tree-structured name space starting from /(parent) which is called the root directory.

Different file types in linux

The beauty of linux lies in the fact that it almost treats everything as files including devices. There are the following types of files

1. Regular files

2. Directory files

3. Symbolic links

4. Device files(character,block).

5. Pipes

6. Sockets

The first three types are constituents of the linux filesystem.Device files are related to I/O devices and device drivers integrated into the kernel.Pipes and sockets are special files used for interprocess communication.

Inode

All information needed by the filesystem to handle a file in included in a data structure called the inode.Each file has its own inode which the filesystem uses to identify the file.The following information is kept in the inode

1.File type(as discussed above)

2.Number of hard links associated with the file(see next section)

3.File length in bytes

4.Inode number that identifies the file within the filesystem

5.User ID of the file owner(discussed below)

5.Group ID of the file(discussed below)

6.The last modify time

7.Access rights and file mode (discussed below)

Hard links and symbolic links

The same file may have several links included in the same directory or in different ones, thus several filenames.

Hardlink

A hardlink is just a different filename but points to the same inode on the disc.So the file information of the both the file and the hard link will coincide as they point to the same inode.The unix command used to create a hard link is

$ln f1 f2

f2 is the hard link for file f1

Limitations of hard link

1.Hard links cannot exist to directories as it might transform the tree structure in to a graph with cycles thus making ti impossible to locate a file according to its name.

2.Hard links can be created only for files in the same filesystem as inode is the same.This is a serious limitation as Linux supports variuos other filesystems.

Softlink

Symbolic links are short files that contain an arbitrary pathname of another file. The pathname may refer to any file located in any filesystem,it may even refer to a non exixtent file or a file in another filesystem.Thus symbolic links are short files than contain the pathname of the file that is linked to.So a symbolic link will have a separate inode for itself.The unix command to create a symbolic link is

$ln -s f1 f2

f2 is a symbolic link to f1.The linux filesystem will create a sym link f2 and will write in to it the pathname for f1.In this way f2 can refer to f1.

Users and Groups

A multiuser system is a computer that is able to concurrently and independently execute several applications belonging to two or more users. "Concurrently" means that applications can be active at the same time and contend for the various resources such as CPU, memory, hard disks, and so on. "Independently" means that each application can perform its task with no concern for what the applications of the other users are doing.

In a multiuser system, each user has a private space on the machine: typically, he owns some quota of the disk space to store files, receives private mail messages, and so on. The operating system must ensure that the private portion of a user space is visible only to its owner. In particular, it must ensure that no user can exploit a system application for the purpose of

of violating the private space of the another user.

All users are identified by a unique number called the User ID , or UID. Usually only a restricted number of persons are allowed to make use of a computer system. When one of these users starts a working session, the operating system asks for a login name and a password.If the user does not input a valid pair, the system denies access. Since the password the assumed to be private the users privacy is maintained.In order to selectively share material with other users, each user is a member of one or more groups, which are identified by a unique number called a Group ID,or GID. Each file is associated with a UID and GID.

Access rights and mode

The users of a file fall in to one of this three classes

1.The owner of the file

2.The users who belong to the same groups as that of the owner

3.All other users(others) in the system

There are three types of access rights for each of these classes namely

Read,write and execute.

Thus the set of access rights associated with a file in linux consists of nine(3(for diff classes of users) * 3(for different access rights)) different flags.There are three additional flags which define the file mode which have a meaning when applied to executable files.They are

1.SUID flag

If the executable file has the SUID flag set, the process gets the UID of the file owner.

2.SGID

If the executable file has the SUID flag set, the process gets the GID of the file group.

The suid and sgid programs are important programs to be protected in a secure system as they change the id's during execution.So an intruder might use these programs for executing something malicious on behalf of the user who is suid or sgid.

3.sticky

An executable file with the sticky flag set corresponds to a request to the kernel to keep the program in memory after its execution terminates.These flag is set when many processes share the same program for example vi might be used by many processes.So vi can have its sticky bit set.This flag has become obsolete as other approaches like copy-on-write are used now for sharing code pages between processes.

chmod is the unix command used to allow the user to set access and mode flags for a file.

Example

$chmod 4777 f1

4777 in binary is 100111111111.So there are 12 bits corresponding to User classes,access and mode permissions as below.

100---will set the suid flag for f1(mode of the file)

111---will give read,write,exec access to owner of f1

111---will give read,write,exec access to other users of the group which the user belongs to.

111---will give read,write,exec access to other remaining users in the system.

Virtual File System technology

Linux follows a object oriented Virtual File System technology inspired from SVR4 and solaris.There linux supports most of the filesystems like DOS,FAT,ext3,resierfs,JFS etc..,Also porting a file system to Linux is very easy task because of the VFS technology that linux follows.

III.Processes in Linux

Process is another fundamental abstraction(apart from File) provided by the OS.Having seen a overview of the filesystem in linux let us see how linux handles processes.

A process can be defined either as "an instance of a program in execution," or as the "execution context" of a running program. In traditional operating systems, a process executes a single sequence of instructions in an address space,the address space is the set of memory addresses that the process is allowed to reference.Operating systems like linux allow multiple execution flows,that is,multiple sequences of instructions executed in the same address space.

Multiuser systems must allow different processes to be active concurrently and thereby contend for tbe resources,mainly the CPU.Such systems are said to be multitasking systems.The scheduler is the part of the kernel which decided which process will run on the CPU at a given instant of time.It is done in such a manner that every process feels that it is the only process running on the CPU.This concept is called virtualization of the processor.Another virtualisation that is provided by linux(or any OS) to processes is the virtual memory where in a process feels that it has the entire memory on system available to it.Processes of a multiuser system must be preemptive ie., the scheduler of the kernel will decide how long each process can hold the CPU.Thereby if a higher priority process comes in to execution the scheduler will preempt the lower priority running process.

Linux is a multiprocessing system with preemptive processes.

Process management in Linux

The fork( ) and exit( ) system calls are used respectively to create a new process and to terminate it.Linux maintains a clear distinction between the process and the program by using exec( )-like system call to load a new program.After exec has been done the process resumes execution with a brand new address space containing the loaded program.

Process Creation

Processes in Linux follow a parent child relationship.The Process which invokes the fork is the parent and the process that is created is the child.The init process(created by the init.c of the kernel) is the root parent of all the other processes in linux.The task_struct is the data structure in the kernel that defines the process.Parents and children can easily find each other as the data structure contains information about the relationship.Linux implements fork using the copy-on-write approach which defers address space duplication of parent to the child on fork.The address space is copied only when a write is being made in to the address space.So till a write happens the parent and the child share only the Page tables and not the address space.The copy-on-write has the following advantage

1.Most instances of fork are followed by an exec to a program as the child does some other functionailty when compared to the program.Thereby it is a waste(an overhead) to copy the address space of the parent to the child and then again immediately overwrite the address space.So this overhead is reduced by the copy-on-write approach.

Process Termination

The exit system call is used to terminate a process.The kernel handles this system call by releasing the resources owned by the process and sending the parent process a SIGCHLD signal, which is ignored by default.

Zombie processes

The parent enquires about the termination of the child process by the wait( ) system call which allows a process to wait until one of its children terminates; it returns the process ID (PID) of the terminated child.A special zombie process state is introduced to represent terminated processes on which the parent has not issued a wait system call.The process descriptor of the child is released after the wait is executed by the parent and the child process goes to the stopped state.Now the question arises if the parent does not issue a wait call and if it terminates what happens to the child in Zombie state.There will be many zombies which will occupy useful memory.The solution lies in init process which takes over as the parent of child process whose parents have terminated.It routinely issues wait calls thereby getting rid of the zombies.

IV.The process/Kernel model

Having known about the kernel architecture and the basic abstractions(file,process) let us now see how the linux kernel is modelled.On multiuser/multitasking systems the operating system must hide all low level details concerning the physical organization of the computer from applications run by user.So when a user application wants to access a hardware,it request the kernel which evaluates the request and if it chooses to grant access,it interacts with the hardware on behalf of the process.This thereby enhances the security on multiuser systems which prevent user applications from damaging the system hardware resources.Probably,this is the reason why DOS does not require such a model as it is single user system which allows the user to do anything with the systems hardware.

Well how does linux implement the above mentioned feature.All modern operating systems,implement the above mentioned feature with the help of hardware specific features which forbids the user programs to interact directly with the hardware.For example,the x86 CPU provides four rings of execution from ring 0 to ring 3 in the order of descending privileges.Linux uses the two rings namely ring 0 and ring 3 for implementing the feature.User mode applications run in ring 3 of x86 and kernel runs in ring 0 of x86.Therefore these rings correspond to the User mode and kernel mode concept of the linux operating system.

Note:Intel introduced protected mode(ring levels) starting from 80386.So Linux was developed for 80386 and above(commonly referred as i386/i686 architectures).

When a program is executed in User Mode, it cannot directly access the kernel data structures or the kernel programs. When an application executes in Kernel Mode, however, these restrictions no longer apply. Each CPU model provides special instructions to switch from User Mode to Kernel Mode and vice versa. A program executes most of the time in User Mode and switches to Kernel Mode only when requesting a service provided by the kernel. When the kernel has satisfied the program's request, it puts the program back in User Mode.

The kernel is a process manager and not a process by itself.The creation,deletion and handling of processes are done by a group of routines in the kernel.The process/kernel model in linux allows a process to request a kernel service through system calls.System calls thereby take the process from user mode to kernel mode,does the necessary request and puts the process back in the user mode.

A switch to Kernel mode from user mode will happen by any one of these methods

1.Through system call by a process as discussed above

2.The CPU exceutes an exception.The exception has to be handled by the kernel on behalf of the process that caused the exception.For example,the kernel must handle the page fault exception.

3.A device issues an interrupt to the CPU to notify the CPU an event.In this case the kernel executes the corresponding interrupt handler for the device.

Linux also has some privileged kernel level processes.They are called kernel threads.Linux uses kernel threads in a limited way for certain functionalites.They execute in the kernel thread.keventd is an example of a kernel thread.

V.Kernel Synchronisation

On multiuser/multitasking systems many processes must be handled by the kernel at a single instant of time as several processes may be executing in the kernel at the same time.For example ,a process executing on a CPU in a uniprocessor system might be waiting on some I/0.During this time the process in kernel mode is interleaved and another process is executed in the kernel.When the I/O interrupt is finished the process waiting for I/O is executed again.So the Linux kernel must be reentrant,ie..,multiple processes must be handled by the kernel maintaining the global data structures they use in a consistent state.

Before proceeding further,we will see the definition of a kernel control path.A kernel control path is a sequence of instructions executed in the kernel mode on behalf of a process or on behalf of an interupt.

How can Kernel reentrancy be achieved?

The following are the methods to achieve kernel reentrancy

1.Reentrant functions

2.Atomic operations

3.Non Premptive kernel

4.Interrupt disabling

5.Locking mechanisms(semaphores and spinlocks)

Reentrant functions

Reentrant functions are those functions which operate only on local variable and not on global data structures.But the kernel cannot only be limited to reentrant functions.Also the kernel has a fixed stack which is small,so local variable must be less.

Before looking at other mechanisms of achieving reentarncy let us see what a race condition is and what is a critical region.

Assume that there is a global data structure(a resource) R1.If R1 is one the resource is free.Now a kernel control path KCP1 reads the value of R1 which is 1 i.e.., the resource is free.Now if KCP1 is interleaved from the kernel and if KCP2 reads the value of R1 which is still 1.It will take the resource and decrement the value to 0.Now if KCP1 resumes execution it still sees that the resource is free and decrements the value of R1 to -1,thereby taking the resource.So both the KCP's are using the resources leading to dangerous effects.This is a race condition.

Atomic operations

It is always safe to access a global variable with a single atomic uninteruptible instruction.For example in the previuos example if the two kernel paths have read the data and decremented the value of R1 in a singl operation there would have been no race condition.

But its always not possible to access data structures in a single atomic operation.Any section of code that should be finished by a process befored another process is scheduled is called the critical region.Further mechanisms we will see how to protect critical regions.

Non Premptive kernel

A simple solution to synchronisation problems is to make the kernel non preemptive ie., when a process is in kernel mode it cannot be interleaved by any other process until it voluntarily relinquishes the CPU(in which case it makes sure that the Data structures are in a consistent state).Therefore in a non preemptive kernel all the global data structures except those that are used by interupts and exceptions are safe(as interleaving of a process in kernel mode happens when a interuppt or exception occurs).Non premptability is ineffective in Multiprocessor systems as two kernel control paths executing in different CPU's can access the same data structure.The linux kernel was non preemptable until 2.5 devt series and 2.6 stable series.Now the kernel is preemptible.Preemptible kernels are more suited for time critical real time processes.

Interrupt disabling

Another method to achieve synchronisation is to disable interuppts before entering a critical region and enabling it after the critical region.This is a simple solution but is not optimal as large critical region will have the Hardware interrupts freezed for a long time leading to a freeze.Also it is ineffective in multiprocessor systems as the data structure might be accessed by another process running in a different CPU.

Locking mechanisms

The locking mechanisms lock the corresponding global data structure in question thereby making sure that when the lock is acquired only a single process can access the data structure.They are effective both in Uniprocessor and Multiprocessor systems.The locking mechanisms used by the linux kernel are

1.Semaphores

2.Spin Locks

Semaphores

A semaphore is simply a counter associated with a data structure; the semaphore is checked by all kernel threads before they try to access the data structure.Each semaphore may be viewed as an object composed of:

a)An integer variable

b)A list of waiting processes

c)Two atomic methods: down() and up()

The down() method decrements the value of the semaphore. If the new value is less than 0, the method adds the running process to the semaphore list and then blocks (i.e., invokes the scheduler). The up() method increments the value of the semaphore and, if its new value is greater than or equal to 0, reactivates one or more processes in the semaphore list. Each data structure to be protected has its own semaphore, which is initialized to 1. When a kernel control path wishes to access the data structure, it executes the down() method on the proper semaphore. If the value of the new semaphore isn't negative, access to the data structure is granted. Otherwise, the process that is executing the kernel control path is added to the semaphore list and blocked. When another process executes the up() method on that semaphore, one of the processes in the semaphore list is allowed to proceed.

SpinLocks

In multiprocessor systems, semaphores are not always the best solution to the synchronization problems. Some kernel data structures should be protected from being concurrently accessed by kernel control paths that run on different CPUs. In this case, if the time required to update the data structure is short, a semaphore could be very inefficient. To check a semaphore, the kernel must insert a process in the semaphore list and then suspend it. Since both operations are relatively expensive, in the time it takes to complete them, the other kernel control path could have already released the semaphore. In these cases, multiprocessor operating systems make use of spin locks. A spin lock is very similar to a semaphore, but it has no process list: when a process finds the lock closed by another process, it "spins" around repeatedly, executing a tight instruction loop until the lock becomes open. Of course, spin locks are useless in a uniprocessor environment. When a kernel control path tries to access a locked data structure, it starts an endless loop. Therefore, the kernel control path that is updating the protected data structure would not have a chance to continue the execution and release the spin lock. The final result is that the system hangs.

Signals and interprocess communication

The linux kernel implements signals for communicating to the process an event.For example,SIGKILL is sent to the process if it receives a terminate signal.The linux kernel implements 32 different posix signals.User processes can communicate with each other with the help of SYS V IPCs like sahred memory,pipes,fifos,semaphores and message queues.

VI.Memory Management in Linux

Memory management is the most complex(as it is architecture dependant) and important activity in the kernel.Linux supports Virtual memory management.Linux uses paging to implement virtual memory concept.Linux does not use segmentation.Memory management will be described in detail in a later article.For now the advantages a virtual memory offers are

1.Several processes can be executed concurrently.

2.It is possible to run applications whose memory needs are larger than the available physical memory.

3.Processes can execute a program whose code is only partially loaded in memory.

4.Each process is allowed to access a subset of the available physical memory.

5.Processes can share a single memory image of a library or program

6.Programs can be relocatable, that is, they can be placed anywhere in physical memory.

7.Programmers can write machine-independent code, since they do not need to be concerned about physical memory organization.

RAM USAGE

The usage of memory is one very important thing that has to be taken care by the kernel.Linux clearly distiguishes between Memory that is dedicated to the kernel and the memory that can be used by the processes.The static kernel image is loaded from the 1st Megabyte of the RAM and is pinned(it is not swapped or paged out).The remaining part of the RAM is used for

1.Kernel dynamic structures

2.Memory for processes

3.Caches for disks etc., to get better performance.

How the memory is allocated for above mentioned three is very important and hence requires a separate article.In a few words, linux takes care of memory allocation problems like internal fragmentation,external fragmentation etc., by making use of buddy system algorithm and slab allocation mechanism.So Linux uses a Slab allocator on top of a buddy system algorithm.

Virtual Adddress space of a process

Every process in linux has a virtual address space(ranging from 0 to 4GB on a 32 bit intel CPU).

A address space of a process contains all the virtual memory addresses that the process can reference.The kernel usually stores a process virtual address space as a list of memory area descriptors(for example memory area descriptors to the code segment,stack segment,heap etc.,).Linux uses demand paging ie., the page is allocated after a page fault happens.

VII.Device drivers

Having discussed most of kernel subsystems namely filesystem,process,synchronisation,interrupts,syscalls,meory management lets see in a nutshell about device drivers.The kernel interacts with I/O devices with help of device drivers.Device drivers are included in the kernel and consist of data structures and functions that control one or more devices like hard disks,keyboard,mouse etc.,Each driver interacts with the remaining part of the kernel (even with other drivers) through a specific interface.There the device driver layer can be seen as the last layer in the kernel interacting with other layers through well defined interfaces.This approach helps programmers to write device specfic code in a separate module without knowing about the kernel source code as well as the internal architecture.

VIII.Linux implementation of threads

Finally,it is mandatory to discuss how linux supports multithreaded application programming as it does in a unique manner.In linux threads are also processes which share the address space of the processes.Linux implements threads as processes because the process creation time in linux is much faster compared to other OS'es.A thread is therefore a process which can scheduled independently of the main process and it shares the same address space.

SUMMARY

In summary a linux kernel is monolithic with modular support and consists of the following subsystems,

1.Filesystem

2.Process management

3.Memory management

4.Synchronisation

5.System calls

6.Device drivers

7.Interrupts and exceptions

8.Signals

The explanation and deciphering of the different kernel layers will be explained in future articles contirbuted by the various members of the lkg_india.I also promise two more articles which will be extension of this article namely

1.Linux kernel 2.6 features

2.Linux VS other Operating systems and the future of linux

Wednesday, September 2, 2009

Small course Loadable Kernel Modules in linux Kernel 2.6

Loadable Kernel Modules in linux Kernel 2.6

Learning Objectives

  • Discuss History of Loadable Kernel Modules (LKM).
  • Describe advantages of Using LKMs
  • Describe what LKMs can do.
  • Discuss LKM Utilities
  • Installing and removing
  • Loadable Kernel Modules in Kernel 2.6

Reference

History of Loadable Module

  • Loadable Kernel Modules did not exist in Linux in the beginning.
  • Loadable Kernel Modules have been around at least since Linux1.2 (1995).
  • Device drivers were always quite modular, and only small amount of work was needed to make them Loadable Kernel Module.
  • Since about 2000 everything that make sense as an LKM had the option of being LKM.

Advantages of using LKMs

  • Don’t have to rebuild Kernel Often
  • Helps you diagnose system problem
  • Saves Memory because only required modules will be loaded in the memory.
  • Faster to maintain and debug.
  • Gives same performance as Kernel built-in code.

What LKMs can Do

  • Device drivers
  • File System Drivers
  • System Calls
  • Network Drivers
  • TTY line disciplines
  • Executable interpreters

Building Kernel Modules

  • Loadable Kernel Modules are also know as Kernel Modules.
  • After building the Kernel image issue following commands: make modules Above command compiles the source code and creates module object files
  • Then issue the following commandsmake modules_installAbove command will copy all modules over to the conventional locations

Loadable kernel Module Utilities

  • insmod Insert an LKM into the kernel.
  • rmmod Remove an LKM from the kernel.
  • depmod Determine interdependencies between LKMs.
  • lsmod List currently loaded LKMs.
  • modinfo Display contents of .modinfo section in an LKM object file.
  • modprobe Insert or remove an LKM or set of LKMs intelligently. For example, if load A before loading B, Modprobe will automatically load A when you tell it to load B.

Inserting kernel Modules

  • Basic program for inserting LKMs is insmod.
  • Try to load the modules “msdos” and “ntfs”.
  • Try following commands to load the modules msdos, the path for module may change depending on your Kernel Version:
    # cd /lib/modules/2.6.18-53el5/kernel/fs
    # insmod msdos/msdos.ko

Listing the loaded modules

  • Loaded modules may be listed by using the “lsmod” command.
  • You may also get information about modules from “/proc/modules”cat /proc/modules
  • You may also get information about “devices” and “interrupts” from “/proc/devices” and “/proc/interrupts”

Removing Modules

  • Modules may be removed by using “rmmod” command.
  • All these commands must be executed by superuser.

Using modprobe

  • Using modprobe is a better way of loading modules. Modprobe checks dependencies and also loads the modules needed to support the module being loaded.
  • Many modules such as some CDROM Drivers and Networks Drivers require certain parameters to be passed with the modules.
  • The files “/etc/modprobe.conf”, “/etc/modprobe.conf.local” and the directory “/etc/modprobe.d” contains parameters for modules that directly access the hardware. As modprobe can use information from these files it is a better method to load modules.
  • There are no standard module parameters, drivers may have their own set of parameters. To find out parameters of a driver read the documentation for that module in the directory “/usr/src/linux/documentation”.

Kmod – The Kernel Module Loader

  • Kmod automates the process of loading Kernel Module.
  • Kmod keeps on running in the background and automatically loads a kernel Module using “modprobe” whenever a desired feature is needed in the Kernel.
  • Kmod does not unload the modules if not required in feature but with Amount of RAM available this is not a big issue.

Modules in Linux kernel 2.6

  • The Linux 2.6 kernel introduces a new, unified framework for device drivers, which requires changes to custom device drivers developed to run under earlier versions of the Linux kernel.
  • The new driver model provides a framework for full and complete support for
  1. device Plug and Play
  2. power management
  3. Defines the interfaces that these subsystems can use when communicating with individual drivers.
  • The new driver framework provides a much cleaner separation of responsibilities between buses and drivers.
  • The 2.6 Linux kernel also introduces the sysfs filesystem to provide a hierarchical view of each system's device tree (and to prevent further overloading of the proc filesystem).
  • A new naming convention for loadable kernel modules, using the .ko extension (kernel object) rather than the standard .o (object) extension used in all previous stable releases of the Linux kernel.

Summary

  • Kernel loadable module reduce the size of Kernel.
  • It is easier to debug your system when using Kernel Modules.
  • New drivers can be added to system without recompiling the Kernel.
  • A set of utilities is available to manage Kernel Modules.

Tuesday, August 11, 2009

Using the Ethernet Drivers as Modules

Using the Ethernet Drivers as Modules

Most of the linux distributions now ship kernels that have very few drivers built-in. The drivers are instead supplied as a bunch of independent dynamically loadable modules. These modular drivers are typically loaded by the administrator with the modprobe(8) command, or in some cases they are automatically loaded by the kernel through `kerneld' (in 2.0) or `kmod' (in 2.1) which then calls modprobe.

Your particular distribution may offer nice graphical configuration tools for setting up ethernet modules. If possible you should try and use them first. The description that follows here gives information on what underlies any fancy configuration program, and what these programs change.

The information that controls what modules are to be used and what options are supplied to each module is usually stored in the file /etc/modules.conf. The two main options of interest (for ethernet cards) that will be used in this file are alias and options. The modprobe command consults this file for module information.

The actual modules themselves are typically stored in a directory named /lib/modules/`uname -r`/net where the uname -r command gives the kernel version (e.g. 2.0.34). You can look in there to see which module matches your card.

The first thing you need in your modules.conf file is something to tell modprobe what driver to use for the eth0 (and eth1 and...) network interface. You use the alias command for this. For example, if you have an ISA SMC EtherEZ card which uses the smc-ultra.o driver module, you need to alias this driver to eth0 by adding the line:

        alias eth0 smc-ultra

Important Note: The alias above is only used by the module utilities to translate a generic device name (e.g.eth0) into a hardware specific driver module name. When the driver loads, it never even sees this alias; instead it will simply choose the first free ethN (N=0,1,2,...) device name available. Thus, if more than one ethernet module is being loaded, the ethN assigned to the driver by the kernel may or may not be the same as the one given on the alias line, depending on the order in which the modules have been loaded. If you need to ensure that a particular card is given a particular IP address, then read the station address and assign your IP address based upon that. If you are writing your own shell scripts for this, you can just parse the ifconfig output; if using C, then you would use ioctl(ethfd, SIOCGIFHWADDR, &ifreq).

The other thing you may need is an options line indicating what options are to be used with a particular module (or module alias). Continuing with the above example, if you only used the single alias line with no options line, the kernel would warn you (see dmesg) that autoprobing for ISA cards is not a good idea. To get rid of this warning, you would add another line telling the module what I/O base the card is configured to, in this case say the hexidecimal address 0x280 for example.

        options smc-ultra io=0x280

Most ISA modules accept parameters like io=0x340 and irq=12 on the insmod command line. It is REQUIRED or at least STRONGLY ADVISED that you supply these parameters to avoid probing for the card. Unlike PCI and EISA devices, there is no real safe way to do auto-probing for most ISA devices, and so it should be avoided when using drivers as modules.

A list of all the options that each module accepts can be found in the file:

/usr/src/linux/Documentation/networking/net-modules.txt

It is recommended that you read that to find out what options you can use for your particular card. Note that some modules support comma separated value lists for modules that have the capability to handle multiple devices from a single module, such as all the 8390 based drivers, and the PLIP driver. For exmple:


        options 3c503 io=0x280,0x300,0x330,0x350 xcvr=0,1,0,1

The above would have the one module controlling four 3c503 cards, with card 2 and 4 using external transcievers. Don't put spaces around the `=' or commas.

Also note that a busy module can't be removed. That means that you will have to ifconfig eth0 down (shut down the ethernet card) before you can remove the module(s).

The command lsmod will show you what modules are loaded, whether they are in use, and rmmod will remove them.

Wednesday, July 15, 2009

Linux kernel release 2.0.xx

 Linux kernel release 2.0.xx

These are the release notes for linux version 2.0. Read them carefully,
as they tell you what this is all about, explain how to install the
kernel, and what to do if something goes wrong.

WHAT IS LINUX?

Linux is a Unix clone written from scratch by Linus Torvalds with
assistance from a loosely-knit team of hackers across the Net.
It aims towards POSIX compliance.

It has all the features you would expect in a modern fully-fledged
Unix, including true multitasking, virtual memory, shared libraries,
demand loading, shared copy-on-write executables, proper memory
management and TCP/IP networking.

It is distributed under the GNU General Public License - see the
accompanying COPYING file for more details.

ON WHAT HARDWARE DOES IT RUN?

Linux was first developed for 386/486-based PCs. These days it also
runs on DEC Alphas, SUN Sparcs, M68000 machines (like Atari and Amiga),
MIPS and PowerPC.

DOCUMENTATION:

- there is a lot of documentation available both in electronic form on
the internet and in books, both Linux-specific and pertaining to
general UNIX questions. I'd recommend looking into the documentation
subdirectories on any Linux ftp site for the LDP (Linux Documentation
Project) books. This README is not meant to be documentation on the
system: there are much better sources available.

- There are various readme's in the kernel Documentation/ subdirectory:
these typically contain kernel-specific installation notes for some
drivers for example. See ./Documentation/00-INDEX for a list of what
is contained in each file.

INSTALLING the kernel:

- If you install the full sources, do a

cd /usr/src
gzip -cd linux-2.0.XX.tar.gz | tar xfv -

to get it all put in place. Replace "XX" with the version number of the
latest kernel.

- You can also upgrade between 2.0.xx releases by patching. Each
patch that is released for 2.0.xx contains only bugfixes. No
new features will be added to the Linux kernel until the 2.1.xx
development effort begins. To install by patching, get all the
newer patch files and do

cd /usr/src
gzip -cd patchXX.gz | patch -p0

(repeat xx for all versions bigger than the version of your current
source tree, _in_order_) and you should be ok. You may want to remove
the backup files (xxx~ or xxx.orig), and make sure that there are no
failed patches (xxx# or xxx.rej). If there are, either you or me has
made a mistake.

Alternatively, the script patch-kernel can be used to automate this
process. It determines the current kernel version and applies any
patches found.

cd /usr/src
linux/scripts/patch-kernel

The default directory for the kernel source is /usr/src/linux, but
can be specified as the first argument. Patches are applied from
the current directory, but an alternative directory can be specified
as the second argument.

- make sure your /usr/include/asm, /usr/include/linux, and /usr/include/scsi
directories are just symlinks to the kernel sources:

cd /usr/include
rm -rf asm linux scsi
ln -s /usr/src/linux/include/asm-i386 asm
ln -s /usr/src/linux/include/linux linux
ln -s /usr/src/linux/include/scsi scsi

- make sure you have no stale .o files and dependencies lying around:

cd /usr/src/linux
make mrproper

You should now have the sources correctly installed.

CONFIGURING the kernel:

- do a "make config" to configure the basic kernel. "make config"
needs bash to work: it will search for bash in $BASH, /bin/bash and
/bin/sh (in that order), so hopefully one of those is correct.

- Alternate configuration commands are:
"make menuconfig" Text based color menus, radiolists & dialogs.
"make xconfig" X windows based configuration tool.

NOTES on "make config":
- having unnecessary drivers will make the kernel bigger, and can
under some circumstances lead to problems: probing for a
nonexistent controller card may confuse your other controllers
- compiling the kernel with "Processor type" set higher than 386
will result in a kernel that does NOT work on a 386. The
kernel will detect this on bootup, and give up.
- A kernel with math-emulation compiled in will still use the
coprocessor if one is present: the math emulation will just
never get used in that case. The kernel will be slightly larger,
but will work on different machines regardless of whether they
have a math coprocessor or not.
- the "kernel hacking" configuration details usually result in a
bigger or slower kernel (or both), and can even make the kernel
less stable by configuring some routines to actively try to
break bad code to find kernel problems (kmalloc()). Thus you
should probably answer 'n' to the questions for a "production"
kernel.

- Check the top Makefile for further site-dependent configuration
(default SVGA mode etc).

- Finally, do a "make dep" to set up all the dependencies correctly.

COMPILING the kernel:

- make sure you have gcc-2.6.3 or newer available. It seems older gcc
versions can have problems compiling newer versions of linux. If you
upgrade your compiler, remember to get the new binutils package too
(for as/ld/nm and company).

- do a "make zImage" to create a compressed kernel image. If you want
to make a bootdisk (without root filesystem or lilo), insert a floppy
in your A: drive, and do a "make zdisk". It is also possible to do
"make zlilo" if you have lilo installed to suit the kernel makefiles,
but you may want to check your particular lilo setup first.

- if your kernel is too large for "make zImage", use "make bzImage"
instead.

- if you configured any of the parts of the kernel as `modules', you
will have to do "make modules" followed by "make modules_install".
Read Documentation/modules.txt for more information. For example,
an explanation of how to use the modules is included there.

- keep a backup kernel handy in case something goes wrong. This is
especially true for the development releases, since each new release
contains new code which has not been debugged.

- In order to boot your new kernel, you'll need to copy the kernel
image (found in /usr/src/linux/arch/i386/boot/zImage after compilation)
to the place where your regular bootable kernel is found.

For some, this is on a floppy disk, in which case you can "cp
/usr/src/linux/arch/i386/boot/zImage /dev/fd0" to make a bootable
floppy. Note that as of Linux 2.0.0, a kernel copied to a 720k
double-density 3.5" floppy disk no longer boots. In this case,
it is highly recommended that you install LILO on your
double-density bootfloppy or switch to high-density floppies.

If you boot Linux from the hard drive, chances are you use LILO which
uses the kernel image as specified in the file /etc/lilo.conf. The
kernel image file is usually /vmlinuz, or /zImage, or /etc/zImage.
To use the new kernel, copy the new image over the old one (save a
backup of the original!). Then, you MUST RERUN LILO to update the
loading map!! If you don't, you won't be able to boot the new kernel
image.

Reinstalling LILO is usually a matter of running /sbin/lilo.
You may wish to edit /etc/lilo.conf to specify an entry for your
old kernel image (say, /vmlinux.old) in case the new one does not
work. See the LILO docs for more information.

After reinstalling LILO, you should be all set. Shutdown the system,
reboot, and enjoy!

If you ever need to change the default root device, video mode,
ramdisk size, etc. in the kernel image, use the 'rdev' program (or
alternatively the LILO boot options when appropriate). No need to
recompile the kernel to change these parameters.

- reboot with the new kernel and enjoy.

IF SOMETHING GOES WRONG:

- if you have problems that seem to be due to kernel bugs, please check
the file MAINTAINERS to see if there is a particular person associated
with the part of the kernel that you are having trouble with. If there
isn't anyone listed there, then the second best thing is to mail
them to me (Linus.Torvalds@Helsinki.FI), and possibly to any other
relevant mailing-list or to the newsgroup. The mailing-lists are
useful especially for SCSI and NETworking problems, as I can't test
either of those personally anyway.

- In all bug-reports, *please* tell what kernel you are talking about,
how to duplicate the problem, and what your setup is (use your common
sense). If the problem is new, tell me so, and if the problem is
old, please try to tell me when you first noticed it.

- if the bug results in a message like

unable to handle kernel paging request at address C0000010
Oops: 0002
EIP: 0010:XXXXXXXX
eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx
esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx
ds: xxxx es: xxxx fs: xxxx gs: xxxx
Pid: xx, process nr: xx
xx xx xx xx xx xx xx xx xx xx

or similar kernel debugging information on your screen or in your
system log, please duplicate it *exactly*. The dump may look
incomprehensible to you, but it does contain information that may
help debugging the problem. The text above the dump is also
important: it tells something about why the kernel dumped code (in
the above example it's due to a bad kernel pointer). More information
on making sense of the dump is in Documentation/oops-tracing.txt

- You can use the "ksymoops" program to make sense of the dump. Find
the C++ sources under the scripts/ directory to avoid having to do
the dump lookup by hand:

- in debugging dumps like the above, it helps enormously if you can
look up what the EIP value means. The hex value as such doesn't help
me or anybody else very much: it will depend on your particular
kernel setup. What you should do is take the hex value from the EIP
line (ignore the "0010:"), and look it up in the kernel namelist to
see which kernel function contains the offending address.

To find out the kernel function name, you'll need to find the system
binary associated with the kernel that exhibited the symptom. This is
the file 'linux/vmlinux'. To extract the namelist and match it against
the EIP from the kernel crash, do:

nm vmlinux | sort | less

This will give you a list of kernel addresses sorted in ascending
order, from which it is simple to find the function that contains the
offending address. Note that the address given by the kernel
debugging messages will not necessarily match exactly with the
function addresses (in fact, that is very unlikely), so you can't
just 'grep' the list: the list will, however, give you the starting
point of each kernel function, so by looking for the function that
has a starting address lower than the one you are searching for but
is followed by a function with a higher address you will find the one
you want. In fact, it may be a good idea to include a bit of
"context" in your problem report, giving a few lines around the
interesting one.

If you for some reason cannot do the above (you have a pre-compiled
kernel image or similar), telling me as much about your setup as
possible will help.

- alternately, you can use gdb on a running kernel. (read-only; i.e. you
cannot change values or set break points.) To do this, first compile the
kernel with -g; edit arch/i386/Makefile appropriately, then do a "make
clean". You'll also need to enable CONFIG_PROC_FS (via "make config").

After you've rebooted with the new kernel, do "gdb vmlinux /proc/kcore".
You can now use all the usual gdb commands. The command to look up the
point where your system crashed is "l *0xXXXXXXXX". (Replace the XXXes
with the EIP value.)

gdb'ing a non-running kernel currently fails because gdb (wrongly)
disregards the starting offset for which the kernel is compiled.

Source :

Saturday, May 16, 2009

New features in Linux kernels 2.6.28 and 2.6.29

New features in Linux kernels 2.6.28 and 2.6.29

Linux Kernel MapLinux kernel has in recent times seen numerous advances. And the latest versions of the Linux kernel namely 2.6.28 and 2.6.29 have some fabulous features in-built into them.

Topping over 10 million lines of code, the current day Linux kernel is no push over and is forming a serious threat to its competition.

Some of the features that are there in the more recent Linux kernels are as follows:

* New file systems - Linux kernel supports a new file system called Ext4. Ext4 supports large number of files of greater size and deeper directory structures. Another file system which is still in experimental mode but is soon going to be a choice for Linux users is the Btrfs file system which competes with ZFS in features.

* Better memory management for the Linux kernel graphics stack.

* Boot tracer - This is a feature in built into the new kernels, which will allow the developers to find possible ways in which they can further reduce the time taken for the Linux kernel to completely boot up.

* Freezer - This new feature helps you to easily migrate your operating system to a new host.

* Improved virtual memory scalability

* Disk improvements - Such as better support for solid state devices, improvements for ATA hard disks and so on. For instance, Linux kernel now provides protection against sudden jolts and shocks in ATA hard disks.

Thursday, April 30, 2009

Compiling the Linux Kernel

This post will serve as a primer to people who are new to the world of Linux hacking, and are attempting to compile the Linux kernel from source. The various steps from downloading the kernel source to booting from the new kernel image are explained. Also given are tips on cleaning up the source code, doing verbose compilation etc.


1. Downloading the kernel source code

In order to compile a new kernel we have to download the source code of the Linux kernel. We can download the source from www.kernel.org. Here we can find all versions of the Linux kernel source code. Let's take an example. Suppose we want to compile the 2.6.9 version of the linux kernel. We have to download the 2.6.9 source code from:

http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.9.tar.bz2

It's better to download the bzipped version, as that will be more compressed than its gzipped counterpart; hence will take less time to download. A wget from the command line will look like:

wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.9.tar.bz2

Once we download the required kernel version source, we need to bunzip and untar it. We can do the following:

tar xvjf linux-2.6.9.tar.bz2

The 'x' option is to denote the untarring (e'x'traction), 'v' for verbose, 'j' for specifying that we need to bunzip the file before untarring and 'f' for stating the name of the input file.

The file will untar into the directory linux-2.6.9. Once it's untarred 'cd' to linux-2.6.9.

2. Configuring the kernel

We have to configure the kernel before we start compiling it. During the configuration phase, we will select the components which we want to be part of the kernel. For example: suppose we are using the ext3 filesystem. Then we need to select the ext3 filesystem support while configuring the kernel. Typically we have to run a
make menuconfig
This will bring up the ncurses interface for configuring the kernel. There are other options such as 'make xconfig' and 'make config'. The former will bring up the configuration menu in graphical mode and the latter in text mode.

Once we select the different components we want for our kernel, we can exit the configuration interface. We should select the option to save the configuration from the configuration menu, before exiting.

After we have configured the kernel as mentioned above, we can find a file named '.config' in the top level directory of the source. This file is the configuration file. It contains various options and their states (whether they are selected or not). For example, if we choose to have the PCI support in our kernel we can find an entry of the form:

CONFIG_PCI=y
in the .config file. Similarly, options which are selected as not required will appear as not set. Suppose we have not selected the XFS filesystem support in our kernel we will find the following in the .config
# CONFIG_XFS_FS is not set

A great feature of 2.6 kernels is that if we are running make menuconfig (or xconfig or config) for the first time, then the configuration menu we are presented with is based on our current kernel configuration. In my case, I have a Fedora Core 1 system. The kernel which I run is '2.4.22-1.2115.nptl'. Hence when I run a 'make menuconfig' for the first time on the source then the configuration menu presented will contain the options as given in '/boot/config-2.4.22-1.2115.nptl'.

3. Building Dependencies

This step is required in kernels prior to 2.6 series (here I am only referring to the stable series kernels). For example if we are using a 2.4 kernel then we have to build the dependencies explicitly. We have to run the following:
make dep
This will build the dependencies. But for a 2.6 kernel we can skip this step. The dependencies are automatically created when making the final image with a 2.6 kernel.

4. Creating the final image

We can build various types of kernel binary images. We can build a plain kernel image, or a compressed version of it; the usual choice is compressed, or the 'bzImage'. We can create the bzImage by running
make bzImage
In 2.6 kernels this step will also resolve the dependencies and proceed to create a bzImage image.

After the compilation is over we can find the kernel image at the path arch/i386/boot/bzImage in case of an image for a 386 based processor (Pentium, AMD etc.).

5. Compiling and Installing the modules

In the configuring section if we have selected some components to be built as kernel modules then we need to compile those modules. To compile the modules we should run the command:
make modules
This command will compile the components (which are selected for module compilation) to modules. In a 2.4 kernel the result will be .o files of the corresponding components. But in a 2.6 kernel the output file will be a .ko module. For example if we have given the option for the Network driver of Realtek cards to be built as modules then after giving a 'make modules' we can find in 'driver/net/' a file named 8139too.o in the case of a 2.4 kernel and 8139too.ko in the case of a 2.6 kernel.

After we have compiled the modules, it's time now to install the modules. To install the modules run:

make modules_install
as root. This will install the modules and other necessary files into the /lib/modules/2.6.9 directory.

6. Booting from the new kernel

Once we are done with the installation of modules, we can go for an automatic installation procedure for the kernel binary. We just have to run
make install
This will update the kernel image on to the /boot area, update the configuration file of the bootloader (lilo.conf or grub.conf) and then do the necessary actions to make the new kernel bootable.

After this we need to reboot the machine. When the machine boots next time the boot menu will present us with the option to boot from the new kernel we built. We choose that option and voila!! boot into a kernel we built all by ourselves!

7. Manual installation of the kernel

In case 'make install' does not work, or if we cannot perform an automatic installation due to some other reason, we can go for a manual installation of the kernel. For example, if we are using the grub boot loader then we have to copy the bzImage into the boot partition and then change the '/etc/grub.conf' to reflect the presence of the new image. If we are having lilo boot loader then we have to copy the bzImage to the boot location and then modify the lilo.conf and then run the 'lilo' command to make sure that next time we boot we will have our new image as a choice to boot from. The following are the steps we should perform as root user if we are using lilo boot loader:
 cp -a arch/i386/boot/bzImage /boot/bzImage-2.6.9 
After this we add the following entry to /etc/lilo.conf
image=/boot/bzImage-2.6.9
label=2.6.9-kernel
root=your_root_disk
We should run lilo after this
lilo -v
We will reboot the machine after this. When we are prompted at the lilo prompt enter '2.6.9-kernel' as the boot option and we will be booting to the new custom built kernel.

8. Verbose compilation

We find that the compilation of the kernel is very quiet. Much less information on what is getting compiled is shown on the screen while the compilation proceeds.
#make bzImage
CHK include/linux/version.h
UPD include/linux/version.h
SPLIT include/linux/autoconf.h -> include/config/*
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/modpost.o
HOSTCC scripts/mod/sumversion.o
....
....

If we need to know what commands are used for compilation, then we need to give the verbose compilation option while compiling. That is:
make bzImage V=1
This will output the commands which are executed while compiling. Here is a snippet from the compilation output:
<..snip..>
make -f scripts/Makefile.build obj=init
gcc -Wp,-MD,init/.main.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall
-Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -pipe -msoft-float
-mpreferred-stack-boundary=2 -march=i686 -Iinclude/asm-i386/mach-default -O2
-fomit-frame-pointer -DKBUILD_BASENAME=main -DKBUILD_MODNAME=main -c -o init/main.o
init/main.c
CHK include/linux/compile.h
UPD include/linux/compile.h
gcc -Wp,-MD,init/.version.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall
-Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -pipe -msoft-float
-mpreferred-stack-boundary=2 -march=i686 -Iinclude/asm-i386/mach-default -O2
-fomit-frame-pointer -DKBUILD_BASENAME=version -DKBUILD_MODNAME=version -c -o
init/version.o init/version.c
<..snip..>

9. Cleaning the kernel source

After we have initiated compilation once on the source if we want to clean the object files and other temporary files then we have to run the following:
make clean
This will remove most generated files but will keep the configuration file.

If we need an absolute cleaning, i.e. if we want to return the source to the state in which it was before we started the compilation, then do a

make mrproper
This command will delete all generated files, the configuration file as well as various backup files. This will in effect unwind all the changes we made to the source. The source after this step will be as good as it was just after the download and untar.

10. Conclusion

We have seen how to obtain the linux kernel source, how to configure it, how to build the kernel image and modules, how to boot from the newly compiled kernel and how to do a verbose compilation. Also we have seen how to clean up the temporary files and configuration files which were created during the compilation. The next step for a budding kernel hacker would be to modify the kernel source and try experimenting with it.

Tuesday, April 28, 2009

What the kernel does when it starts up ?

  1. The kernel un-compresses

  2. The kernel claims a certain amount of memory for its working tables and buffers (kernel memory).

  3. All the driver that are built into the kernel initialize by detecting their respective hardware

  4. The kernel mounts the root file system The kernel mounts the root directory of the root file system to the kernels' idea of a system (superstructure) root directory.

  5. The kernel executes /sbin/init

The kernel now waits for asynchronous events to occur; i.e. It is now ready to serve the system by servicing requests from processes and hardware.

Everything that happens subsequently on the system has to either be requested by a binary through a system call to the kernel, or an asynchronous event triggered by hardware

Monday, March 16, 2009

List of Linux kernel names

List of Linux kernel namesLink

Thursday, March 12, 2009

What are Different versions of linux kernels available in Market?

Yet to be answered .........

Thursday, March 5, 2009

How to Find The Kernel Version

It can be useful to know the version number of the kernel (i.e., the core of the operating system) on a particular Linux system. Not only is it instructive in itself, but it can also be helpful in diagnosing and upgrading systems because each release of the kernel contains some differences, sometimes minor and sometimes substantial.

Fortunately, it is extremely easy to obtain this information, and, in fact, there is a choice of at least five ways to do it. Moreover, each of these techniques can also be used, with slight modification, to obtain additional information about a system.

Perhaps the easiest is to use the uname command (which reports basic information about a system's hardware and software) with its -r option, that is,

uname -r

This method has the advantages that only a minimal amount of typing is required and that it provides just information about the kernel with no extra output to search through.

A second way is to look at the /proc/version file. This can be easily accomplished by using the cat command (which is commonly used to read and concatenate files), i.e.,

cat /proc/version

A third way is to use the rpm (i.e., Red Hat package manager) command with its -q (i.e., query) option and use the word kernel as an argument (i.e., input data) as follows:

rpm -q kernel

This method has the advantage that it provides output information solely about the kernel. However, it has the disadvantage that it only works on distributions (i.e., versions) of Linux that use the rpm package system, such as those based on Red Hat.

A fourth method is to look at the contents of the dmesg command, which is used to report information about the system as it boots up (i.e., starts up). Because dmesg generates a large amount of output, it is convenient to first transfer that output using a pipe (represented by the vertical bar character) to the grep filter with the word Linux as an argument in order to display only lines that contain that word (and thus the kernel version information) as follows:

dmesg | grep Linux

The disadvantages of this method are that it requires some extra typing and that there is still a lot of output to search through even though it has been greatly reduced through the use of the grep filter.

A fifth method is to look in directories in which the kernel or its source code (i.e., the original version as written by humans in a programming language) is kept. There can be differences among systems, and some systems might not contain the source code. However, the kernel frequently resides in the boot directory, and thus its name, which includes the version and release numbers, can be found by using the ls command (which lists the contents of a directory) with that directory as an argument as follows:

ls /boot

This command will likely produce several references to the version of the currently installed and running kernel. Among them should be an entry such as vmlinuz-2.4.20-6 (in the case of kernel version 2, major release 4, minor release 20). vmlinuz is a compressed Linux kernel, and it is bootable, which means that it is capable of loading the operating system into memory so that the computer becomes usable and application programs can be run.
 
Things You Should Know About Linux !!!