
Slackware initrd mini HOWTO
by Patrick Volkerding, volkerdi@slackware.com
  Fri Apr 10 18:45:55 CDT 2009
Adapted for Slackware ARM port by Stuart Winter, mozes@slackware.com
  Sat Jun 20 11:20:14 BST 2009

This document describes how to create and install an initrd, which may be 
required to use the 2.6 kernel.  Also see "man mkinitrd".

1.  What is an initrd?
2.  Why to I need an initrd?
3.  initrd, Kernel packages and /boot in Slackware ARM
4.  How do I build the initrd?
5.  Now that I've built an initrd, how do I use it?


1.  What is an initrd?

Initrd stands for "initial ramdisk".  An initial ramdisk is a very small 
Linux filesystem that is loaded into RAM and mounted as the kernel boots, 
and before the main root filesystem is mounted.

2.  Why do I need an initrd?

The usual reason to use an initrd is because you need to load kernel 
modules before mounting the root partition.  Usually these modules are 
required to support the filesystem used by the root partition (ext3, 
reiserfs, xfs), or perhaps the controller that the hard drive is attached 
to (SCSI, RAID, etc).  Essentially, there are so many different options 
available in modern Linux kernels that it isn't practical to try to ship 
many different kernels to try to cover everyone's needs.  It's a lot more 
flexible to ship a generic kernel and a set of kernel modules for it.

3.  initrd, Kernel packages and /boot in Slackware ARM

Unlike the x86 platform, a separate kernel is required for each ARM platform.
For each platform that Slackware ARM supports, the following
are provided:

  - 1 Kernel package in slackware/a/
    e.g.  kernel_versatile-2.6.29.1-arm-1.tgz
  - 1 Kernel module package in slackware/a/
    e.g.  kernel-modules-versatile-2.6.29.1_versatile-arm-1.tgz
  - 1 initrd in kernels/<platformname>/initrd-<platformname>.gz
    e.g.  kernels/versatile/initrd-versatile.gz

The Kernel, Kernel module packages and initrd contain the name of
the platform.  The 'versatile' name is for the 'ARM Versatile development
board'.
In the future, expect to see more kernels and initrd's As Slackware ARM 
expands to support additional ARM devices.

The Kernels found in the 
  slackwarearm-<version>/kernels/<platform>/zImage-<platform>
  e.g. slackwarearm-14.0/kernels/versatile/zImage-versatile
are copies of those found in the Slackware Kernel package in the a/series:
  kernel_<platform>-<version>-arm-<build>.tgz package

In most other platforms, including the x86, the Kernel lives on a Linux
filesystem inside /boot.  Slackware ARM also provides a Kernel in this location,
but on most (if not all) ARM platforms, the Kernel file must reside outside of
the Linux filesystem:
  - usually on a FAT partition on a compact flash (Psion Netbook Pro)
  - on a RISC OS filesystem (Acorn RiscPC)
  - in a directory on your host Operating System (QEMU)

On some ARM platforms, their Linux boot loaders may support booting of a Kernel
from a Linux filesystem, but this is seldom the case.  Since Slackware ARM provides
a mostly modular Kernel, both a copy of the Kernel 'zImage-<platform>' and 
the 'initrd-<platform>' files must be copied to a location that is visible to
your platform's Linux boot loader.


4.  How do I build the initrd?

***
** Please read all of this section before following any of the steps.
**    

The easiest way to make the initrd is to use the mkinitrd script included 
in Slackware's mkinitrd package.  We'll walk through the process of 
upgrading to the Linux Kernel version 2.6.29.1 for the 'ARM Versatile'
platform, using the packages found in Slackware's slackware/a/ directory.

First, make sure the kernel, kernel modules, and mkinitrd package are 
installed (the current version numbers might be a little different, so 
this is just an example):

  upgradepkg --install-new  kernel_versatile-2.6.29.1-arm-1.tgz
  upgradepkg --install-new  kernel-modules-versatile-2.6.29.1_versatile-arm-1.tgz
  upgradepkg --install-new  mkinitrd-1.3.3-arm-1.tgz

