You don't need to patch anything. You just need to configure and compile the kernel by yourself. This is advanced task so it is not for begginers. The trick is to configure the kernel to support just your hardware and compile everything inside the kernel and not as a module (at least the drivers necessary for booting: disk controller, filesystem, …).
There are plenty of tutorials, how to configure and compile your kernel
So just google "kernel compile {your distro}". It is important to use correct tutorial for your distro. Distro you are using may expect some functionality available only in "distro" kernel and not in "vanilla" kernel. Correct tutorial will point you to correct sources.
You can use UUIDs in /etc/fstab
but not in GRUB after removing initrd/initramfs.
For example, I'm using Gentoo and I have never used initrd/initramfs. Everytime the new kernel is available, I must configure and compile it by myself. I'm using grub with root=/dev/sdb4
kernel parameter but in fstab I'm using UUIDs.
So if I want my rootfs to be in RAM, I need to set CONFIG_INITRAMFS_SOURCE to point to my rootfs (in cpio format presumably).
That's one way to do it, yes, but it is not the only way.
If you have a bootloader that can be configured to load the kernel and the initramfs as separate files, you don't need to use CONFIG_INITRAMFS_SOURCE
while building the kernel. It is enough to have CONFIG_BLK_DEV_INITRD
set in kernel configuration. (Before initramfs there was an older version of the technique named initrd
, and the old name still appears at some places.) The bootloader will load the initramfs file, and then fill in some information about its memory location and size into a data structure in a specific location of the already-loaded kernel image. The kernel has built-in routines that will use that information to find the initramfs in the system RAM and uncompress it.
Having the initramfs as a separate file will allow you to modify the initramfs file more easily, and if your bootloader can accept input from the user, perhaps specify another initramfs file to be loaded instead of the regular one at boot time. (That's very handy if you try and create a customized initramfs and get some things wrong. Been there, done that.)
For a traditional BIOS-based x86 system, you'll find information about these details in (kernel source)/Documentation/x86/boot.txt. UEFI-based systems do it a bit differently (also described in the same file), and other architectures like ARM have their own sets of details about passing information from the bootloader to the kernel.
Furthermore, what if I want my rootfs to be on physical storage (like eMMC, flash drive, etc.) and not in RAM?
In regular non-embedded systems, the initramfs will usually only contain enough functionality to activate the essential sub-systems. In a regular PC, those would usually be the drivers for the keyboard, display and the driver for the storage controller for your root filesystem, plus any kernel modules and tools required to activate subsystems like LVM, disk encryption, and/or software RAID, if you use those features.
Once the essential sub-systems are active and the root filesystem is accessible, the initramfs will typically do a pivot_root(8)
operation to switch from initramfs to the real root filesystem. But an embedded system, or a specialized utility like DBAN, could package everything it needs into the initramfs and just never do the pivot_root
operation.
Usually, the scripts and/or tools within the initramfs will get the necessary information to locate the real root filesystem from the options on the kernel command line. But you don't have to do that: with a customized initramfs, you could do something like switching to a different root filesystem if a specific key or mouse button is held down at a specific time in the boot sequence.
With a complex storage configuration (e.g. encrypted LVM on top of a software RAID, on a system that uses redundant multipathed SAN storage), all the information needed to activate the root filesystem might not fit onto the kernel command line, so you could include the bigger pieces into initramfs.
Modern distributions usually use an initramfs generator to build a tailored initramfs for each installed kernel. Different distributions used to have their own initramfs generators: RedHat used mkinitrd
while Debian had update-initramfs
. But after the introduction of systemd
it looks like many distributions are standardizing on dracut
as an initramfs generator.
A modern initramfs file can be a concatenation of multiple .cpio
archives, and each part may or may not be compressed. A typical initramfs file on a modern x86_64 system might have an "early microcode update" file as a first component (usually just a single file in an uncompressed cpio archive, as the microcode file is typically encrypted and so not very compressible. After that comes the regular initramfs content, as a compressed .cpio
file.
To gain a deeper understanding of your system, I would encourage you to extract an initramfs file to a temporary directory and then examine its contents. On Debian, there is an unmkinitramfs(8)
tool that can be used to extract an initramfs file in a straightforward manner. On RedHat 7, you might need to use /usr/lib/dracut/skipcpio <initramfs file>
to skip the microcode update file, and then pipe the resulting output to gzcat
and onward to cpio -i -d
to extract the initramfs contents to the current working directory. Ubuntu might use lzcat
in place of gzcat
.
Best Answer
I know it's a late answer, but for anyone still trying to find one, here is my solution: you can create a combined .efi image with kernel, commandline and initramfs inside, called a "unified kernel image".
Reference: https://wiki.archlinux.org/index.php/Systemd-boot#Preparing_a_unified_kernel_image