A Case Against initrd

I never really liked initial ramdisks. It always felt like a dirty, hackish solution. It tends to slow down the boot process, and it requires maintaining a complete second system environment -- which has to be kept in sync with the main system on upgrades and configuration changes... Rather surprisingly, I don't use initrd on my system :-)

Some other considerations now prompted me to think about this in more depth. And I know you want to read my earthshaking conclusions :-)

During a typical boot process nowadays, we have a succession of four different environments: First one is the firmware. (BIOS in standard PCs.) Second is bootloader. Third is ramdisk. And finally, the fourth is the real working environment.

This is clearly too much. It creates complexity. It creates redundancy -- not so much in code, but in configuration -- a maintenance nightmare. (Be honest: Are you *not* dreaming of broken ramdisks and bootloader entries by night?...)

So, which of these phases could be rationalized? The first one is obviously necessary. (Well, unless we want to store a complete image of the system environment in flash memory, and update it on every upgrade and configuration change :-) ) The fourth one is what we want in the end. But what about the two intermediate stages, poor things, can we cut down on these?

Leaving them both out seems pretty much impossible in practice. That would require the firmware to provide drivers for pretty much any device the user might want to load the system components or information about the startup from (users have an annoying tendency to come up with the most surprising setups :-) ); and the firmware would need to be smart enough to construct and launch the image for a completely working system instance, based on the provided startup information.

I heard that OpenFirmware is/was quite powerful. I doubt though that it had enough drivers to completely avoid the need for additional stages; and I'm also not convinced that it was smart enough to completely load various systems without too much hassle. Of course, it's possible to do about anything with a sufficient amount of Forth scripts -- but then (I'm tactfully omitting the masochism factor here :-) ), it's effictively introducing another stage again.

Anyways, the cold dark evil reality we live in is standard PC BIOS -- which tends to have a considerable number of drivers (though still not enough for all cases...), but is totally stupid -- all it does is load a single sector from the hard disk...

So stage 2 (boot loader) is not really avoidable. Which leaves us with stage 3: Is the boot loader powerful enough to avoid the need for a ramdisk? I tend to believe that with GRUB2, it is.

It comes with a lot of drivers -- probably enough to satisfy any need.

(This is a bit of code duplication of course; with a ramdisk, the system's native drivers are used to ultimately load the final system environment, and the earlier stages can be kept minimal. OTOH, the grub drivers can be much simpler than the system's proper drivers, so it's not really that bad. Moreover, it can't be really avoided anyways -- in general, you want to be able to load the kernel and boot infromation from the same places from where the rest of the system is later loaded... And if not you, then someone else :-) )

Also, it comes with the multiboot loader, which -- in combination with the powerful scripting facilities -- should be sufficient to completely set up the working environment for many operating systems. And if that is yet not powerful enough, there is still the possibility of writing a custom loader module handling specifics of the system. The nice thing is that the module doesn't need to be distributed with GRUB itself (it's nice to keep the bootloader down to a size that still fits on a CD ;-) ) -- it is perfectly possible and reasonable to make it part of the actual operating system for which it is designed.

In a (much) older post, I mentioned my POSIX level driver proposal. Part of it describes boot methods. Aside from a boring ramdisk (sorry...), I also proposed a lovably crazy approach: Implementing a mechanism that allows using GRUB's drivers after the actual system starts, until it has loaded it's own drivers.

Now I realize that it makes much more sense the other way round: Move the boot process (up to the moment all necessary native drivers are available) completely into GRUB. This allows a similar level of flexibility, with considerably less magic. (I'll miss the crazyness...)

The driver proposal relies heavily on extracting information from the filesystem structure, and passive translators in particular; so we need to extend GRUB so that it can read passive translator information from the filesystem, and initialize active translators so that the driver hierarchy can immediately become functional once control is passed to the system.

This could either be done by implementing extensions that can be used in normal boot scripts, or by implementing a loader module that does all the driver setup automatically. The former is probably more tricky, but also more transparent and flexible.

A similar approach should allow preparing the startup of any other system as well, avoiding the need for any initial ramdisk. Good riddance :-)