Change into the /boot directory:

  cd /boot

A helper script is supplied with the "mkinitrd" package.  This script 
helps determine which modules to include in the new initrd.

  /usr/share/mkinitrd/mkinitrd_command_generator.sh

The script will output something like this:

mkinitrd -c -k 2.6.29.1-versatile -f ext4 -r /dev/sda2 \
         -m scsi_mod.ko.gz:sd_mod.ko.gz:cdrom.ko.gz:\
            sr_mod.ko.gz:crc16.ko.gz:jbd2.ko.gz:mbcache.ko.gz:ext4.ko.gz \
         -o /boot/initrd.gz
[line breaks added]

The important command operators above are:
  -f ext4  
              tell 'mount' inside the initrd to expect an 'ext4'
              formatted root filesystem.  I am using the 'ext4' filesystem
              on my machine.  the 'mkinitrd_command_generator.sh' script
              will determine the correct filesystem module for your system.
  -r /dev/sda2
              tell the initrd that the root filesystem is on the /dev/sda2
              device.
 
The rest of the colon separated names are of the Kernel modules required
to boot the Operating System.

Now run the command as specified by the script -- adding any additional
Kernel modules required.

This should do two things.  First, it will create a directory
/boot/initrd-tree containing the initrd's filesystem.  Then it will
create an initrd (/boot/initrd.gz) from this tree.  If you wanted to,
you could make some additional changes in /boot/initrd-tree/ and
then run mkinitrd again without options to rebuild the image.  That's
optional, though, and only advanced users will need to think about that.

If you are interested in the exact commands used to create the generic
Slackware ARM initrd images, please refer to the Kernel build script:
  slackwarearm-<version>/source/k/kernel.SlackBuild

There are a lot of useful comments in the build script.

***********************************************************************
         *****************************************************
         ** Note: mkinitrd_command_generator.sh limitations **
         *****************************************************
***********************************************************************

 In Slackware ARM version 12.2, the mkinitrd_command_generator.sh script doesn't
 determine all of the necessary Kernel modules to boot the system.
 Until this is resolved, it's best to create the initial RAM disk
 as follows - making any necessary adjustments to the kernel
 module list.
 The following example is taken from the 'source/k/kernel.SlackBuild'
 Kernel build script:

 You can paste in the following into the shell verbatim, but if you are using
 one of the supported systems for which Slackware ARM has a kernel, you should
 look at the 'source/k/kernel.SlackBuild' script as *this* document you are 
 now reading is not updated very often and will not keep track of the kernel
 package build script.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

   # Update the Kernel version
   VERSION=3.9.4

   # Update the architecture if necessary.
   # The Marvell SheevaPlug is part of the 'Kirkwood' family.
   # For the ARM 'Versatile' board, change it to 'versatile'.
   SLKARCH=kirkwood


For the Kirkwood platform
-------------------------

   # Generic requirements:
   # Filesystems:
   INITRDFS="vfat:jbd:jbd2:nls:exportfs:binfmt_misc:md:dm-mod:mbcache:ext2:ext3:ext4:reiserfs:jfs:xfs:fscache"
   # Generic SCSI drivers & low-level drivers for discs/media:
   INITRDSCSI="sg:scsi_mod:sd_mod:cdrom:sr_mod:scsi_tgt:mmc_block"
   # Network filesystems:
   INITRDNETFS="nfs:lockd:nfs_common"
   # USB hubs & support mods, including interface devices (USB keyboards etc)
   # followed by some specific device drivers.
   INITRDUSB="ehci-hcd:uhci_hcd:usbhid:ohci_hcd:hid:usbcore:usb-storage:ums-cypress:ums-usbat:ums-freecom:ums-isd200:ums-sddr09:ums-sddr55:ums-alauda:ums-jumpshot:ums-onetouch"
   # For SDHC cards:
   INITRDCARDS="mvsdio"

   # Additional stuff such as Netconsole
   # INITRDADDITIONS=":netconsole"

   # The two below are for the "Versatile" board.
   # Network interface cards:
   INITRDNETDEV="smc91x"

   # SCSI cards:
   INITRDSCSI="$INITRDSCSI:sym53c8xx"

   # These two are for the kirkwood systems:
   # Network interface cards:
   INITRDNETDEV="mv643xx_eth"

   # SATA support for the Kirkwood family:
   # Generic libata & Marvell's SATA driver.
   INITRDSATA="libata:sata_mv"

   # XGI video chipset used on OpenRD and probably other kirkwood devices:
   INITRDVIDEO="xgifb"

