Kernel: Settings and modules
Jonni Bidwell continues his journey to sysadmin nirvana, pausing under a tree to meditate on the mysteries of the kernel and kernel modules
The operating system kernel lies at the heart of all Linux systems, from the smallest embedded or mobile device, to the largest supercomputer. Remarkably, across the broad spectrum, the kernel has the same essential tasks. It controls access to hardware; competition for resources between different applications and other tasks; handles I/O activity, and files and data storage; security; networking and so on. By selecting kernel command line parameters at boot time, the system can be made to behave in many different ways.
In this tutorial we continue our showcase of the Linux Foundation’s EssentialsofLinuxSystemAdministration courseLFS201. In this outing we cover Chapter 6: what the kernel does and how it does it, kernel command line parameters and the sysctl utility for setting them. We also touch on Chapter 7, giving an overview of kernel modules.
Narrowly defined, Linux is only the kernel of the operating system, which includes many other components, such as libraries and applications that interact with the kernel. The kernel is the essential central component that connects the hardware to the software and manages system resources, such as memory and CPU time allocation among competing applications and services. It handles all connected devices using device drivers, and makes the devices available for operating system use. A system running only a kernel has rather limited functionality, and will be found only in dedicated and focused embedded devices.
The main responsibilities of the kernel include: System initialisation and boot up Process scheduling Memory management Controlling access to hardware I/O between applications and storage devices Security control, both locally (such as filesystem permissions) and over the network Implementation of local and network filesystems Networking control Various parameters are passed to the system at boot on the kernel command line. Normally, these are on the linux line in the GRUB configuration file, but can be modified at boot. A sample GRUB kernel command line, specified in /boot/grub2/grub.cfg, might look like: linux16 /boot/vmlinuz-3.19.1.0 \
root=UUID=01234567-8888-9abc-def0fedcba987654 ro \ vconsole.keymap=us crashkernel=auto \ vconsole.font=latarcyrheb-sun16 rhgb quiet LANG=en_US.UTF-8
or perhaps something simpler such as: linux16 /boot/vmlinuz-4.7.3 root=LABEL=RHEL7 ro
Everything after the vmlinuz file specified is an option. Any options not understood by the kernel will be passed to init, the first user process (pid1) to be run on the system. Note that grub.cfg shouldn’t be edited directly, since it’ll be overwritten when the kernel is upgraded. Instead, a new one should be generated by editing the files in /etc/grub and running grub-mkconfig. To see what command line a system was booted with type: $ cat /proc/cmdline
If the shorter command line above was used, then this command would output: BOOT_IMAGE=/boot/vmlinuz-4.7.3 root=LABEL=RHEL7
Boot parameters
There is a rather surprisingly long list of kernel parameters which can be viewied at https://www.kernel.org/doc/ Documentation/admin-guide/kernel-parameters.rst, in the kernel sources themselves at Documentation/kernelparameters.txt or by typing man bootparam . Parameters can be specified simply as a value given as an argument, or in the form param=value , where the given value can be a string, integer or array of integers, as explained in the docs.
We used the following parameters in the lengthy command line earlier: root : root filesystem ro : mounts root device read-only on boot vconsole.keymap : which keyboard to use on the console crashkernel : how much memory to reserve for kernel crashdumps vconsole.font : which font to use on the console rhgb : for graphical boot (deprecated, replaced by Plymouth) quiet : disables most log messages LANG : the system language
By convention, there should be no intentionally hidden or secret parameters. They should all be explained in the docs, and patches to the kernel source with new parameters should always include patches to the documentation file.
The sysctl interface can be used to read and tune kernel parameters at run time. Current values can be displayed with: $ sysctl -a There are quite a number of them, so we’ve truncated this output to show just a selection: abi.vsyscall32 = 1 kernel.ctrl-alt-del =0 kernel.pid_max = 32768 kernel.threads-max = 62409 net.ipv4.ip_default_ttl = 64 net.ipv4.ip_forward = 0 vm.nr_hugepages = 16 vm.swappiness = 10
Each value above corresponds to a pseudofile residing under /proc/sys, with directory slashes being replaced by dots. For example, these two commands are equivalent: $ sudo sh -c ‘echo 1 > /proc/sys/net/ipv4/ip_forward’ $ sudo sysctl net.ipv4.ip_forward=1
The second command won’t work if there are spaces around the equals sign. The first command is more complicated than a simple sudo echo 1 >… because the redirection (>) part isn’t governed by sudo , so this would result in a permission-denied error. So we either must invoke a different shell as root and pass the command to it (as in the first command), or just run the part in quotes as root.
Browsing through the pseudofiles under /proc/sys will render the same information as sysctl -a . You can obtain full details on how to use sysctl by doing man 8 sysctl . To bring up information about using the sysctl() function from programs to do the same operations, do man 2 sysctl . If settings are placed in /etc/sysctl.conf (see man sysctl.conf for details) settings can be fixed at boot time. Changes to this file can be digested by running: $ sudo sysctl -p which means that those changes will be enacted immediately. On systemd-based distros the settings are read from /usr/lib
/sysctl.d/00-system, but the original file is still supported.
Kernel modules
The Linux kernel makes extensive use of modules, which contain important software that can be loaded and unloaded as needed after the system starts. Many modules incorporate device drivers. Other modules can control network protocols, support different filesystem types and many other purposes. Parameters can be specified when
loading modules to control their behaviour. The end result is a great degree of flexibility and agility in responding to changing conditions and needs.
Many facilities in the Linux kernel are designed to be built into the kernel when it’s initially loaded, or to be added (or removed) later as modules as necessary. Indeed, all but the most central kernel components are integrated in such a fashion. Even in cases where the functionality will virtually always be needed, incorporation of the ability to load and unload as a module encourages development, because kernel reboots aren’t required to test changes. We can use the insmod command to load a module directly: $ sudo /sbin/insmod /path/to/module_name.ko
Kernel modules are stored at /lib/modules/<kernelversion> and have the file extension .ko . Modules are version specific and must match the running kernel or they can’t be loaded. The lsmod command lists currently loaded modules and shows their dependencies. Modules can be removed with rmmod . Note that it’s not necessary to specify the full path or the .ko extension here.
Most of the time, insmod and rmmod are eschewed in favour of the modprobe command. The full path doesn’t need to be specified, because modprobe relies on modules being installed in the correct location, generally /lib/ modules/$(uname -r). The command automatically loads any other modules that are required. Module removal is achieved with the -r switch, which will also unload any modules that were being used by the one specified, so long as they’re not required elsewhere.
The modinfo command displays information about kernel modules, including their filenames, versions, supported hardware and any parameters that they can be loaded with. Information about loaded modules is also available from the /sys pseudofilesystem directory tree. For example, to find out about the e1000 in the screenshot, one would look under /sys/module/e1000.