Showing posts with label kernel. Show all posts
Showing posts with label kernel. Show all posts

Tuesday, 5 July 2011

Modifying the Linux Kernel to Improve Performance

*/

Introduction

Like a government that rules a nation and all its provinces, the Linux kernel is the central program that not only governs how programs interact with one another, but also provides the guidelines on how they should use the computer's core infrastructure, such as memory, disks, and other input/output (I/O) devices for the user's benefit.
Linux drivers, the programs that manage each I/O device, are the staff that keeps all the government departments running. Continuing with the analogy, the more departments you make the kernel manage, the slower Linux becomes. Large kernels also reduce the amount of memory left over for user applications. These may then be forced to juggle their memory needs between RAM and the much slower swap partitions of disk drives, causing the whole system to become sluggish.
The Fedora installation CDs have a variety of kernel RPMs, and the installation process autodetects the one best suited to your needs. For this reason, the Fedora Linux kernel installed on your system is probably sufficient. The installation process chooses one of several prebuilt kernel types depending on the type of CPU and configuration you intend to use (Table 33-1).

 Kernels Found On Fedora Installation CDs

Processor TypeConfiguration
i586Single processor
i586Multiprocessor (SMP)
i686Single processor
i686Multiprocessor (SMP)

The Pros And Cons Of Kernel Upgrades

Despite this best fit installation, you may want to rebuild the kernel at times. For example, there is no installation RPM for multiprocessor systems with large amounts of memory. You may also want to experiment in making a high-speed Linux router without support for SCSI, USB, Bluetooth, and sound but with support for a few NIC drivers, an IDE hard drive, and a basic VGA console. This would require a kernel rebuild.
Rebuilding the kernel in a small business environment is usually unnecessary. If your system starts to slow down and you can't afford to replace hardware or are unable to add more RAM, however, you may want to tune the kernel by making it support only necessary functions or updating built-in parameters to make it perform better. Sometimes new features within the new kernel are highly desirable; for example, the version 2.6 kernel has much more efficient data handling capabilities than the older version 2.4, providing new life for old hardware.
Kernel tuning on a production server shouldn't be taken lightly, because the wrong parameters could cause your system to fail to boot, software to malfunction, or hardware peripherals to become unavailable. Always practice on a test system and keep a backup copy of your old kernel. Whenever possible, hire a consultant with kernel experience to help, and use this chapter and other references as a guide to prepare you for what to expect.
This chapter provides only an overview of the steps to take. It won't make you an expert, but it will expose you to the general process and provide greater confidence when you need to research the task with a specialized guide.

The Kernel Sources Package

