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 Removed legacy ARMv5 for Slackware ARM port by Stuart Winter, mozes@slackware.com Mon Sep 26 21:27:38 BST 2016 ================================================================================= This document describes how to create and install an initrd. 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 With Slackware 14.2 and earlier, ARMv5 and ARMv7 were supported and out of necessity there were at least _two_ Kernels. With Slackware 15.0 there is a single "armv7" Kernel that supports the officially supported devices. However, should we need additional Kernels in the future, we retain the original structure and naming conventions: For each platform that Slackware ARM supports, the following are provided: - 1 Kernel package in slackware/a/ e.g. kernel_armv7-4.7.4-arm-1.txz - 1 Kernel module package in slackware/a/ e.g. kernel-modules-armv7-4.7.4_armv7-arm-1.txz - 1 initrd in kernels//initrd- e.g. kernels/armv7/initrd-armv7 There are two formats of the same initrd - the "uinitrd" and "initrd". The "uinitrd" is for versions of U-Boot that are not capable of loading a standard "initrd". For officially supported devices, please refer to the installtion documentation to discover which version to use. The Kernel, Kernel module packages and initrd contain the name of the platform or architecture. In the example above, the 'armv7' name refers to the ARMv7 architecture which covers most supported devices. The Kernels found in the slackwarearm-/kernels//zImage- e.g. slackwarearm-15.0/kernels/armv7/zImage-armv7 Again as with the initrd, there are also "uImage" versions of these. are copies of those found in the Slackware Kernel package in the a/series: kernel_--arm-.txz 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. For the officially supported devices, /boot is generally either an ext2 formatted partition (since most U-Boot versions can read ext2) or is a directory within the root file system. On some devices and using QEMU you'd need to have the Kernel and initial RAM disk accessible outside of Linux. Please refer to the documentation for such systems. 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 for the 'ARM v7' 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-modules-armv7-4.7.4_armv7-arm-1.txz upgradepkg --install-new kernel_armv7-4.7.4-arm-1.txz upgradepkg --install-new mkinitrd-1.4.8-arm-3.txz 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 4.7.4-armv7 -f ext4 -r /dev/sda2 -m mmc_core.ko.gz:sunxi-mmc.ko.gz:scsi_mod.ko.gz:libata.ko.gz:libahci.ko.gz: libahci_platform.ko.gz:ahci_sunxi.ko.gz:mbcache.ko.gz:jbd2.ko.gz:ext4.ko.gz -u -o /boot/initrd.gz [line breaks and indentation 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 15.0, 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=4.4.7 # Update the architecture if necessary. SLKARCH=armv7 # Network interface cards: # Versatile Express has SMSC911 # Trimslice: Realtek 8169 (needs a firmware blob which is handled by the a/kernel-firmware package) # Banana Pi/stmmac - ST Microelectronics INITRDNETDEV="smsc911x:r8169:stmmac" # Generic libata: # The Compulab Trimslice's SATA is on an internal USB host INITRDSATA="libata" # Subsystems for System on Chip stuff: # (Some of these may not be required - I can most likely whittle them down later) INITRDSOC="i2c-tegra:spi-tegra:phy-tegra-usb:ehci_tegra:dwmac-sunxi:sunxi-mmc:ahci_sunxi" # Real Time Clock: # Trimslice: rtc-em3027 # BananaPi: rtc-sunxi # Versatile Express: rtc-pl031 INITRDRTC="rtc-em3027:rtc-sunxi:rtc-pl031:rtc-ds1307" # Wait 2 seconds for the media to become available: mkinitrd \ -R \ -L \ -u \ -w 2 \ -k $VERSION-$SLKARCH \ -s /boot/initrd-tree \ -m $INITRDEXPLICITS:$INITRDSOC:$INITRDVIDEO:$INITRDSCSI:$INITRDSATA:$INITRDUSB:$INITRDFS:$INITRDNETDEV:$INITRDNETFS:$INITRDCARDS${INITRDADDITIONS}:$INITRDRTC:$INITRDNAND \ -o /boot/initrd-$SLKARCH >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5. Now that I've built an initrd, how do I use it? Now that you've got an initrd (/boot/initrd-), 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 officially supported ARM devices enable initrd to be present _within_ your Linux filesystems. If you are using such a supported system, skip to section 5.2 However if you are not then you may need to copy the initrd outside of Linux. For example, 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 The officially supported devices can load either a standard Kernel and initrd, or at least the U-Boot formatted version (hence why we supply both). In the case of the the Trimslice, if you followed the Slackware ARM installation document, 'INSTALL_TRIMSLICE.TXT' and setup an ext3 formatted "/" 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 Trimslice" \ -d /boot/initrd-armv7 \ /boot/uinitrd-armv7 In section 5.0 ('Booting the Slackware ARM OS') of 'INSTALL_TRIMSLICE.TXT' you set the name of the initial RAM disk to 'uinitrd-armv7'. 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!