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//initrd-.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-/kernels//zImage- e.g. slackwarearm-14.0/kernels/versatile/zImage-versatile are copies of those found in the Slackware Kernel package in the a/series: kernel_--arm-.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-' and the 'initrd-' 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-/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 and uses the # Slackware ARMv5 generic Kernel. # For ARMv7 systems, change the settings accordingly. SLKARCH=armv5 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-/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_KIRKWOOD.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 armv5 platform" \ -d /boot/initrd-armv5.gz \ /boot/uinitrd-armv5 In section 5.0 ('Booting the Slackware ARM OS') of 'INSTALL_SHEEVAPLUG.TXT' you set the name of the initial RAM disk to 'uinitrd-armv5'. 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!