Working with the Kernel
The heart of your computer is the kernel. This kernel works with specific parameters and modules, and as a Linux user you need to have at least a minimal knowledge about them. In this chapter, you’ll learn how to perform basic kernel management tasks and how to change parameters for your kernel. You’ll also learn how to configure GRUB to load your kernel.
Understanding the Kernel
As mentioned, the Linux kernel is the heart of the operating system. It is the software that communicates directly to the hardware. The kernel is the only part of the operating system that communicates to the hardware directly; all other components that you use have to go through the kernel as shown in Figure 13-1.
Figure 13-1. Only through the kernel can all software communicate to the computer hardware
To access the different hardware components, the kernel needs drivers. Every kernel driver is represented by a kernel module. Only the most essential drivers are directly compiled in the kernel itself. While booting, the kernel loads in initial RAM disk. This RAM disk contains drivers for hardware that may be present in your computer. These drivers are not included in the kernel itself, because these are non-essential drivers.
In general, drivers are loaded automatically when the computer boots through the kernel directly or by using the initial RAM disk or when new hardware is attached to the computer. The latter is done with the aid of the udev process, which is used by all modern distributions.
Note In the old days, kernels were monolithic, meaning that all drivers were compiled directly into the kernel. This also meant that if a user needed a new driver, he or she had to enable the driver in the source code and recompile the entire kernel. Fortunately, this is no longer necessary; if a new driver is required, the user just has to load a new module. Therefore, situations where kernels need to be recompiled are pretty rare nowadays.
Managing Kernel Modules
To work with your computer’s hardware, you need drivers to access the hardware. The role of the driver is to tell the kernel exactly how it should address the hardware. In general, you don’t need to do anything for proper hardware access, but some cases will require your involvement, and Linux offers some commands to help you with that. These commands are discussed in the following sections.
Before doing any module management on your computer, you should know which modules are loaded. For this purpose, you can use the lsmod command. Listing 13-1 shows you the command and sample output.
The output of lsmod shows you not only which modules are loaded, but also what the modules are doing. In the first column of its output, you see the name of the module (for instance, on the last line, you see information about ide_core). Next is the amount of memory the module uses (117648 in the case of usb_core), followed by the number and names of the other modules that currently use this module. In particular, the latter part of this information is important to know about, because if a module has dependencies, you cannot just unload it before unloading the dependencies. Before doing anything, you should use lsmod to see what the modules are currently doing, after which you can use modprobe or modinfo on these modules.
Loading and Unloading Modules with modprobe
Basically, modules get loaded automatically. In some cases, however, you may need to unload and reload a module by hand. This may be required after changing options for a module (see the section “Changing Module Options” later in this chapter for more information). As modules normally get loaded automatically, you’ll probably have to unload a module first before you can load it again. To unload a module that is currently loaded, use modprobe -r. For example, the following command would unload the fat32 module from your computer:
modprobe -r fat32
modprobe will not normally return any messages; it just does its job and quits. If you actually want to see what it is doing, you can add the -v option for verbosity. This can be especially useful when loading a module; for instance, it shows you what dependencies are automatically loaded with your module. Listing 13-2 gives an example of this. Notice that modules that are currently required by another kernel module as a dependency cannot be unloaded.
Loading of a module may fail because of versioning errors. Typically, modules are written for a specific version of the kernel, and if the version in the module is wrong, it will fail to load. A bad solution to this problem is to disable version checking by using the -f (force) option. Notice that this should never happen for kernel modules that where installed with the kernel. Versioning problems can occur though if an administrator has manually installed Linux kernel modules that are not a part of the official Linux kernel, the proprietary kernel modules.
You may succeed in loading the module using the option -f, but it won’t be stable. However, if this is your only option, you may need to use it. Before using modprobe -f, you should first check whether you can find the source code for your module, which you might want to compile again to make sure it works with your kernel. See the section “Compiling Modules” later in this chapter for more information.
Displaying Module Properties with modinfo
In some situations, you may just want to know more about a module that is currently loaded. To do this, you can use modinfo. This is a pretty straightforward command that gives you all available properties for a module, which may be useful for troubleshooting. For instance, modinfo also gives you the license that is used for the module in question. This allows you to recognize a proprietary module, which may possibly cause problems in your current kernel. In Listing 13-3, you can see the result of running the modinfo command on the vfat module.
Changing Module Options
When working with kernel modules, you can pass options to them. You would do this by editing the /etc/modprobe.conf configuration file or by adding module-specific files to /etc/modprobe.d. You can include lines for specific modules in modprobe.conf and specify all you need to do on one line per module, or alternatively you can create a configuration file for a specific module in /etc/modprobe.d. Note that the letter currently is the preferred method for loading kernel modules. Listing 13-4 shows partial sample contents of modprobe.conf.
As you can see, a few commands are used in modprobe.conf or the files in /etc/modprobe.d:
As you can see, when using the lsmod command , some modules depend on other modules to load successfully. Scanning for these module dependencies is the responsibility of the depmod command, which automatically loads when your computer boots. The result of this command is written to the modules.dep file, which you can find in the modules directory for your current kernel (/lib/modules/...). Notice that normally you should not need to manually use the depmod command as this command is automatically executed when the kernel is installed, or when kernel updates are installed.
Since this file just contains a long list of modules and their depen- dencies, it makes no sense to edit it yourself. In case a module has dependency problems, it can be useful to run the depmod command again from the command line. This command will generate a new modules.dep file automatically for you.
Legacy Commands for Module Management
Some older commands for module management don’t take module dependencies in consid- eration. You should not use these commands, which I’ve listed here, because they most likely won’t load and unload your modules correctly:
EXERCISE 13-1: WORKING WITH KERNEL MODULES
Finding the right Hardware Module
For hardware on your computer, the right modules should be loaded automatically. You can verify if this is the case using the lspci -k command. Listing 13-5 shows partial output of this command, notice the last line of every PCI address that mentions the name of the PCI module that is loaded.
In some cases you won’t see any Kernel driver in use line. If this is the case, no kernel module could be found for this specific hardware. To fix this issue, you should try to find a proprietary driver with the vendor of the specific hardware.
Tuning Kernel Parameters
In the old days, tuning kernel parameters was hard. You needed to change parameters in the C language source files and recompile the kernel to make changes. Today this is no longer a requirement. Instead, you can write new parameters to the /proc file system. This file system contains several kernel settings, and by writing directly to some of the files in /proc, you will immediately change the setting.
You should never try to change settings in /proc without knowing what you are doing, because you may severely trash your system. However, /proc expertise requires deep insight into the working of Linux and the Linux kernel; hence, I won’t give you a complete list of every parameter that you can change in /proc. I will give you some useful examples, however, as well as the method to make changes permanent.
Writing Changes to /proc
To write a change to a file in /proc, you need to echo the new value to the configuration file. All kernel-related configuration files are in /proc/sys. Let’s consider an example: the con- figuration file /proc/sys/net/ipv4/ip_forward indicates whether your computer can route packets between two network cards. Typically, this is not required for an end-user compu- ter, but you may choose to set this up if you want to use your computer as a wireless access point, for instance. You can show the default setting in this file by using cat /proc/sys/net/ ipv4/ip_forward, which will give you the value of 0, meaning that routing currently is disa- bled. To enable it, echo the value of 1 to this configuration file. Listing 13-6 shows how this procedure works.
The disadvantage of the procedure just described is that changes are not persistent when you reboot your computer. This means that after a reboot, you would have to apply all of these settings again. Fortunately, a workaround exists in the form of the sysctl package. If installed, sysctl runs as a service when your computer boots. When loaded, it reads its configuration file, /etc/sysctl.conf. This file contains a list of all parameters that have to be applied to the /proc file system. Listing 13-7 shows an example of what the contents of sysctl may look like. This example, which comes from an Ubuntu server, contains some valuable information on param- eters that you may want to change.
In /etc/sysctl.conf, configuration files in /proc/sys are referred to by using relative path names. As you can see in the last line, for instance, the setting net/ipv4/ip_always_defrag is used, which refers to the file with the complete name of /proc/sys/net/ipv4/ip_always_ defrag. Instead of using the notation with slashes that you see in this example listing, your distribution may use the dotted notation, which would in this case be net.ipv4.ip_always_ defrag. It doesn’t matter which you choose, as both are compatible.
When changing kernel settings, you should know where to find which kind of settings. In /proc/sys, different subdirectories are used to group different kinds of configuration files. The following subdirectories are used:
Some Useful /proc Parameters
As mentioned before, tuning the kernel by modifying the /proc file system is not easy to do and requires deep insight in the working of the kernel. Therefore, I will not go into that here. To give you an impression of the possibilities, I’ve included a short list of some of the options in /proc:
EXERCISE 13-3: MAKING KERNEL CHANGES THROUGH /PROC
Compiling Your Own Kernel and Kernel Modules
Among the advantages of using Linux is that you can create new functionality based on the source files of kernel as well as other programs. In this section, you’ll read how compiling is used to get things going, first as it applies to the kernel, and second as it applies to new kernel modules.
To be able to build and compile your own software, you must have a C compiler installed on your computer. Typically, the GNU C compiler, which is in the gcc package, is used for this purpose. Make sure that it is installed, as well as all the packages that depend on it, before pro- ceeding. Read Chapter 8 for more information about the installation of new software packages on your distribution.
Note: On enterprise Linux distributions such as SUSE and Red Hat, it is not common to compile your own kernel. The kernel source files often aren’t even included. This is because for those distributions the supportability is very important. By recompiling your own kernel, you’ll break support as you are going to include options that haven’t been verified by the vendor. So if you’re using an enterprise Linux distribution, don’t compile changes into your kernel.
Understanding Make
To compile software, you need a C compiler, which is in the gcc package. To compile C files successfully, generically speaking you’ll use one of two approaches; the one you use depends on which way the source program files have been delivered. If your source file is one file only, you could compile it directly, using the gcc command. When dealing with Linux kernels and drivers, this never is the case; you don’t work with one single source file, but with lots of source files that are all linked to each other and, depending on your current configuration, have to behave differently. As it would be virtually impossible to compile all of these one by one, most source files come with a file that helps with the compilation process, named Makefile. You will find it after extracting the source files from the software package.
The Makefile contains specific instructions that tell the C compiler exactly what it has to do when compiling the software. To start compiling the software against this Makefile is not too hard: you just run the make command. However, since there can be different Makefiles on your computer, you should always run the make command from the directory that contains the Makefile you need to start compiling your software.
If the software in question is very complex, the Makefile may contain instructions to run the compiling job for different scenarios. This is the case when working with the kernel, where you can run make with different arguments to tell the compiler exactly what it has to do. These arguments are not specific to make but are defined in the Makefile itself. If you’re not afraid of complicated scripts, you can even read the Makefile to try to find out exactly what it accomplishes. (See http://www.gnu.org/software/make/manual/make.html for more information on make.)
Modifying and Compiling the Kernel
Before the Linux kernel was modular and before it was easy to write new kernel options to the /etc/sysctl.conf file to change settings dynamically, you needed to change kernel settings and recompile a new kernel after making your setting changes. Nowadays, there is hardly a reason to proceed in this way. Nevertheless, this section gives some insight into what is needed to configure and compile your own kernel, which will result in a new kernel. Before you start, make sure that the kernel source files are installed on your computer. Read Chapter 8 for more details on how to install software.
It only makes sense to compile a kernel if you have changed settings to the kernel. The next section shows you how to do so, and the section after that discusses how to compile the kernel after making these changes.
Modifying the Kernel
The current kernel configuration is normally stored in the .conf file in the directory /usr/ src/linux, which contains the source files of your current kernel. To create this file, different options are available, of which two will be covered here:
Creating a .config file from Scratch
To create a .config file from scratch, you need to run the make config command or one of the related commands. This command starts a script that asks for every single piece of kernel functionality how you want to configure it, which is very user unfriendly. Some alternatives exist that are easier to use: make menuconfig and make xconfig. Both offer a menu interface that enables you to specify what you need in your new kernel configuration. As they offer the same functionality, I will cover the make menuconfig command only; you can run it from the console, which is not the case for make xconfig.
You must run the make config commands from the /usr/src/linux directory, so before you start, make sure that you are in this directory. Next, type make menuconfig to start the menu-based kernel configuration. Figure 13-2 shows what the interface looks like.
Figure 13-2. make menuconfig offers a menu interface that allows you to change kernel options
In the make menuconfig interface, all options are subdivided in different modules that allow you to find specific functionality easily. You can select an option by navigating to it with the arrow keys and pressing Enter to select it. Some options can just be switched on or off, whereas other options can be enabled as a module as well. For the latter option type, you can toggle between selected, unselected, or an M, which indicates that you want to use the option as a module (see Figure 13-3). You can also get more details about what functionality is related to a given option: select it first and then use the Tab key to navigate to the Help option. Select- ing Help will show you a description of the selected function.
Figure 13-3. From make menuconfig, it is easy to switch options on or off
Once you are finished creating the configuration you need with make menuconfig, you can browse back to the top of the menu interface by selecting Exit until you are back in the main menu. This offers you the screen shown previously in Figure 13-2. From there, select Exit once more. You will now be prompted to save the current selection. Select Yes to write the current selection to a configuration file. Read the section “Compiling a New Kernel” later in this chap- ter for information on how to proceed from this point.
Creating a .config Based on the Default Configuration
Every kernel also contains a default configuration, which according to the kernel maintainer contains the best options for the architecture that you are using. You can easily write this default configuration to the /usr/src/linux/.config file by using the make defconfig com- mand. Make sure that you use this command from the /usr/src directory, as it otherwise won’t work.
After starting the make defconfig command, lots of options will scroll over your screen (see Listing 13-8), and the result is written to the new .config file.
Compiling a New Kernel
Now that you have created the /usr/src/linux/.config file, it’s time to compile the new ker- nel, or better, build the new kernel. Whereas previously several commands were needed to do this, nowadays you can perform this task by running one simple command from the /usr/src/ linux directory:
make
Completing the build of a new kernel can take awhile. make will show you the names of all the individual source files that it is currently is working on and display any warning or status errors related to these files. Listing 13-9 gives you an impression of what you see at this point.
Although you won’t often have to recompile the kernel very often, the same is far from true for kernel modules. The issue is that many hardware vendors refuse to publish the source code for their drivers under open source licenses. Instead, they will make some proprietary Linux drivers available only. These proprietary Linux drivers are generic, but to be fully functional, drivers have to be developed for your specific kernel. The only way to meet this requirement is to compile these drivers for your machine.
Speaking in a generic way, there are two methods to install such drivers on your com- puter: the easy way and the hard way. When choosing the easy way, you’ll have to integrate the web site where the vendor made his or her drivers available as a package repository on your computer. When choosing the hard way, you’ll have to download and compile the drivers yourself. The exact procedure to do this is different for each driver. What is described in the following procedure is a generic way that will work in most cases:
This generic procedure should help you in compiling and installing the driver for your kernel. It is a very generic procedure, however: in all cases, you should check the documenta- tion that comes with the driver to see whether it contains any specific instructions.
When your computer starts up, a Linux kernel has to be loaded. On most Linux distributions, this is accomplished by the Grub 2 boot loader. This boot loader shows a configuration while it starts, and from this startup menu it allows you to specify specific options that should be used when booting (see Figure 13-4). It also has a configuration file that can be used to make startup parameters persistent.
Figure 13-4. The Grub2 bootloader menu
The Grub 2 boot menu shows the different kernel versions that are available. After software updates have been installed, you normally will see a few kernel version, which allows you to select an older version, or a troubleshooting kernel in case you have problems starting the default kernel. From the Grub 2 boot loader menu, you can press the e key on a highlighted item. This opens the screen that you can see in Figure 13-5, where kernel boot options can be specified. To do this, find the line that starts with the text Linux and add the boot parameters to the end of the line.
Figure 13-5. Specifying kernel boot options
In the example from figure 13-4 you can see that many arguments are provided on the line that starts with linux16. You’ll also notice that different Linux distributions are using different options. In this case for instance the options rhgb and quiet are used to indicate that the system should not show any startup messages. If you rather do want to see startup messages, you can remove these options from this line.
Also, you can add specific kernel options to this line. If your machine fails to start for instance, you can add the argument systemd.unit=rescue.target to enter rescue mode. This brings you in a minimal mode where you can repair settings on your system. Notice that all changes you’re making from here are once only. To start with the modified kernel arguments, use the Ctrl-X key stroke.
If you want to make changes to the GRUB 2 boot loader permanent, you should include them in the file /etc/default/grub. In this file you’ll find a line GRUB_CMDLINE that contains all kernel arguments that are used when booting. You can add to or remove from this line as required. After making modifications, you need to write the changes to the Grub 2 configuration. You can do so using grub2-mkconfig -o /boot/grub2/grub.cfg. Notice that you should never write to the /boot/grub2/grub.cfg file directly, as all modifications to it will be overwritten if the kernel or the Grub 2 software are updated.
EXERCISE 13-3: MODIFYING GRUB2 ARGUMENTS
In this exercise you’ll learn how to enter rescue mode.
Summary
In this chapter, you have learned how to work with the kernel. You’ve read how to manage ker- nel modules, as well as how to change kernel parameters. The following commands have been covered in this chapter:
In the next and final chapter of this book, you will read how to create shell scripts.
18.117.91.187