A few notes I took while building my first custom kernel a year back.
Building and installing a custom Linux kernel on Debian
$ cp /boot/config-$(uname -r) .config $ sudo make -j 4 && sudo make modules_install -j 4 && sudo make install -j 4 $ update-initramfs -c -k $(VERSION) $ update-grub
make -j4 builds the kernel and the kernel modules. 4 is the number of threads
used for the build, adjust it to match your hardware. Build time: about 1-2
hours on a decent machine
make modules_install installs the kernel modules to /lib/modules or
make install installs the newly built kernel to
update-initramfs creates initramfs for the new kernel.
update-grub updates GRUB's config files to take the new kernel in account.
What is initramfs ?
initramfs is a tiny rootfs loaded by the kernel at startup. It is responsible for mounting the actual root filesystem.
A rootfs is a ramfs (or a tmpfs, depending on your kernel configuration) which is always present in > 2.6 systems. A ramfs is basically the kernel's caching mechanisms exported as a ram-based filesystem. The ramfs implementation is very simple (the code base is actually so small that it's always enabled in the kernel) but this comes with a few drawbacks: ramfs memory can't be freed (a ramfs grows indefinitely) nor limited (it will fill up the ram until the system goes oom).
tmpfs addresses most of these issues at the cost of increased complexity.
Why not directly mount the actual /root ?
If the system you're booting on is clearly defined during kernel build, that is it is possible to statically build the kernel modules into the kernel, it isn't needed, no. However, GNU/Linux distributions like Debian distribute generic kernels where all drivers are distributed as modules (statically compiling them into the kernel would produce way too big kernel images), and in this case modules have to be selected and loaded from /lib at boot time.
This is the "main" reason why systems like Debian typically need to mount initramfs before mounting the actual /root.
That said, there are other reasons to use initramfs, even with statically compiled drivers.
For example, in the case where the HDD is encrypted, user-space binaries are needed to decrypt the disk (along with an interface to retrieve the passphrase, etc). All of this is not handled by the kernel, meaning that it has to be included in a minimal user-space environment in the initramfs.
Similarily, booting from the network requires networking tools not provided by the kernel itself, so they have to be included in the initramfs.
What's the difference with initrd ?
initrd was compressed filesystem image mounted by the kernel.
initramfs is a set of compressed files decompressed into a temporary cache fs into the kernel.
It is quite common to call initramfs initrd nowadays. initramfs is kind of the modern way to implement initrd.
Why updating the GRUB config ?
The GRUB displays a list of available kernels to boot from at startup. This list
has to be updated somehow. Back in the days you had to enter them manually in
the configuration files, but now there are scripts capable of scanning the root
filesystem and generating these config files for you. That's exactly what
grub-mkconfig does, and
update-grub is nothing more than a wrapper for
grub-mkconfig -o /boot/grub/grub.cfg.
Sources, further reading
- @sreehari: How to build and install the latest Linux kernel from source
- @rob (kernel.org): ramfs, rootfs and initramfs