NSLU2-Linux
view · edit · print · history

Debian.NoInitramfs History

Hide minor edits - Show changes to markup

September 15, 2007, at 12:24 PM by Phil Endecott -- typo
Changed lines 11-12 from:
  1. You need to make the kernel will wait for your USB device to come online before mounting it.
to:
  1. You need to make the kernel wait for your USB device to come online before mounting it.
December 10, 2006, at 05:20 PM by Phil Endecott -- Mention rootdelay command-line argument
Changed lines 9-12 from:

To get rid of the initramfs there are three things that you need to do:

  1. You need to apply a small kernel patch so that the kernel will wait for your USB devices to come online.
to:

To get rid of the initramfs there are two or three things that you need to do:

  1. You need to make the kernel will wait for your USB device to come online before mounting it.
Changed lines 15-21 from:
  1. You need to set a kernel command line indicating which device to use as the root.

Kernel Patch

When you plug in a USB device, some time elapses while the USB and SCSI subsystems initialise it. I think that most of this time is a deliberate delay to allow for you physically connecting it reliably. Because of this, during boot the kernel is likely to give up with a panic telling you that your root device is not available before it has been initialised. A simple patch is required to make the kernel retry until the device comes online. It is available here: http://www.xenotime.net/linux/usb/usbboot-2422.patch

to:
  1. You may need to set a kernel command line indicating which device to use as the root.

Waiting for USB

When you plug in a USB device, some time elapses while the USB and SCSI subsystems initialise it. I think that most of this time is a deliberate delay to allow for you physically connecting it reliably. Because of this, during boot the kernel is likely to give up with a panic telling you that your root device is not available before it has been initialised.

There are two ways to avoid this. The simplest it to use the rootdelay kernel command line argument, which specifies how long the kernel should pause for, in seconds, before trying to mount the root device. See ChangeKernelCommandLine for how to set this.

Alternatively, a simple patch can be applied to make the kernel retry until the device comes online. It is available here: http://www.xenotime.net/linux/usb/usbboot-2422.patch

Changed lines 36-37 from:

You need to specify the root device on the kernel command line. However, the kernel will attempt to convert an alphanumeric device name (e.g. /dev/sda1) to major/minor device numbers before the USB and SCSI systems are ready, which will fail. Instead you need to use a numeric format, e.g. root=8:1. (use ls -l to find the major/minor device numbers for your root device.) You may be able to supply this as a default command line setting when you build your kernel, but I prefered to set it using APEX. Changing the kernel command line from APEX is described in ChangeKernelCommandLine.

to:

If you use the patch described above to retry until the root device is available you need to specify the root device on the kernel command line. However, the kernel will attempt to convert an alphanumeric device name (e.g. /dev/sda1) to major/minor device numbers before the USB and SCSI systems are ready, which will fail. Instead you need to use a numeric format, e.g. root=8:1. (use ls -l to find the major/minor device numbers for your root device.) You may be able to supply this as a default command line setting when you build your kernel, but I prefered to set it using APEX. Changing the kernel command line from APEX is described in ChangeKernelCommandLine.

Changed lines 40-42 from:
to:

I'm unsure whether it's necessary to explicitly specify the root device if you use the rootdelay option, and whether it's necessary to use numeric device numbers - can someone confirm?

December 08, 2006, at 04:43 PM by Phil Endecott -- Create this page
Added lines 1-46:

How to run Debian / NSLU2 with no Initramfs

The internal flash in a normal Debian / NSLU2 system contains a kernel and an "initramfs". The initramfs is a directory structure containing files that are run as soon as the kernel has started; this is called "early userspace". This code is responsible for mounting the real root filesystem, located on an external USB drive.

The benefit of using an initramfs is that the kernel does not need to have built-in support for all of the different hardware and filesystems that you might be using for your root. (Consider, for example, all the kernel code required to mount an NFS root.) Instead, the initramfs contains kernel modules for all of this hardware, and only the necessary modules are loaded. This results in a kernel that uses less RAM.

For a distribution like Debian, having a kernel image that supports lots of different root filesystem hardware is important. But if you compile your own kernel to run on hardware that isn't likely to change much, it could be considered overkill. My motivation for removing the initramfs is to free some space in the internal flash: the Debian initramfs image is over 3 megabytes!

To get rid of the initramfs there are three things that you need to do:

  1. You need to apply a small kernel patch so that the kernel will wait for your USB devices to come online.
  2. You need to build a kernel with built-in support for the hardware and filesystem used by your root device.
  3. You need to set a kernel command line indicating which device to use as the root.

Kernel Patch

When you plug in a USB device, some time elapses while the USB and SCSI subsystems initialise it. I think that most of this time is a deliberate delay to allow for you physically connecting it reliably. Because of this, during boot the kernel is likely to give up with a panic telling you that your root device is not available before it has been initialised. A simple patch is required to make the kernel retry until the device comes online. It is available here: http://www.xenotime.net/linux/usb/usbboot-2422.patch

This patch was written for 2.4.22. I manually applied it to my 2.6.19 kernel and it works well, subject to the comments below about how you specify the root device.

Building a kernel

I'm not going to explain how to build a kernel here - mainly because I haven't got cross compilation using the Debian make-kpkg tool working properly. See BuildImage for some other instructions. The important point is that when you configure the kernel you need to enable all of the things that are required by your root filesystem as built-in code, i.e. press "y", not modules ("m"). This includes PCI support, the EHCI and OHCI USB host controller, USB storage, SCSI disks, and your chosen filesystem (ext3). Also, don't forget to disable initramfs support.

Specifying the root device

You need to specify the root device on the kernel command line. However, the kernel will attempt to convert an alphanumeric device name (e.g. /dev/sda1) to major/minor device numbers before the USB and SCSI systems are ready, which will fail. Instead you need to use a numeric format, e.g. root=8:1. (use ls -l to find the major/minor device numbers for your root device.) You may be able to supply this as a default command line setting when you build your kernel, but I prefered to set it using APEX. Changing the kernel command line from APEX is described in ChangeKernelCommandLine.

Note that this is likely to fail if you have multiple disks since the order of initialisation is non-deterministic. Mounting by disk label is not supported at this level, though it may be possible with some more patching. Luckily I have only one disk on the slug I'm doing this to.

Installing the new kernel

Before installing the new kernel (and new APEX, if you've changed it), save a copy of your flash. You can revert to this using upslug2 if necessary.

# cat /dev/mtdblock* > /var/tmp/flash_backup.bin
# scp /var/tmp/flash_backup.bin other-computer:/somewhere/safe

I haven't managed to make a kernel-image .deb file, so I don't know if installing that will just work. Instead I manually installed the new modules and put the new kernel in /boot/vmlinux-2.6.19. To keep flash-kernel happy I created a zero-length /boot/initrd.img.2.6.19. Then just run "flash-kernel", reboot and cross your fingers!

view · edit · print · history · Last edited by Phil Endecott.
Originally by Phil Endecott.
Page last modified on September 15, 2007, at 12:24 PM