I personally think they're moving in the wrong direction. I'd rather have "NMIRFS" (no more initramfs). Eg, a smarter bootloader that understands all bootable filesystems and cooperates with the kernel to pre-load modules needed for boot and obviates the need for initramfs.
FreeBSD's loader does this, and its so much easier to deal with. Eg, it understands ZFS, and can pre-load storage driver modules and zfs.ko for the kernel, so that the kernel has everything it needs to boot up. It also understands module dependencies, and will preload all modules that are needed for a module you specify (similar to modprobe).
As other sibling comments have explained, an initramfs is usually optional for booting Linux.
If you build the drivers for your storage media and filesystem into the kernel (not as a module), and the filesystem is visible to the kernel without any userland setup required beforehand (e.g. the filesystem is not in an LVM volume, not on an MD-RAID array, not encrypted), it is fully capable of mounting the real root filesystem and booting init directly from it.
The only point of consideration is that it doesn't understand filesystem UUIDs or labels (this is part of libuuid which is used by userland tools like mount and blkid), so you have to specify partition UUIDs or labels instead (if you want to use UUIDs or labels). For GPT disks, this is natively available (e.g. root=PARTUUID=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709 or root=PARTLABEL=Root). For MS-DOS disks, this is emulated for UUIDs only by using the disk ID and partition number (e.g. root=PARTUUID=11223344-02).
You can also specify the device name directly (e.g. root=/dev/sda2) or the major:minor directly (e.g. root=08:02), but this is prone to enumeration order upset. If you can guarantee that this is the only disk it will ever see, or that it will always see that disk first, this is often the most simple approach, but these days I use GPT partition UUIDs.
Yes, I think he realizes it's optional for booting Linux.
In practice, we have generic kernels which require a lot of stuff in modules for real user systems running on distributions. Instead, though, we could have a loader which doesn't require this big relatively-opaque blob and instead loads the modules necessary at boot time (and does any necessary selection of critical boot devices). i.e. like FreeBSD does.
There's advantages each way. You can do fancier things with an initramfs than you ever could do in the loader. On the other hand, you can change what's happening during boot (e.g. loading different drivers) without a lot of ancillary tooling to recover a system.
Not entirely, it is possible for simple boot solutions, but to enable LUKS and various other rootfs, it usually requires some userspace probing, authentication, etc. I'm not so sure it would be easy to convince the kernel maintainers to add a user prompt for pin code to the kernel just to avoid having an initrd.
> it is possible for simple boot solutions, but to enable LUKS and various other rootfs, it usually requires some userspace probing, authentication, etc
I did mention that the root filesystem had to be both not encrypted and not require any userland setup.
> I'm not so sure it would be easy to convince the kernel maintainers to add a user prompt for pin code to the kernel
That wouldn't help, as the password is not usually used directly as a volume encryption key. In LUKS2 for example, a memory-hard KDF (Argon2) can be used to transform the password or PIN into a key-slot encryption key which is then used to decrypt that slot to obtain the volume encryption key (which is usually completely random and not at all related to or derived from any kind of password) in order to set up the dm-crypt mapping.
> just to avoid having an initrd.
No distribution has used an initrd in the last several years; initramfs reigns supreme now. They are not the same thing; an initrd is an image of a real filesystem (e.g. squashfs or ext2) that is read-only mounted onto / by the kernel during its startup, while an initramfs is (an optionally-compressed) cpio archive that is extracted to a read-write tmpfs (or ramfs if tmpfs is not available) mounted on / by the kernel during its startup and then the memory occupied by that cpio archive is freed because it is no longer necessary. An initramfs can also be built into the kernel image; an initrd cannot, and must be provided by a bootloader.
The Linux kernel does not require an initramfs. You can build a kernel with everything compiled in; with no modules needed at all. Initramfs is used for generic kernels where you don't know beforehand which features will be required. This allows you to avoid wasting RAM on features you don't use. But it is optional.
I realize that. But every distro I've used uses an initramfs, so unless you want to build your own kernels, you're stuck with it, and the painfully slow initramfs updates when you update packages, and dkms (or similar) updates the initramfs with the newer version of your out-of-tree modules.
Given the reason why "out-of-tree modules" exist, there's really no way to eliminate initramfs or something like it entirely in the general case. It might be possible to speed up the process of building the image (as long as the results are not "redistributed"), but this is a licensing and legal problem, not a technical one. FreeBSD is under a much more permissive non-copyleft license and so can legally bundle things that Linux cannot.
- linux tells the bootloader what folder the modules live
- bootloader just puts them all in memory
- linux just picks what it needs.
That's all the initramfs is anyways. The point is there's no reason to prebuild an image from inside Linux, you can just have grub assemble a simple fs on the fly.
initramfs can be eliminated if no kernel modules are required to boot the system. In practice, this means drivers for the motherboard, drivers for the block storage system, and the filesystem have to be compiled in as opposed to being modules. Certain 'interesting' disk schemes that require userspace configuration tools aren't possible, including LVM2, dmraid, disk encryption, /etc/fstab has to hardcode the physical path, and probably a dozen other things I can't think of. If you want to do PXE boot over wifi and you have out of tree wifi drivers I don't think that would work, though tbh PXE over wifi sounds insane.
> ...But to load it at boot time it absolutely must be done through an initramfs. Is that right?
No, not AFAICS; it is incorrect.
On UEFI the system boots from a FAT32 partition. Put the kernel directly on that FAT32 partition, and any necessary modules such as ZFS, and the kernel can load the ZFS module from FAT32 and then mount root directly without any need for an initramfs.
This is how systemd-boot works.
I am not advocating systemd-boot -- I found it a pain to work with -- but the point is that it's perfectly possible and doable. The initramfs is a bodge and it's time we did away with it. It should only be needed for installation and rescue media.
> But to load it at boot time it absolutely must be done through an initramfs. Is that right?
Yes, because it cannot be part of the kernel image, or it would be illegal (a violation of the GPL license) to distribute that kernel. Therefore, it must be a module, and that module has to live somewhere and be loaded by something. If root is on ZFS, this must therefore live in an initramfs and be loaded by it so that the initramfs can mount the real root filesystem on the kernel's behalf.
One could have the equivalent of DKMS build the modules into the kernel image instead of building the initramfs. I don't know how much practical overhead there is to the initramfs and pivot_root dance, but it feels far uglier than it should need to be to just load some modules.
That would run afoul of Turkish copyright vignette laws, that have an exemption for stuff everyone can use and redistribute royalty-free but no exemption for stuff that you can use royalty free but not redistribute.
The distro could automatize the compilation of the kernel with ZFS on the user machine. In that case no license is violated as the kernel image is not distributed with ZFS.
That would probably make updates a lot less slower than having zfs shipped in an initramfs though.
It doesn't really have to be slower as all that would be needed to do on installation is the final linking step. Linking prebuilt objects into a prepared kernel image shouldn't be inherently slower than assembling modules into an initramfs.
The "problem" with the GPL here arises not when you, the end user, take a piece of GPL-licensed software and combine it with other software, as is your GPL-protected right, but when you try to redistribute the result. You see, every end user has the same right to obtain all of the source code for GPL-licensed software that they receive, and for all of that source code to be licensed in a way compatible with the GPL. Once the kernel and non-GPL-licensed modules have been combined into a single piece of software, you are free to use it locally as you wish, but you can't share it, because you would be unable to meet the obligations you owe to the person you give it to.
Bear in mind that the modules are meant to be combined with the kernel, and the method by which that happens isn't specified by the module authors. So, a tool which makes all of this easier for you to do isn't circumventing any restriction meant to stop you from doing this, because no such restriction exists.
> So, a tool which makes all of this easier for you to do isn't circumventing any restriction
Is this the case though? I thought there was an argument that in order to create that tool - you would need enough knowledge that it would require you to basically create a derivative work.
Is anyone really wanting to get back into the business of building their own kernels? I started using Linux heavily in '92, and I've built a lot of kernels, and am quite happy to not be building them anymore.
It's easy (2-3 commands), takes like a minute on a modern machine with trimmed down kernel configuration, and you can customize the kernel to your liking (write/patch drivers, embed firmware blobs, fix things that are broken or missing). What's to hate? :)
Though I only do it for my ARM based devices currently.
And if you're not throwing away build artifacts after each build, then getting stable updates is just a `git pull` and incremental make, which is usually very quick.
I kind of liked compiling my own kernels. I felt I was better-connected to the state of things, and it was fun to see it all evolve from the vantage point of "make menuconfig".
But initramfs isn't so bad, and it allows things like ZFS root to have a modicum of smoothness and integration.
I build my own kernel. I did invest some time to select the right configuration, but now it's just a question of copying over the old .config and running "make". What's annoying about that?
I understand not wanting to. I have been compiling my own kernels since about 2008, I think. I have occasionally thought about switching to something else, but really it has only gotten better (faster) over time.
When I was young and spry, I used to compile them with every new minor revision. Now, it is just maybe a couple times per year. I think that cooling it on how often I do it has helped it not become annoying.
kernel compilation is easily automated. I don't want to do that and like the initramfs approach mostly because I like the fact I can take a hard drive out of a computer and boot the system on another one in case of a hardware failure.
That is a lot faster than recovering from a backup.
> Initramfs is used for generic kernels where you don't know beforehand which features will be required.
And also for e.g. cases where you've got some custom stack of block devices that you need to set up before the root FS and other devices can be mounted. It's not just about loading kernel modules.
Because there are a lot of different types of filesystems supported. And you'd have to compile them all into the kernel. Which of course you can do, that is supported by the build system today. But Distros typically prefer to keep their kernels small, and not waste the RAM that would be taken up by compiling it all into the kernel.
This requires a bunch of additional logic in the bootloader (eg, providing disk encryption keys), and since you're not doing this in a fully-featured OS environment (as you are in the initramfs case) it's going to be hard providing a consistent experience through the entire boot process. Having the pre-boot environment be a (slightly) cut-down version of the actual OS means all your tooling can be shared between the two environments.
This is a step in that direction. What they are proposing is not so much "no bootloader" but using a small Linux as bootloader. I'm using a similar setup for some time and it gives some of these advantages. Especially you get support for all relevant filesystems (you can support everything Linux supports because it is Linux), it can dynamically build a minimal initramfs with only the needed drivers if you want to and understands module dependencies (e.g. it can just dump the list of modules it uses itself) and is generally much more flexible.
This bootloader gives you some amazing features such as booting distros from different zfs datasets or snapshots and chrooting into your system. Really does make grub and ext4 feel like the stoneage.
A little of both. Everyone know about Linus' refusal to touch CDDL code, but grub isn't the kernel.
There have been several attempts to add features to the grub zfs code over the years, but there are several maintainers of grub who happen to be employees of Oracle, and typically the attempts go nowhere.
I personally can't recommend using grub anymore. The whole "just make 2 pools" solution is unacceptable, and until Oracle stops gatekeeping, their code becomes more obsolete in my eyes.
Linux has multiple choices for filesystems for root, even if you only count the most popular ones. And on top of that they could be encrypted by LUKS. Duplicating all that into the bootloader is what GRUB does, and poorly. Putting the kernel into the ESP is much better in that regard.
The keys to decrypt the kernel are in u-boot. u-boot's keys are in the low level boot loader, and the keys for that are sometimes burned in write-only fuses on the microcontroller itself. Other chips have OP-TEE or similar frameworks, and you just chain the keys all the way down to the initramfs and that data is wiped when you start init.
You're reliant on the capabilities of the chip that you're working with, and a flaw in that can unravel everything that you've done. In one case, I had to disable the on-chip boot agent once things were provisioned because of flaws in their implementation.
In short, a signed applet could be sent to the chip to do things like read/write NAND or NOR, set fuse bits, etc. When an unsigned applet was sent, it was rejected as expected but they neglected to clear the memory contents in this case. So you could send a malicious applet, let it be rejected, and then just tell it to execute. It's kind of a fascinating writeup if you want to know more [1].
Does FreeBSD's loader share code with the kernel? It does seem like a lot of duplication of systems to make it work in comparison to just using the same code.
FreeBSD's loader does this, and its so much easier to deal with. Eg, it understands ZFS, and can pre-load storage driver modules and zfs.ko for the kernel, so that the kernel has everything it needs to boot up. It also understands module dependencies, and will preload all modules that are needed for a module you specify (similar to modprobe).