Introduction and Background info
An Operating System, abbreviated as OS, is a piece of software that controls the hardware components of a system, be it a phone, laptop or a desktop. It is in charge of the communication between the software and the hardware. Windows XP, Windows 8, Linux and Mac OS X are all examples of operating systems. The operating system consists of:
- The bootloader: software in charge of the boot process of your device.
- The kernel: the core of the system and manages the CPU, memory and peripheral devices.
- Daemons: background services.
- The shell: comprises a command process that allows manipulation of the device through commands entered into a text interface.
- Graphical Server: the sub-system that shows the graphics on your screen.
- Desktop Environment: this is what the users usually interact with.
- Applications: are programs that perform the user’s tasks such as word processors.
Kernel space and Userspace
Kernel Space: the kernel is found in an elevated system state, which includes a protected memory space and full access to the device’s hardware. This system state and memory space is altogether referred to as kernel-space. Within kernel space the core access to the hardware and system services are managed and provided as a service to the rest of the system.
User Space: the user’s applications are carried out in the user-space, where they can reach a subset of the machine’s available resources via kernel system calls. By using the core services provided the kernel, a user level application can be created like a game or office productivity software for example.
Linux has gained in popularity over the years due it being open source hence, based on a UNIX like design, and ported to more platforms compared to other competing operating systems. It is an operating system, as indicated, that resembles a UNIX OS – a stable multi-user multi-tasking operating system, and that has been assembled as a free and open-source software for development and distribution. Meaning that any individual or company has the permission to use, imitate, study and alter the Linux operating system in any way they desire.
The Linux Kernel
From its first release on September 17, 1991, the Linux kernel has defied all odds to be Linux’s defining component. It was released by Linus Torvalds and makes use of the GNU/Linux to describe the operating system. Linux kernel-based Android OS on smartphones has made Linux beat its competition to be the largest installed OS base of all general-purpose operating systems. History of Linux Kernel can be found here.
A kernel can either be monolithic, microkernel or hybrid (like the OS X and Windows 7). The Linux kernel is a monolithic computer operating system kernel that resembles the UNIX system. The Linux line of Operating Systems commonly referred to as Linux Distributions are based on this kernel. The monolithic kernel, unlike the microkernel, not only encompasses the Central Processing Unit, memory and IPC but also has device drivers, system server calls and file system management. They are best at communicating with hardware and performing several tasks simultaneously. It is for this reason that processes here react at a fast rate.
However, the few setbacks are the huge install and memory footprint needed and inadequate security as everything operates in a supervisor mode. In contrast, a microkernel may react slowly to application calls as user services and the kernel are separated. They are thus smaller in size when compared to the monolithic kernel. Microkernels are easily extensible, but more code is needed to write a microkernel. The Linux kernel is written in the C and Assembly programming languages.
The Linux kernel relationship with the Hardware
The kernel can manage the system’s hardware through what is referred to as interrupts. When the hardware wants to interface with the system, an interrupt is issued that interrupts the processor that in turn does the same to the kernel. To provide synchronization, the kernel can disable interrupts, be it a single one or all of them. In Linux, however, the interrupt handlers do not run in a process context, they instead run in an interrupt context not associated with any process.This particular interrupt context exists solely to let an interrupt handler quickly respond to an individual interrupt and then finally exit.
What makes the Linux Kernel different from other Classic Unix Kernels?
Significant differences exist between the Linux kernel and the Classic Unix kernels; as listed below:
- Linux supports dynamic loading of kernel modules.
- The Linux kernel is preemptive.
- Linux has a symmetrical multiprocessor support.
- Linux is free due to its open software nature.
- Linux ignores some standard Unix features that the kernel developers call “poorly designed.”
- Linux provides an object-oriented device model with device classes, hot-pluggable events, and a user-space device file-system
- The Linux kernel fails to differentiate between threads and normal processes.
Components of the Linux Kernel
A kernel is simply a resource manager; the resource being managed may be a process, memory or hardware device. It manages and arbitrates access to the resource between multiple competing users. The Linux kernel exists in the kernel space, below the userspace, which is where the user’s applications are executed. For the user space to communicate with the kernel space, a GNU C Library is incorporated which provides a forum for the system call interface to connect to the kernel space and allow transition back to the userspace.
The Linux kernel can be categorized into three primary levels:
- The system call interface; this is the topmost and undertakes the basic actions such as read and write.
- The kernel code; is located below the system call interface, it is common to all of the processor architectures supported by Linux, it is sometimes defined as architecture-independent kernel code.
- The architecture-dependent code; it is under the architecture-independent code, forms what is usually referred to as a Board Support Package (BSP) – this contains a small program called the bootloader that places the Operating System and device drivers into memory.
The architectural perspective of the Linux kernel consists of: System call interface, Process Management, the Virtual File system, Memory Management, Network Stack, Architecture and the Device Drivers.
- System call interface; is a thin layer that is used to undertake function calls from user space into the kernel. This interface may be architecture dependent
- Process management; is mainly there to execute the processes. These are referred to as the thread in a kernel and are representing an individual virtualization of the particular processor
- Memory management; memory is managed in what are known as pages for efficiency. Linux includes the methods in which to manage the available memory as well as the hardware mechanisms for physical and virtual mappings. Swap space is also provided
- Virtual file system; it provides a standard interface abstraction for the file systems. It provides a switching layer between the system call interface and the file systems supported by the kernel.
- Network stack; is designed as a layered architecture modeled after the particular protocols.
- Device drivers; a significant part of the source code in the Linux kernel is found in the device drivers that make a particular hardware device usable. Device driver tutorial
- Architecture-dependent code; those elements that depend on the architecture on which they run, hence must consider the architectural design for normal operation and efficiency.
System calls and Interrupts
Applications pass information to the kernel through system calls. A library contains functions that the applications work with. The libraries then, through the system call interface, instruct the kernel to perform a task that the application wants. What is a Linux System Call?
Interrupts offer a way through which the Linux kernel manages the systems’ hardware. If hardware has to communicate with a system, an interrupt on the processor does the trick, and this is passed on to the Linux kernel.
Linux kernel interfaces
The Linux kernel offers various interfaces to the user space applications that perform a variety of tasks and have different properties. Two distinct Application Programming Interface (API) exist; the kernel-user space and the kernel internal. The Linux API is the kernel-userspace API; it gives access to programs in the user space into the system resources and services of the kernel. It is made up of the System Call Interface and the subroutines from the GNU C Library.
This refers to the kernel-user space ABI (Application Binary Interface). This is explained as the interface that exists between program modules. When comparing API and ABI, the difference is that ABI’s are used to access external codes that are already compiled while API are structures for managing software. Defining an important ABI is majorly the work of Linux distributions than it is for the Linux kernel. A specific ABI should be defined for each instruction set, for example, x86-64. End-users of Linux products are interested in the ABIs rather than the API.
System Call Interface
As earlier discussed, this plays a more prominent role in the kernel. It is a denomination of the whole part of all existing system calls.
The C standard library
All the system calls of the kernel are within the GNU C Library whereas, the Linux API is comprised of the system call interface and the GNU C Library, also called glibc.
Portable Operating System Interface(POSIX)
POSIX is a collective term of standards for maintaining compatibility among the operating systems. It declares the API together with utility interfaces and command line shells. The Linux API, not only has the usable features defined by the POSIX but also has additional features in its kernel:
- Cgroups subsystem.
- The Direct Rendering Manager’s system calls.
- A readahead feature.
- Getrandom call that is present in V 3.17.
- System calls such as futex, epoll, splice, dnotify, fanotify and inotify.
More information about POSIX Standard is here.
The modular kernel
Previous versions of the Linux kernel were in such a way that all their parts were statically fixed into one, monolithic. However, modern Linux kernels have most of their functionality contained in modules that are put into the kernel dynamically. This in contrast to monolithic types, is referred to as modular kernels. Such a setup allows a user to load or replace modules in a running kernel without the need of rebooting.
The Linux Loadable Kernel Module (LKM)
The basic way of adding code in the Linux kernel is through the introduction of source files to the kernel source tree. However, you may want to add a code while the kernel is running. The code added this way is referred to as a loadable kernel module. These particular modules perform various tasks but are specified into three: device drivers, file system drivers and system calls.
The loadable kernel module can be compared to the kernel extensions in other operating systems. You can put a module into the kernel by either loading it as an LKM or binding it into the base kernel.
The benefits of LKMs over binding into the base kernel:
- Rebuilding your kernel often is not necessary, saving time and avoids errors.
- They assist in figuring out system problems such as bugs.
- LKMs save you space as you only have them loaded when you need to use them.
- Give much faster maintenance and debugging time.
Uses of LKMs
- Device drivers; the kernel exchanges information with hardware through this. A kernel must have a device’s driver before using it.
- Filesystem drivers; this translates the contents of a filesystem
- System calls; programs in the user space utilize system calls to acquire services from the kernel.
- Network drivers; interprets a network protocol
- Executable interpreters; loads and manages an executable.
Compiling the Linux Kernel
Unlike what most people say, compiling the Linux kernel is a simple task. The following is a step-by-step illustration of the process using one of the Linux distributions: Fedora 13 KDE. (It is advisable to backup your data and grub.conf just in case something goes wrong)
- From http://kernel.org website, download the source.
- While in your downloads directory, extract the kernel source from the archive by entering the following command in terminal:
tar xvjf Linux-2.6.37.tar.bz2
- Use the command make mrproper to clear the build area prior to any compilation.
- Use a configuration say xconfig, These configurations are designed to make it easier to run any program in Linux.
- Specify the modules and features you wish your kernel to contain.
- After acquiring the .config file, the next step is to go to Makefile
- Run the make command and wait for the compilation to go through.
- Install the modules using the command make modules_install
- Copy your kernel and the system map to /boot.
- Run the new-kernel-pkg to build the list of module dependencies and stuff like grub.conf
Upgrading the kernel
It is possible to upgrade a Linux kernel from an older version to a more recent one, while retaining all of the configuration options from the earlier version. To achieve this, one has to first back up the .config file in the kernel source directory; this is in case something goes wrong when trying to upgrade your kernel. The steps are:
- Get the latest source code from the main kernel.org website
- Apply the variations to the old source tree to bring it up to the latest version.
- Reconfigure the kernel based on the preceding kernel configuration file you had backed up.
- Build the new kernel.
- Now you can install the new build the kernel.
Downloading the new source; the Linux kernel developers understand that some users may not want to download the full source code for the kernel updates, as this would waste time and bandwidth. Therefore, a patch is made available which can upgrade an older kernel release. Users only need to know which patch applies to a particular version, since a kernel patch file will only update the source code from one specific release. The different patch files can be applied through the following ways;
- Stable kernel patches which apply to the base kernel version.
- Base kernel release patches only apply to the previous base kernel version
- Incremental patch upgrade from a particular release to the next release. This allows developers avoid the hustle of downgrading then upgrading their kernel. Instead, they can switch from their current stable release to the next stable release.
The Linux kernel mainly acts as a resource manager acting as an abstract layer for the applications. The applications have a connection with the kernel which in turn interacts with the hardware and services the applications. Linux is a multitasking system allowing multiple processes to execute concurrently. The Linux kernel is popular due to its open source nature that allows users to alter the kernel to what is suitable for them and their hardware. Therefore it can be used in a variety of devices, unlike other operating systems.
The modular characteristic of the Linux kernel adds more thrill to its users. This is because of the wide variety of modifications that can be made here without rebooting the system. The flexibility gives its users a big room to actualize their imaginations.
Moreover, the monolithic nature of the kernel is a great advantage as it has a high processing ability than the microkernel. The main setback with the Linux type of kernel is that if any of its services fail, then the whole system goes down with it. Latest versions have been designed in a way that if a new service is added, there is no need of modifying the whole operating system. This is an improvement when compared to previous versions.
Wikipedia Linux Kernel
Wikipedia Linux Kernel Interfaces
Linux Loadable Kernel Module How To
linux.com beginners guide