The kernel is started via bootloader. The bootloader can pass kernel parameters to the kernel (see man bootparam).
Historically the bootloader tells the kernel to start the program init but nowadays systemd. The kernel parameters can also be changed during runtime via the program sysctl. To see the parameters type sysctl -a and to get a description man sysctl.
The kernel needs also a root filesystem. Kernel modules are on this root filesystem and could cause a what is first chicken or the egg problem, since kernel modules are on the root filesystem but might are required to access the root filesystem. There are two ways to solve this. Include the modules in the kernel, or use an initramfs. A initramfs is an initial ram file system that can be loaded into ram.
All modules required for the boot must be either in the kernel or initramfs
Boot with a liveCD's and look what it is using:
Launch the following programs:
lspci from pciutils package
lspci -v to get more details. lspci -vvv | grep Kernel to see what kernel modules get used.
lspci -vvv -s 00:10.2 to see just one single card
lspci -k to see the kernel modules supporting the cards and if in use
update-pciids update the list of known PCI ID and put it in
/usr/share/misc/pci.ids ,
this is where the text of lspci comes from.
lsmod
lshw
lsusb
dmesg
gtk-lshw (emerge lshw)
hwinfo
cat /proc/modules lists them or better formatted:
cat /proc/modules | cut -d ' ' -f 1
Check the Ethernet card since update via Internet requires it. Use the help and description in make menuconfig, make nconfig, using X make xconfig or make gconfig. Check there the kernel module names later to be seen when you use the command lsmod.
An easier way than create the .config file is finding somebody who already has done it, so look to find a .config.
There is make help that prints out a lot make inside the kernel source directory can do.
This section gives some hints about kernel compilation or information when building the first time a kernel on a new computer. For kernel updated go directly to the kernel compilation section.
The kernel sources are in the directory
cd /usr/src. To see
whats there type ls -l. The symbolic link Linux points to the selected source. To update the source
manually, the old link can be removed rm /usr/src/linux and a new link can be created ln -s linux-<nnn> linux.
Use make xconfig to have the short documentation available when for the options. Documentation is on the Internet or /usr/src/linux/Documentation.
or https://www.kernel.org/doc/ that is build from the file /usr/src/linux/arch/x86/Kconfig. This file includes lines as
source "init/Kconfig"
that include other files.
The kernel configuration of the hidden file /usr/src/linux/.config can be attached to the kernel. The kernel options IKCONFIG (general
setup > kernel .config support) and IKCONFIG_PROC (general setup > enable access to .config
through /proc/config.gz> must be set.
When the
kernel is running and having set IKCONFIG_PROC the
/usr/src/linux/.config can be unzipped
from /proc/config.gz gunzip config.gz.
To restore cd /usr/src/linux and zcat /proc/config.gz > .config
The other option is:
scripts/extract-ikconfig <name of the kernel file>
Before rebooting and running into version problems with some kernel modules not delivered with the new kernel source. Re-emerge those kernel modules now, since the link points already to the new kernel source (even the old kernel is running) so the drivers will match the kernel version, otherwise the kernel probably will refuse to load those drivers (Other way would be using the option to force loading kernel modules with mismatching versions exist, however this is less clean and safe).
Further if selecting in Grub at boot time previous compiled kernels, an other problem might occur. Kernel modules are still used from the last compilation and might no more be compatible to the previous installation, they might even block your computer. Therefore all kernel modules not taken from the kernel need to be re-compiled as well.
To not manually remember what kernel modules are installed, Gentoo Linux has a tool emerge module-rebuild that does a rebuild to all used kernel modules not delivered with the kernel source
module-rebuild rebuild
does the job. An alternative would be emerge all packages individually.
The kernel source is under
/usr/src/linux. It is quite common to have different versions of the kernel source or even patched versions of the kernel sources on the system. So/usr/src/linux is mostly a symbolic link to a directory containing the selected kernel source. Setting up the kernel source means bending the symbolic link
/usr/src/linux to the desired directory as: ln -s /usr/src/<kernel source name> /usr/src/linux
Under Gentoo Linux there is eselect that allows to work with this link more safely and advanced. To see what you have got and what source is used
eselect kernel list
If the newest source is not selected, select it (it does nothing else than safely updating the link of
/usr/src/linux):
eselect kernel set <n>
Goto the kernel source
cd /usr/src/linux
If you have selected a new source copy over old kernel configuration file:
cp /usr/src/linux-4.<version>-gentoo-r<release>/.config .config
To update your old .config to the new source run:
make oldconfig
.config holds the kernel configuration to edit it:
make menuconfig
Pressing / pops up a search window
or the newer method
make nconfig
or to have something more advanced under X:
make xconfig
If there is no .config file type make defconfig or make config
If an option can not be found using make menuconfig then it might be that it is hidden. Search for the option and then look closer to the "Depends on:" line. In the example below set first VLAN_8021Q after that the hidden option BRIDGE_VLAN_FILTERING becomes visible.
Compile the kernel and install the kernel modules
make && make modules_install
(This command uses && to run two commands in a row, make standalone does the compilation and then make modules_install that installs the modules).
Copy and rename the kernel to the boot directory. Depending on how you boot, the destination path might be different as /boot/boot/ . The kernel should be renamed to reflect its source, version and maybe compilation date so it can be distinguished from other kernels:
cp arch/<arch>/boot/bzImage /boot/kernel-<version>-gentoo-r<release>-<date>
The architecture <arch> is i386 for a 32bit machine, x86_64 for a 64bit machine or arm for an embedded system using a arm micro-controller as the Raspberry.
There is also make install to install the kernel, but it will get default names for the kernel and might have a conflict with the grub-mkconfig.
In case the kernel does not compile save your configuration and clean the kernel source:
cp /usr/src/linux/.config /root/kernel-config
cd /usr/src/linux
make clean
mv /root/kernel-config .config
make && make modules_install
For grub grub-mkconfig -o /boot/grub/grub.cfg does the job.
For grub legacy ( grub below version 1) now add entry in the loader menu /boot/grub/grub.conf
title=Gentoo Linux 3.<version>-gentoo-r<release>-<date>root (hd0,0) kernel /kernel-3.<version>-gentoo-r<release>-<date>root=/dev/sda3
When you have a new source compiled, the depending kernel modules not delivered with the kernel source need also to be recompiled, otherwise they might not be accepted by the kernel due to a version conflict.
For Gentoo emerge @module-rebuild will do it. In the past there was the following command (emerge module-rebuild) module-rebuild rebuild that recompiled the known kernel modules not delivered with the kernel source:
Now reboot: init 6
For an overview see:http://tldp.org/HOWTO/KernelAnalysis-HOWTO.html
Applications can communicate with the kernel using system calls. All system calls are listed in
/usr/src/linux/include/asm/unistd.h
The applications prepare the data for the system call and create an interrupt to call the kernel to do something. The following example shows how a C program makes the system call write.
unistd.h is the c library that holds the system call C functions.
0 is the file descriptor and means standard input output. 12 stands for the 12 characters to be printed.
The following program when started gets obviously a process ID, but it also creates a second child process using the fork command. After that both parent and child process get trapped in while loops. Using the KDE System guard both processes can be observed and killed (parent)!
Example 3.3. fork
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main ()
{
int forkvar;
forkvar = fork();
if(forkvar==0)
{
printf("child process\n");
while(1);
}
else
{
printf("parent process started child with PID:%i\n",forkvar);
while(1);
}
return 0;
}
Now, the child process is running, but as a second instance of the parent process. The kernel has a process table that actually can be seen using KDE System guard. Child and parent process running with the same parameters but different PID's. In the tree view the relation between child and parent (and bash that has called them) can also be verified.
The following line can be put into the program to call an other program
execl("<path to and the the binary>","<name of the program>,NULL);
The data in the process table will be replaced.
<path to and the binary> has to be replaced by program to be executed including the directory
<name of the program> has to be replaced
NULL stands for null arguments passed to the program
Processes can have different status:
|
Running |
Having one CPU, just one process can run at a time |
|
Ready |
The process is ready to run but waits for the kernel scheduler to start it |
|
Blocked |
Process is waiting for an event and does not be activated by the kernel scheduler |
The process table is defined in /usr/src/linux/include/linux/sched.h see the definition:
struct task_struct
Different signals can be sent to the processes
|
SIGTERM |
Friendly ask to terminate |
|
SIGKILL |
Not so friendly ask to terminate |
Over the years the kernel configuration could be come bloated, resulting in big kernels and long compilation time.
Create a copy of the /usr/src/linux/.config file
Automatic trimming of the /usr/src/linux/.config file is done with make localmodconfig but this cleans modules that are not loaded (as not appear with lsmod). Such modules however might be used when plug in hardware as usb devices or mounting file systems.
To improve this setup modprobed-db
modprobed-db --help
Run it frequently over the next weeks to log the modules used
cron job
0 */6 * * * /usr/bin/modprobed-db store &> /dev/null
For cronie
cat <<'EOF' > /etc/cron.hourly/modprobed-db #!/bin/sh /usr/bin/modprobed-db store EOF
chmod +x /etc/cron.hourly/modprobed-db
run-parts /etc/cron.hourly
~/.config/modprobed-db.conf is the configuration and ~/.config/modprobed.db the list of modules loaded
With a more complete ~/.config/modprobed.db run make LSMOD=~/.config/modprobed.db localmodconfig
Just modules as files set with (m) not build into the kernel (y) are affected. So to get smaller kernels first try to convert (y) to (m) manually, but take care modules required to boot must be inside the kernel (y) or be inside a initramfs. Check cat .config | grep "=y"
The other way building a big monolithic kernel would be possible with make localyesconfig
make oldconfig with user prompt and make olddefconfig without user prompt will update the /usr/src/linux/.config to the new kernel version and add new settings. make defconfig creates a default /usr/src/linux/.config file
./scripts/diffconfig .config.actual .config.default is a diff tool coming with the kernel to show the differences in a more specific form.
.config files do not contain a complete list of the kernel parameters so the compare output has to be taken by care.
- means just exists in the actual file and be absent in the default file but do not delete it in the actual file
+ means just exists in the default file and be absent in the current file but do not add it in the current file
SND_HDA_CODEC_ANALOG m -> n means first file had (m) second has disabled it (n)