Skip to main content

Getting Started with the Kernel

Source

gh repo clone torvalds/linux

Kernel Source Tree

DirectoryDescription
archArchitecture-specific source
blockBlock I/O Layer
cryptoCrypto API
DocumentationKernel source documentation
driversDevice drivers
firmwareDevice firmware needed to use certain drivers
fsthe VFS and the individual filesystems
includeKernel headers
initKernel boot and initialization
ipcInterprocess communication code
kernelCore subsystems, such as the scheduler
libHelper routines
mmMemory management subsystem and the VM
netNetworking subsystem
samplesSample, demonstrative code
scriptsScripts used to build the kernel
securityLinux Security Module
soundSound subsystem
usrEarly user-space code (called initramfs
toolsTools helpful for developing Linux
virtVirtualization infrastructure

Building the Kernel

Configuring the Kernel

Kernel configuration is controlled by CONFIG_$FEATURE. For example, symmetrical multiprocessing (SMP) is controlled by CONFIG_SMP.

Configuration options values can be yes,no,module. Kernel features are usually yes or no whereas drivers are can be either yes,no,module. Configuration options can also be strings or integers.

We can use:

# Asks for options 1-by-1
make config

# Better tools
make menuconfig
make gconfig

# Creates configuration based on your architecture
make defconfig

to facilitate configuration.

Once the configuration is done, the selected options will be stored in .config.

After making changes in .config, you can validate and update the configuration using:

make oldconfig

Another helpful option is CONFIG_IKCONFIG_PROC which places the complete, compressed kernel configuration file at /proc/config.gz. You can then run the following command to compy the config:

zcat /proc/config.gz > .config
make oldconfig

To build the kernel using:


# No need for all the noise, just print errors/warnings if encountered
make > /dev/null

We can speed up the build process by running n concurrent jobs;

make -jn

# For 16 concurrent jobs
make -j16 > /dev/null

ccache and distcc can improve kernel build time as well.

Installing the Kernel

The installation is architecture and bootloader dependent. We need to find the directions for the bootloader on where it's expecting the kernel image and how to set it up to boot.

On x86 system using grub, you would:

cp arch/i386/boot/bzImage /boot
mv /boot/vmlinuz-version

And then edit /boot/grub/grub.conf and adding a new entry for the new kernel.

Linux Kernel Attributes

No libc or Standard Headers

This means that the kernel is not linked to any library because of speed and size. The full C library is too large and inefficient for the kernel.

Many usual libc functions are implemented inside the kernel such as lib/string.c. All we need to do is to include <linux/string.h>.

No Memory Protection

Make sure to not dereference a NULL pointer which will cause a major kernel error (oops). The kernel memory is not pageable so every byte consumed in memory is one less available physical memory.

No Floating Point

Using a floating point inside the kernel requires manually saving and restoring the floating point registers. Don't do this!

Stack

The user-space has a large stack that can grow dynamically. The kernel stack is small and fixed-size depending on architecture. On x86, the stack is configurable at compile-time and can be either 4KB or 8KB. Each process receives its own stack.

Sync and Concurrency

The kernel is susceptible to race conditions since it's a multitasking operating system, supports SMP, interrupts occur asynchronously with respect to the currently executing code.