You will need to install the kernel source code on your system prior to modifying your kernel. As of Fedora Core 3, the kernel sources come as a source RPM package that matches the version of the kernel you are running. In Fedora Core 2 and earlier, the Kernel sources came as a generic RPM package called kernel-source, the installation of which is covered in Appendix III, "Fedora Version Differences".
The newer method is more complicated as it requires a number of post installation steps. Though the process is well documented in the release notes section of the Fedora website (http://fedora.redhat.com/docs/release-notes/) there are some clarifications that are needed. These are explained in the following section.

Installing Kernel Sources

The installation process for the kernel sources is long, but not very complicated. Here is how it's done:
1. Determine the version of your kernel with the uname command. In this case it is version 2.6.14-1.1644.
[root@bigboy tmp]# uname -r
2.6.14-1.1644_FC4smp
[root@bigboy tmp]#
2. Visit your favorite Fedora operating system download mirror and get the corresponding source RPM package. If you are running the original version of the kernel that came with your installation discs, then the sources will be located in the /core/<version>/i386/os/SRPMS/ directory. If the kernel has been updated using yum or some other method, the sources will be located in the /core/updates/<version>/SRPMS/ directory. In this example the sources of an updated Core 4 kernel is downloaded from the /core/updates/4/SRPMS/ directory of http://download.fedora.redhat.com using wget.
[root@bigboy tmp]# wget
http://download.fedora.redhat.com/pub/fedora/linux/core/updates/4/SRPMS/kernel-2.6.14-1.1644_FC4.src.rpm
--15:32:22-- 
http://download.fedora.redhat.com/pub/fedora/linux/core/updates/4/SRPMS/kernel-2.6.14-1.1644_FC4.src.rpm
           => `kernel-2.6.14-1.1644_FC4.src.rpm'
Resolving download.fedora.redhat.com... 66.187.224.20,
209.132.176.20, 209.132.176.220, ...
Connecting to
download.fedora.redhat.com|66.187.224.20|:80...
connected.
HTTP request sent, awaiting response... 200 OK
Length: 40,454,218 (39M) [application/x-rpm]

100%[=========================>] 40,454,218   862.89K/s    ETA 00:00

15:33:10 (842.22 KB/s) -
`kernel-2.6.14-1.1644_FC4.src.rpm' saved
[40454218/40454218]

[root@bigboy tmp]#
3. Install the contents of the RPM file into the /usr/src/redhat/SOURCES and /usr/src/redhat/SPECS directories using the rpm command.
[root@bigboy tmp]# rpm -Uvh kernel-2.6.14-1.1644_FC4.src.rpm 
   1:kernel                 ########################################### [100%]
[root@bigboy tmp]#
4. The kernel source directory tree will have to be created next. Enter the /usr/src/redhat/SPECS directory and create the tree using the rpmbuild command with the -bp option.
[root@bigboy tmp]# cd /usr/src/redhat/SPECS
[root@bigboy SPECS]# ls
kernel-2.6.spec
[root@bigboy SPECS]# rpmbuild -bp --target $(arch) kernel-2.6.spec
Building target platforms: i686
Building for target i686
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.44004
+ umask 022
+ cd /usr/src/redhat/BUILD
...
...
...
removed `./init/Kconfig.orig'
removed `./init/main.c.orig'
+ find . -name '*~' -exec rm -fv '{}' ';'
+ exit 0
[root@bigboy SPECS]#
5. The tree has now been created in the /usr/src/redhat/BUILD/kernel-<version> directory. You can link, move or copy this directory to become /usr/src/linux depending on your needs and the likelihood of you compiling multiple kernel versions in future. In this case, the tree is moved and then linked.
[root@bigboy SPECS]# cd /usr/src/redhat/BUILD/kernel-2.6.14/
[root@bigboy kernel-2.6.14]# ls
linux-2.6.14  vanilla
[root@bigboy kernel-2.6.14]# mv linux-2.6.14 /usr/src/
[root@bigboy kernel-2.6.14]# cd /usr/src
[root@bigboy src]# ln -s ./linux-2.6.14 linux
[root@bigboy src]# ls
kernels  linux  linux-2.6.14  redhat
[root@bigboy src]#
6. The configuration files for specific kernels shipped in Fedora Core will be located in the configs/ directory. In this case the uname -a command is used to determine the systems CPU type (686) and the kernel type (SMP, Symmetrical Multi Processor), and the relevant configuration file is then copied to become the new /usr/src/linux/.config file to be used during the kernel compilation.
[root@bigboy src]# cd /usr/src/linux
[root@bigboy linux]# uname -a
Linux bigboy.my-web-site.org 2.6.14-1.1644_FC4smp #1 SMP
Sun Nov 27 03:39:31 EST 2005 i686 i686 i386 GNU/Linux
[root@bigboy linux]# cp configs/kernel-2.6.14-i686-smp.config .config
cp: overwrite `.config'? y
[root@bigboy linux]#
7. You can also automatically copy the correct file from the /usr/src/linux/configs/ directory to /usr/src/linux/.config using the make oldconfig command.
[root@bigboy linux]# cd /usr/src/linux
[root@bigboy linux]# make oldconfig
You should now be ready to compile a customized kernel at your leisure, but first I'll discuss Kernel modules.

Kernel Modules

Over the years the Linux kernel has evolved, in the past device drivers were included as part of this core program, whereas now they are loaded on demand as modules.

Reasons For Kernel Modules

There are a number of advantages to this new architecture:
  • Updates to a driver, such as a USB controller module, don't require a complete recompilation of the kernel; just the module itself needs recompiling. This reduces the likelihood of errors and ensures that the good, working base kernel remains unchanged.
  • An error in a device driver is less likely to cause a fault that prevents your system from booting. A faulty device driver can be prevented from loading at boot time by commenting out its entry in the /etc/modprobe.conf file, or by using the rmmod command after boot time. In the past, the kernel would have to be recompiled.
  • Updates to a driver don't require a reboot either, just the unloading of the old and reloading of the new module.
  • You can add new devices to your system without requiring a new kernel, only the new module driver is needed. This adds a great deal of flexibility without a lot of systems administrator overhead.
There are some drivers that will always need to be compiled into the kernel to make sure your system boots correctly. For example, routines for basic system functions used in reading and writing files, are an indispensable integrated part of any kernel.
Loadable kernel modules now include device drivers to manage various types of filesystems, network cards, and terminal devices to name a few. As they work so closely with the kernel, the modules need to be compiled specifically for the kernel they are intended to support. The kernel always looks for modules for its version number in the /lib/modules/<kernel version> directory and permanently loads them into RAM memory for faster access. Some critical modules are loaded automatically, others need to be specified in the /etc/modprobe.conf file.
The kernel recompilation process provides you with the option of compiling only the loadable modules. I won't specifically cover this, but simultaneous recompilation of all modules will be covered as part of the overall recompilation of your kernel.

How Kernel Modules Load When Booting

One question that must come to mind is "How does the kernel boot if the disk controller modules reside on a filesystem that isn't mounted yet?"
As stated in Chapter 7, "The Linux Boot Process", the GRUB boot loader resides on its own dedicated partition and uses the /boot/grub/grub.conf file to determine the valid kernels and their locations. The grub.conf file not only defines the available kernels, but also the location of the root partition and an associated ramdisk image that is automatically loaded into memory and that contains just enough modules to get the root filesystem mounted.
Note: In Fedora Linux, the /boot/grub/grub.conf file can also be referenced via the symbolic link file named /etc/grub.conf.

Modules And The grub.conf File

In this example of the /boot/grub/grub.conf file, the kernel in the /boot directory is named vmlinuz-2.6.8-1.521, its RAM disk image file is named initrd-2.6.8-1.521.img, and the root partition is (hd0,0).
#
# File: /boot/grub/grub.conf
#
default=0
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Fedora Core (2.6.8-1.521)
        root (hd0,0)
        kernel /vmlinuz-2.6.8-1.521 ro root=LABEL=/
        initrd /initrd-2.6.8-1.521.img
 
The .img file is created as part of the kernel compilation process, but can also be created on demand with the mkinitrd command.
The (hd0,0).disk definition may seem strange, but there is a file that maps the GRUB device nomenclature to that expected by Linux in the /boot/grub/device.map file.
#
# File: /boot/grub/device.map
#
(fd0)     /dev/fd0
(hd0)     /dev/hda
During the next phase of the boot process, the loaded kernel executes the init program located on the RAM disk, which mounts the root filesystem and loads the remaining modules defined in the /etc/modprobe.conf file before continuing with the rest of the startup process.

Loading Kernel Modules On Demand

It is possible to load add-on modules located under the /lib/modules/<kernel version> directory with the modprobe command. For example, the iptables firewall application installs kernel modules that it uses to execute NAT and pass FTP traffic. In this example: these modules are loaded with the modprobe command with the aid of the /etc/rc.local script.
#
# File: /etc/rc.local
#
# Load iptables FTP module when required
modprobe ip_conntrack_ftp

# Load iptables NAT module when required
modprobe iptable_nat
Kernel module drivers that are referenced by the operating system by their device aliases are placed in the /etc/modprobe.conf file and are loaded automatically at boot time. In the example, you can see that devices eth1 and eth0 use the natsemi and orinoco_pci drivers respectively.
#
# /etc/modprobe.conf
#
alias eth1 natsemi
alias eth0 orinoco_pci
Linux has a number of commands to help you with modules. The lsmod command lists all the ones loaded. In the example, you can see that iptables, NFS, and the Orinoco drivers are all kernel modules. You can use the modprobe command to load and unload modules or use the insmod and rmmod commands. See the man pages for details.
[root@bigboy tmp]# lsmod
Module                  Size  Used by
...
...
iptable_filter          2048  0
ip_tables              13440  1 iptable_filter
...
...
exportfs                4224  1 nfsd
nfs                   142912  0
lockd                  47944  3 nfsd,nfs
autofs4                10624  1
sunrpc                101064  20 nfsd,nfs,lockd
...
...
natsemi                18016  0
orinoco_pci             4876  0
orinoco                31500  1 orinoco_pci
hermes                  6528  2 orinoco_pci,orinoco
...
...
[root@bigboy tmp]#


Finally, when in doubt about a device driver, try using the lspci command to take a look at the devices that use your PCI expansion bus. Here you can see that the natsemi module listed in the lsmod command has a high probability of belonging to the 01:08.0 Ethernet controller: device made by National Semiconductor.
[root@bigboy tmp]# lspci
...
...
01:07.0 Network controller: Intersil Corporation Prism 2.5 Wavelan chipset (rev 01)
01:08.0 Ethernet controller: National Semiconductor Corporation DP83815 (MacPhyter) Ethernet Controller
01:0c.0 Ethernet controller: 3Com Corporation 3c905C-TX/TX-M [Tornado] (rev 78)
[root@bigboy tmp]#

Creating A Custom Kernel

The installation of the kernel sources creates a file called README in the /usr/src/linux directory that briefly outlines the steps needed to create a new kernel. Take a look at a more detailed explanation of the required steps.

Make Sure Your Source Files Are In Order

Cleaning up the various source files is the first step. This isn't so important for a first time rebuild, but it is vital for subsequent attempts. You use the make mrproper command to do this; it must be executed in the Linux kernel version's subdirectory located under /usr/src. In this case, the subdirectory's name is /usr/src/linux-2.6.5-1.358.
[root@bigboy tmp]# cd /usr/src/linux
[root@bigboy linux]# make mrproper
...
...
...
[root@bigboy linux]#

The ".config" File

You next need to run scripts to create a kernel configuration file called /usr/src/linux/.config. This file lists all the kernel options you wish to use.

Backup Your Configuration

The .config file won't exist if you've never created a custom kernel on your system before, but fortunately, RedHat stores a number of default .config files in the /usr/src/linux/configs directory. You can automatically copy the .config file that matches your installed kernel by running the make oldconfig command in the /usr/src/linux directory.
[root@bigboy tmp]# cd /usr/src/linux
[root@bigboy linux]# ls .config
ls: .config: No such file or directory
[root@bigboy linux]# make oldconfig
...
...
...
[root@bigboy linux]#
If you've created a custom kernel before, the .config file that the previous custom kernel build used will already exist. Copy it to a safe location before proceeding.

Customizing The ".config" File

Table 33-2 lists three commands that you can run in the /usr/src/linux directory to update the .config file.

Table 33-2 Scripts For Modifying The .config File

CommandDescription
make configText based utility that prompts you line by line. This method can become laborious.
make menuconfigText menu based utility.
make gconfigX-Windows GUI based utility.

 Kernel Option Choices

Kernel Option ChoiceDescription
MThe kernel will load the drivers for this option on an as needed basis. Only the code required to load the driver on demand will be included in the kernel.
YInclude all the code for the drivers needed for this option into the kernel itself. This will generally make the kernel larger and slower but will make it more self sufficient. The "Y" option is frequently used in cases in which a stripped down kernel is one of the only programs Linux will run, such as purpose built home firewall appliances you can buy in a store.
There is a limit to the overall size of a kernel. It will fail to compile if you select parameters that will make it too big.
NDon't make the kernel support this option at all.

 Kernel Configuration Options

OptionDescription
Code maturity level optionsDetermines whether Linux prompts you for certain types of development code or drivers.
Loadable module supportSupport for loadable modules versus a monolithic kernel. Most of the remaining kernel options use loadable modules by default. It is best to leave this alone in most cases.
Processor type and featuresSMP, Large memory, BIOS and CPU type settings.
General setupSupport for power management, networking, and systems buses such as PCI, PCMCIA, EISA, ISA
Memory technology devicesLinux subsystem for memory devices, especially Flash devices
Parallel port supportSelf explanatory
Plug and Play configurationSupport of the automatic new hardware detection method called plug and play
Block devicesSupport for a number of parallel-port-based and ATAPI type devices. Support for your loopback interface and RAM disks can be found here too.
Multidevice support (RAID, LVM)Support for RAID, 0, 1, and 5, as well as LVM.
Cryptography support (CryptoAPI)Support for various types of encryption
Networking optionsTCP/IP, DECnet, Appletalk, IPX, ATM/LANE
Telephony supportSupport for voice to data I/O cards
ATA/IDE/MFM/RLL supportSupport for a variety of disk controller chipsets
SCSI supportSupport for a variety of disk controller chipsets. Also sets limits on the maximum number of supported SCSI disks and CDROMs.
Fusion MPT supportHigh speed SCSI chipset support.
I2O device supportSupport for specialized Intelligent I/O cards
Network device supportSupport for Ethernet, Fibre Channel, FDDI, SLIP, PPP, ARCnet, Token Ring, ATM, PCMCIA networking, and specialized WAN cards.
Amateur Radio supportSupport for packet radio
IrDA subsystem supportInfrared wireless network support
ISDN subsystemSupport for ISDN
Old CD-ROM drivers (not SCSI, not IDE)Support for non-SCSI, non-IDE, non ATAPI CDROMs
Input core supportKeyboard, mouse, and joystick support in addition to the default VGA resolution.
Character devicesSupport for virtual terminals and various serial cards for modems, joysticks and basic parallel port printing.
Multimedia devicesStreaming video and radio I/O card support
Crypto Hardware supportWeb-based SSL hardware accelerator card support
Console driversSupport for various console video cards
FilesystemsSupport for all the various filesystems and strangely, the native languages supported by Linux.
SoundSupport for a variety of sound cards
USB supportSupport for a variety of USB devices
Additional device driver supportMiscellaneous driver support
Bluetooth supportSupport for a variety of Bluetooth devices
Kernel hackingSupport for detailed error messages for persons writing device drivers

Configure Dependencies

As I mentioned before, the .config file you just created lists the options you'll need in your kernel. In version 2.4 of the kernel and older, the make dep command was needed at this step to prepare the needed source files for compiling. This step has been eliminated as of version 2.6 of the kernel.

Edit The Makefile To Give The Kernel A Unique Name

Edit the file Makefile and change the line "EXTRAVERSION =" to create a unique suffix at the end of the default name of the kernel.
For example, if your current kernel version is 2.6.5-1.358, and your EXTRAVERSION is set to -6-new, your new additional kernel will have the name vmlinuz-2.6.5-6-new.
Remember to change this for each new version of the kernel you create.

Compile A New Kernel

You can now use the make command to create a compressed version of your new kernel and its companion .img RAM disk file. This could take several hours on a 386 or 486 system. It will take about 20 minutes on a 400MHz Celeron.
[root@bigboy linux-2.6.5-1.358]# make 
...
...
...
[root@bigboy linux-2.6.5-1.358]#
Note: In older versions of Fedora the command to do this would have been make bzImage.

Build The Kernel's Modules

You can now use the make modules_install command to copy all the modules created in the previous step to the conventional module locations.
[root@bigboy linux]# make modules_install
...
...
...
[root@bigboy linux]#
Note: In versions of Fedora before Core 3, this was a two step process. The make modules command would compile the modules, but locate them within the Linux kernel source directory tree under the directory /usr/src/. The make modules_install command would then relocates them to where they should finally reside under the /lib/modules/<kernel version> directory.

Copy The New Kernel To The /boot Partition

The kernel and the .img you just created needs to be copied to the /boot partition where all your systems active kernel files normally reside. This is done with the make install command.
This partition has a default size of 100MB, which is enough to hold a number of kernels. You may have to delete some older kernels to create enough space.
[root@bigboy linux]# make install
...
...
...
[root@bigboy linux]#

Here you can see that the new kernel vmlinuz-2.6.5-1.358-new is installed in the /boot directory.
[root@bigboy linux]# ls -l /boot/vmlinuz*
lrwxrwxrwx 1 root root       22 Nov 28 01:20 /boot/vmlinuz -> vmlinuz-2.6.5-1.358-new
-rw-r--r-- 1 root root  1122363 Feb 27  2003 /boot/vmlinuz-2.6.5-1.358
-rw-r--r-- 1 root root  1122291 Nov 28 01:20 /boot/vmlinuz-2.6.5-1.358-new
[root@bigboy linux]#

Updating GRUB

You should now update your /etc/grub.conf file to include an option to boot the new kernel. The make install command does this for you automatically.
In this example, default is set to 1, which means the system boots the second kernel entry, which happens to be that of the original kernel 2.6.5-1.358. You can set this value to 0, which makes it boot your newly compiled kernel (the first entry).
default=1
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Red Hat Linux (2.6.5-1.358-new)
        root (hd0,0)
        kernel /vmlinuz-2.6.5-1.358-new ro root=LABEL=/
        initrd /initrd-2.6.5-1.358-new.img
title Red Hat Linux (2.6.5-1.358)
        root (hd0,0)
        kernel /vmlinuz-2.6.5-1.358 ro root=LABEL=/
        initrd /initrd-2.6.5-1.358.img

Kernel Crash Recovery

Sometimes the new default kernel will fail to boot or work correctly with the new kernel. A simple way of recovering from this is to reboot your system, selecting the old version of the kernel from the Fedora splash screen. Once the system has booted with this stable version, edit the grub.conf file and set the default parameter to point to the older version instead. If this fails, you may want to boot from a CD with the original kernel. You can then try to either reinstall a good kernel RPM or rebuild the failed one over again after fixing the configuration problem that caused the trouble in the first place.
*//

Anatomy of the Linux kernel

History and architectural decomposition
Given that the goal of this article is to introduce you to the Linux kernel and explore its architecture and major components, let's start with a short tour of Linux kernel history, then look at the Linux kernel architecture from 30,000 feet, and, finally, examine its major subsystems. The Linux kernel is over six million lines of code, so this introduction is not exhaustive. Use the pointers to more content to dig in further.
A short tour of Linux history
While Linux is arguably the most popular open source operating system, its history is actually quite short considering the timeline of operating systems. In the early days of computing, programmers developed on the bare hardware in the hardware's language. The lack of an operating system meant that only one application (and one user) could use the large and expensive device at a time. Early operating systems were developed in the 1950s to provide a simpler development experience. Examples include the General Motors Operating System (GMOS) developed for the IBM 701 and the FORTRAN Monitor System (FMS) developed by North American Aviation for the IBM 709.
In the 1960s, Massachusetts Institute of Technology (MIT) and a host of companies developed an experimental operating system called Multics (or Multiplexed Information and Computing Service) for the GE-645. One of the developers of this operating system, AT&T, dropped out of Multics and developed their own operating system in 1970 called Unics. Along with this operating system was the C language, for which C was developed and then rewritten to make operating system development portable.
Twenty years later, Andrew Tanenbaum created a microkernel version of UNIX®, called MINIX (for minimal UNIX), that ran on small personal computers. This open source operating system inspired Linus Torvalds' initial development of Linux in the early 1990s (see Figure 1).

Figure 1. Short history of major Linux kernel releases
 
Linux quickly evolved from a single-person project to a world-wide development project involving thousands of developers. One of the most important decisions for Linux was its adoption of the GNU General Public License (GPL). Under the GPL, the Linux kernel was protected from commercial exploitation, and it also benefited from the user-space development of the GNU project (of Richard Stallman, whose source dwarfs that of the Linux kernel). This allowed useful applications such as the GNU Compiler Collection (GCC) and various shell support.
Introduction to the Linux kernel
Now on to a high-altitude look at the GNU/Linux operating system architecture. You can think about an operating system from two levels, as shown in Figure 2.

Figure 2. The fundamental architecture of the GNU/Linux operating system
 
At the top is the user, or application, space. This is where the user applications are executed. Below the user space is the kernel space. Here, the Linux kernel exists.
There is also the GNU C Library (glibc). This provides the system call interface that connects to the kernel and provides the mechanism to transition between the user-space application and the kernel. This is important because the kernel and user application occupy different protected address spaces. And while each user-space process occupies its own virtual address space, the kernel occupies a single address space. For more information, see the links in the Resources section.
The Linux kernel can be further divided into three gross levels. At the top is the system call interface, which implements the basic functions such as read and write. Below the system call interface is the kernel code, which can be more accurately defined as the architecture-independent kernel code. This code is common to all of the processor architectures supported by Linux. Below this is the architecture-dependent code, which forms what is more commonly called a BSP (Board Support Package). This code serves as the processor and platform-specific code for the given architecture.
Properties of the Linux kernel
When discussing architecture of a large and complex system, you can view the system from many perspectives. One goal of an architectural decomposition is to provide a way to better understand the source, and that's what we'll do here.
The Linux kernel implements a number of important architectural attributes. At a high level, and at lower levels, the kernel is layered into a number of distinct subsystems. Linux can also be considered monolithic because it lumps all of the basic services into the kernel. This differs from a microkernel architecture where the kernel provides basic services such as communication, I/O, and memory and process management, and more specific services are plugged in to the microkernel layer. Each has its own advantages, but I'll steer clear of that debate.
Over time, the Linux kernel has become efficient in terms of both memory and CPU usage, as well as extremely stable. But the most interesting aspect of Linux, given its size and complexity, is its portability. Linux can be compiled to run on a huge number of processors and platforms with different architectural constraints and needs. One example is the ability for Linux to run on a process with a memory management unit (MMU), as well as those that provide no MMU. The uClinux port of the Linux kernel provides for non-MMU support. See the Resources section for more details.
Major subsystems of the Linux kernel
Now let's look at some of the major components of the Linux kernel using the breakdown shown in Figure 3 as a guide.

Figure 3. One architectural perspective of the Linux kernel
 
System call interface
The SCI is a thin layer that provides the means to perform function calls from user space into the kernel. As discussed previously, this interface can be architecture dependent, even within the same processor family. The SCI is actually an interesting function-call multiplexing and demultiplexing service. You can find the SCI implementation in ./linux/kernel, as well as architecture-dependent portions in ./linux/arch. More details for this component are available in the Resources section.
Process management
Process management is focused on the execution of processes. In the kernel, these are called threads and represent an individual virtualization of the processor (thread code, data, stack, and CPU registers). In user space, the term process is typically used, though the Linux implementation does not separate the two concepts (processes and threads). The kernel provides an application program interface (API) through the SCI to create a new process (fork, exec, or Portable Operating System Interface [POSIX] functions), stop a process (kill, exit), and communicate and synchronize between them (signal, or POSIX mechanisms).
Also in process management is the need to share the CPU between the active threads. The kernel implements a novel scheduling algorithm that operates in constant time, regardless of the number of threads vying for the CPU. This is called the O(1) scheduler, denoting that the same amount of time is taken to schedule one thread as it is to schedule many. The O(1) scheduler also supports multiple processors (called Symmetric MultiProcessing, or SMP). You can find the process management sources in ./linux/kernel and architecture-dependent sources in ./linux/arch). You can learn more about this algorithm in the Resources section.
Memory management
Another important resource that's managed by the kernel is memory. For efficiency, given the way that the hardware manages virtual memory, memory is managed in what are called pages (4KB in size for most architectures). Linux includes the means to manage the available memory, as well as the hardware mechanisms for physical and virtual mappings.
But memory management is much more than managing 4KB buffers. Linux provides abstractions over 4KB buffers, such as the slab allocator. This memory management scheme uses 4KB buffers as its base, but then allocates structures from within, keeping track of which pages are full, partially used, and empty. This allows the scheme to dynamically grow and shrink based on the needs of the greater system.
Supporting multiple users of memory, there are times when the available memory can be exhausted. For this reason, pages can be moved out of memory and onto the disk. This process is called swapping because the pages are swapped from memory onto the hard disk. You can find the memory management sources in ./linux/mm.
Virtual file system
The virtual file system (VFS) is an interesting aspect of the Linux kernel because it provides a common interface abstraction for file systems. The VFS provides a switching layer between the SCI and the file systems supported by the kernel (see Figure 4).

Figure 4. The VFS provides a switching fabric between users and file systems
 
At the top of the VFS is a common API abstraction of functions such as open, close, read, and write. At the bottom of the VFS are the file system abstractions that define how the upper-layer functions are implemented. These are plug-ins for the given file system (of which over 50 exist). You can find the file system sources in ./linux/fs.
Below the file system layer is the buffer cache, which provides a common set of functions to the file system layer (independent of any particular file system). This caching layer optimizes access to the physical devices by keeping data around for a short time (or speculatively read ahead so that the data is available when needed). Below the buffer cache are the device drivers, which implement the interface for the particular physical device.
Network stack
The network stack, by design, follows a layered architecture modeled after the protocols themselves. Recall that the Internet Protocol (IP) is the core network layer protocol that sits below the transport protocol (most commonly the Transmission Control Protocol, or TCP). Above TCP is the sockets layer, which is invoked through the SCI.
The sockets layer is the standard API to the networking subsystem and provides a user interface to a variety of networking protocols. From raw frame access to IP protocol data units (PDUs) and up to TCP and the User Datagram Protocol (UDP), the sockets layer provides a standardized way to manage connections and move data between endpoints. You can find the networking sources in the kernel at ./linux/net.
Device drivers
The vast majority of the source code in the Linux kernel exists in device drivers that make a particular hardware device usable. The Linux source tree provides a drivers subdirectory that is further divided by the various devices that are supported, such as Bluetooth, I2C, serial, and so on. You can find the device driver sources in ./linux/drivers.
Architecture-dependent code
While much of Linux is independent of the architecture on which it runs, there are elements that must consider the architecture for normal operation and for efficiency. The ./linux/arch subdirectory defines the architecture-dependent portion of the kernel source contained in a number of subdirectories that are specific to the architecture (collectively forming the BSP). For a typical desktop, the i386 directory is used. Each architecture subdirectory contains a number of other subdirectories that focus on a particular aspect of the kernel, such as boot, kernel, memory management, and others. You can find the architecture-dependent code in ./linux/arch.
Interesting features of the Linux kernel
If the portability and efficiency of the Linux kernel weren't enough, it provides some other features that could not be classified in the previous decomposition.
Linux, being a production operating system and open source, is a great test bed for new protocols and advancements of those protocols. Linux supports a large number of networking protocols, including the typical TCP/IP, and also extension for high-speed networking (greater than 1 Gigabit Ethernet [GbE] and 10 GbE). Linux also supports protocols such as the Stream Control Transmission Protocol (SCTP), which provides many advanced features above TCP (as a replacement transport level protocol).
Linux is also a dynamic kernel, supporting the addition and removal of software components on the fly. These are called dynamically loadable kernel modules, and they can be inserted at boot when they're needed (when a particular device is found requiring the module) or at any time by the user.
A recent advancement of Linux is its use as an operating system for other operating systems (called a hypervisor). Recently, a modification to the kernel was made called the Kernel-based Virtual Machine (KVM). This modification enabled a new interface to user space that allows other operating systems to run above the KVM-enabled kernel. In addition to running another instance of Linux, Microsoft® Windows® can also be virtualized. The only constraint is that the underlying processor must support the new virtualization instructions. See the Resources section for more information.

Monday, 4 July 2011

15 Interesting Facts About the Linux Kernel

Exactly 16 years ago, on March 1994, Linux kernel version 1.0.0 was humbly released for the world to tinker with. To celebrate the historic moment, I have collected some really interesting facts about the Linux kernel. So if you are a Linux fan, grab a beer and read on.

1. A 21 year-old Finnish college student created the Linux kernel as a hobby. (Do you know him?)
2. An asteroid was named after the creator of the Linux kernel.
3. Thousands of developers/programmers scattered all around the world are continuously contributing to the development of the Linux kernel.
4. The Linux kernel's official mascot is a penguin named Tux.
5. According to a study funded by the European Union, the estimated cost to redevelop the most recent kernel versions would be at $1.14 billion USD.
6. As of today, only 2% of the Linux kernel has been written by Linus Torvalds.
7. The Linux kernel is written in the version of the C programming language.
8. Linux is now one of the most widely ported operating system kernels, running on a diverse range of systems from handheld computers to mainframe servers.
9. Linux kernel 1.0.0 was released with 176,250 lines of code. The latest Linux kernel has over 10 million lines of code.
10. Microsoft Windows and the Linux kernel can run simultaneously in parallel on the same machine using a software called Cooperative Linux (coLinux).
11. At first, Torvalds wanted to call the kernel he developed Freax (a combination of "free", "freak", and the letter X to indicate that it is a Unix-like system), but his friend Ari Lemmke, who administered the FTP server where the kernel was first hosted for downloading, named Torvalds' directory linux.
12. A guy name William Della Croce, Jr. trademarked the name Linux and eventually demanded royalties for its use. He later agreed to assign the trademark to Torvalds.
13. The Linux kernel can be found on more than 87% of systems on the world's Top 500 supercomputers.
14. A "vanilla kernel" is not an ice cream flavor but an unmodified version of the Linux kernel.
15. The Linux Kernel is not in any way related to the army rank called ‘Colonel’. (hehe)
Cheers!