Goals, features, to do
The purpose in life of a tool like Yaird
is to produce an initial boot image that loads the required modules
to allow a booting kernel to access the root file system and from
there use the startup scripts to get to the default run level.
This means that hardly any drivers need to be compiled into the kernel
itself, so a distribution can produce a kernel with a large amount of
modules that will run unchanged on practically any hardware, without
introducing a large number of unused drivers that would waste RAM.
In a sense, the initial boot image customises the kernel to the hardware
it happens to be running on.
That purpose still leaves a lot of room to optimise for different
goals: as an example, you could attempt to make the generated
image as small as possible, or you could attempt to make the
generated image so flexible that it will boot on any hardware.
This chapter discusses the goals that determined the design, the
resulting features, and what's still left to do.
The goals
Well, not really. I started this thingy to show off a small
algorithm to find required modules based on sysfs information.
To make that a credible demonstration, the small algorithm
turned out to need a lot of scaffolding to turn it into a
working program ...
of Yaird are as follows:
Be free, as in GPL.
Be maintainable. Small functions with documented arguments
and result are better than a shell script full of constructs
like eval "awk | bash | tac 3>&7".
Be secure and reliable. The application should stop with an error
message at the slightest provocation, rather than run the
risk of producing a non-booting initrd image.
The application should not open loopholes that allow the 'bad
guys' to modify the image, gain access to raw devices or
overwrite system files.
Be distribution agnostic. Fedora and Debian run similar
kernels and similar startup scripts, so there's little
reason why the glue between the two levels should be
completely different.
Have limited footprint. The tools needed to build and run
the application should be few and widely available, with a
preference for tools that are installed anyway.
Be future proof. Future kernels may use different modules
and may change device numbers; the application should need
no changes to cope with such migrations.
Promote code reuse. Make functions side-effect free and
independent of context, so that it's easy to package the
core as a library that can be reused in other applications.
Generate small images. The application should accurately
detect what modules are needed to get the root file system
running and include only those modules on the generated
image.
An alternative and equally interesting exercise would be
an attempt to generate a universal initrd that could be
distributed together with the kernel. Such an image
would most likely be based on udev/hotplug.
Requirements:
Linux 2.6.8 or later, both when running
yaird and when running the generated
image. By limiting the goal to support only recent kernels,
we can drastically reduce the number of special cases and
knowledge about modules in the application.
A version of modprobe suitable
for 2.6 kernels.
Sysfs and procfs, both on the old and on the
new kernel.
Perl and the HTML-Template module.
To achieve these goals, the following features are implemented:
Templating system to tune the generated image to a
given distribution; templates for Debian and Fedora FC3
included.
Interprets /etc/fstab, including
details such as octal escapes, ignore and
noauto keywords, and — for ext3 and reiser
file systems — label and uuid detection.
Where applicable, options in /etc/fstab
are used in the generated image.
Supports volume management via LVM2; activates only the volume
group required for the root file system.
Supports software RAID via mdadm; activates only required
devices.
Supports EVMS, an alternative user level interface to LVM2 and MD.
Supports encrypted filesystems via cryptsetup and
cryptsetup-luks.
Supports NFS root filesystems.
Understands SATA, IDE, DASD and USB storage devices.
Generated image does not use hard coded device
numbers.
Except where the distribution depends on it;
there are some issues with mdadm in Debian.
Image generation understands how included executables may
depend on symbolic links and shared libraries. Shared libraries
work for both glibc and klibc.
Support input devices such as USB keyboard, if the input
device supports sysfs.
Input devices are needed in the initial image to supply
a password for encrypted root disk and to do debugging.
Basic support for kernel command line as passed by the boot
loader. Interprets init=, ro, rw.
Module aliases and options as specified in
/etc/modprobe.d are supported.
Interprets the blacklist information from hotplug.
Interprets the kernel configuration file that defines whether a
component is built in, available as a module or unavailable.
By maintaining a mapping between module name and config
parameter for selected modules, we avoid error messages if
for instance a required file system is built into the kernel.
Supports initramfs, both in Debian and Fedora versions.
An example template using the older initrd model
is included for Debian.
Does not require devfs in either the old or the new kernel.
Behaviour of the generated image can be tuned using
configuration files.
Obviously, this tool is far from complete. Here's a list of
features that still need to be implemented:
Swsusp is not supported yet.
Firewire is not supported.
Loopback file systems are not supported yet.
Filesystems encrypted via loopaes are not supported yet.