Table of Contents
Abstract
In this chapter we have made a lifelong friend with a
beautifully sophisticated monolithic kernel called Linux.
First, we are going to configure and compile a custom
Linux kernel.
Then, we will write a kernel module that will create and
maintain a simple „debugging file” under /proc virtual file system.
„LINUX is obsolete”
„<odd>.x.x: Linus went crazy, broke absolutely _everything_, and rewrote the kernel to be a microkernel using a special message-passing version of Visual Basic.” | ||
| --Linus Torvalds RFD: Kernel release numbering (Linux Kernel Mailing List) | ||
In the previous case study, we had some experience
with the operation of the microkernel, where architectural components
are organized in different hierarchical levels. This section drives us
towards the other end of the spectrum, to the world of
monolithic kernels. What do monolithic and micro kernels mean in practice? Think
about the previous MINIX case
study, where the data structures of the lower levels of the kernel
could not be accessed from the higher levels. For example, from the
Minix Information Server, we could not access the vector added to PCB,
we needed to copy it up to the server level. In a
monolithic kernel, the data structures and functions of the kernel can
be accessed from anywhere in the kernel code.
In the known history of mankind, there have been several examples where huge masses of people were cooperating to achieve some mutual goals or were involved in achieving some goals. Some examples may be the building of the pyramids, the religious communities and the large mass armies of the 19th century.
If we investigate only pure intellectual purposes, we will find that we are not an embarrassment of riches. A present day example may be the building of the LHC (Large Hadron Collider), that was built by 10.000 technicians, engineers and scientist from all over the world. This may be comparable to writing the Linux kernel that is being maintained by more than 8000 developers [KERNELDEV]. And if we focus not only on the kernel itself but the whole GNU/Linux system (including editors, browsers, games, etc.), then we will get a much greater number than 10000 volunteers.
We believe that compiling the kernel should be a fundamental experience for all programming students. If the reader has never done it, we will do it now, in this section.
Compiling the kernel is a relatively safe activity, but it is better to do it in a virtualized Linux system. So if the reader has never done it before, we will compile it now, using the virtualized image Batfai_Prog1.ova.
The Linux kernel is a large C program, in order to compile it we need to download its source. The actual kernel sources can be downloaded from kernel.org. Here, at the time of writing, the 3.5 is the actual version. In the beginning, a simple version numbering scheme was used: the unstable versions were numbered by odd numbers and the stable ones by even numbers. But it was too „mathematical”, now a more sophisticated model was used.
But joking apart, the rethinking of the numbering concept was suggested by Linus Torvalds in his email subjected „RFD: Kernel release numbering”.
The 2.6 kernels had already been numbered by the next
schema. A stable major.minor.revision is
followed by a sequence of
major.minor.revision.patchlevel stable versions
that contain bugfixes and security fixes. In parallel with these
versions, the
major.minor.revision+1"-rc-patchlevel" is the
development (unstable) version, where new things are introduced.
The next stable version major.minor.revision+1
will be evolved from the development versions.
On the Linux's 20th birthday, the version numbering was
bumped from 2.6 to 3.0. Now, the revision shows
the fixes, the development versions have the rc
prefix.
We have chosen the current version, that is 3.5. The whole source tree is roughly 70-80 MB (it is not sufficient to download the patch that is only some kilobytes of large.) The unpacked size will be roughly a half gigabyte, but it should be noted that the size of the compiled kernel tree may be larger than 5 GB.
Using the command wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.5.tar.bz2, here we are downloading the kernel sources.
The root of the unpacked kernel tree contains a
README file, we follow the procedure descripted
in this. First, unpack the sources with command tar xvjf
linux-3.5.tar.bz2 or cited from the README, with the
bzip2 -dc linux-3.5.tar.bz2 | tar xvf - command.
The compiling is controlled by the
.config file of the kernel tree that file also
can be found in the running system's /boot folder. We will use the command
make menuconfig in order to customize the kernel.
The make menuconfig works in the terminal screen
and its output is the file .config. If
you have already compiled the kernel, use the command make
mrproper. This program will clean up the config and the
object files from the source tree. As a best practice, the reader
can copy the existing file from the /boot directory into the root of the
source tree, then uses the command make
oldconfig, because in this case it is enough to make
decisions about the new features only.
Reading all kernel options in make
menuconfig is a whole day's work, here we can see only
one: under the menu, we are
going to set the Kernel .config support option
that will save the .config file into the
running kernel itself.
Linux kernel compiling may be coming now. Use the make command to compile the sources (here we do not follow the README, the argument O=output/dir is simply omitted, because we do not want to use a separate build directory).
The compilation has already finished, now we sudo into root and give the command make modeules_install install. With this command, we install the modules and the kernel.
By using the command uname -a, print the version of the running kernel.
We should now reboot the computer. After this, it can be seen that the grub menu has also been updated properly.
Now, the compiled custom kernel controls our computer.
In the previous section, you can see that options marked by a
star (*) will be compiled into the kernel. If we
mark an option with M, it will be compiled into
the kernel as a module.
At creating the configuration, we also have opportunity to compile a pure monolithic kernel without module support.
Without module support, the size of the kernel image is much larger than the original one. Let's also see it after creating and booting a new pure monolithic kernel:
[norbert@BatfaiProg1 ~]$ ls -l /boot/vmlinuz-`uname
-r` -rw-r--r--. 1 root root 25532624 Jul 31 15:50
/boot/vmlinuz-3.5.0