For the Tegra
-------------

   # Network interface cards:
   INITRDNETDEV="r8169" # this one needs a binary blob, which we'll build into the Kernel vmlinuz.

   # SATA support for the Kirkwood family:
   # Generic libata & Marvell's SATA driver.
   INITRDSATA="libata" # The Trimslice's SATA is on an internal USB host

   # MMC
   # INITRDMMC="sdhci-tegra" # For the Toshiba AC100

   # We'd also need "fbcon" if we choose not to compile it into the kernel.
   # The Trimslice uses the Tegra module which we need to compile into the Kernel.
   # INITRDVIDEO="xgifb"

   # Subsystems for System on Chip stuff:
   # (Some of these may not be required - I can most likely whittle them down later)
   INITRDSOC="i2c-tegra:rtc-em3027:spi-tegra"


   # Wait 6 seconds for the USB discs to spin up.  The SheevaPlug's
   # USB recognition can be a bit hit and miss, so it's best to
   # wait for longer than usual.
   mkinitrd \
      -R \
      -L \
      -u \
      -w 6 \
      -k $VERSION-$SLKARCH \
      -s /boot/initrd-tree \
      -m $INITRDVIDEO:$INITRDSCSI:$INITRDSATA:$INITRDUSB:$INITRDFS:$INITRDNETDEV:$INITRDNETFS:$INITRDCARDS${INITRDADDITIONS} \
      -o /boot/initrd-${SLKARCH}.gz

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

5.  Now that I've built an initrd, how do I use it?

Now that you've got an initrd (/boot/initrd.gz), you'll want to load
it along with the kernel at boot time. 

5.1  ARM devices that have an initrd residing out of the reach of Linux

     As already mentioned, the majority of ARM devices need the Kernel and
     initrd to be present _outside_ of your Linux filesystems.
     The best way to get them there depends entirely on your setup.

     Inside QEMU, if you followed the documentation in
     slackwarearm-<version>/QEMU_INSTALL.txt, you could do this:

     cd /boot
     scp initrd.gz root@yourQEMUhostos:/export/armhost/initrd-versatile.gz

     The file will then be in place ready to be booted when you next restart
     QEMU.

5.2  ARM devices that are capable of loading the initrd and Kernel from
     a Linux filesystem

     Some ARM devices such as the Marvell SheevaPlug use 'DAS U-Boot'
     which can load the Kernel and initrd from a 'FAT' or 'ext2' partition.

     In the case of the SheevaPlug, if you followed the Slackware ARM
     SheevaPlug installation document, 'INSTALL_SHEEVAPLUG.TXT' and setup an
     ext2 formatted /boot filesystem, then all that remains is to convert
     the standard gzipped initrd into a U-Boot formatted file.

     # Create a Das U-Boot formatted uInitrd from the standard initrd:
     cd /boot
     mkimage \
       -A arm \
       -O linux \
       -T ramdisk \
       -C gzip \
       -n "Slackware ARM initial RAM disk for the kirkwood platform" \
       -d /boot/initrd-kirkwood.gz \
       /boot/uinitrd-kirkwood

       In section 5.0  ('Booting the Slackware ARM OS') of 'INSTALL_SHEEVAPLUG.TXT'
       you set the name of the initial RAM disk to 'uinitrd-kirkwood'.
       If for any reason you chose another name during the setup process,
       or have changed it since, you will need to rename the initial RAM disk
       to match that configuration.


Other boot loaders vary - but if you've already got this far, you 
most likely know what to do with your initrd ;-)


---------

Have fun!
