Booting Arch Linux ARM (ALARM) on Pogoplug V2 is straightforward, as long as we have only attached the USB drive/stick where ALARM is installed. But if we have any additional USB drives attached to Pogoplug, we face troubles booting ALARM.
An easy workaround is to detach any USB drives but the ALARM USB until booting, then attaching other USB drives. But that means that Pogoplug can’t boot automatically if there is a power outage or something, until we manually do this workaround.
The problem happens because uBoot (the boot loader) may identify the attached USB drives in a different order than the linux kernel may do. Let’s give an example for such scenario:
- Say we have attached two USB drives, one has ALARM, and the other is just a storage drive.
- During the boot process, uBoot may identify the storage drive as the first USB drive (/dev/sda), and the ALARM drive as second USB drive (/dev/sdb).
- uBoot finds the kernel (/boot/uImage) on the first partition of the ALARM drive (/dev/sdb1). So it passes (/dev/sdb1) to the kernel as the root filesystem.
- The kernel may have detected the ALARM drive as the first USB drive (/dev/sda), while it expects the root filesystem on /dev/sdb1, which is the storage drive not the ALARM drive!
If the kernel detects the attached USB disks in the same order as uBoot, there will be no problem. But most of the time the order is different, and the boot process fails when more than one USB drive is attached.
For a stable and expected boot process, we need some other way to identify disks, rather than the generic dynamic (/dev/sdx) notation.
The technique is explained in the following thread, which is about Debian, but the concept can apply to any linux kernel:
We can summarize the technique in the following steps:
- Give a distinct label to the partition containing the root filesystem.
- Modify the uBoot environment parameters to pass that label to the linux kernel.
- The linux kernel searches through all detected partitioned until it find the one with the correct label, which then mounts as the root filesystem and continue the booting process.
Let’s address the steps one by one, and make the necessary configurations to implement each of them.
1- Give Distinct Label to The Partition Containing Root Filesystem
To avoid any confusion, let’s boot Pogoplug with only the ALARM USB attached. When booting completes, we SSH to ALARM as root user and run the following command, which sets the label of the first partition (root filesystem) to ROOTFS:
[root@alarm ~]# e2label /dev/sda1 ROOTFS
2- Modify uBoot Environment Parameters to Pass ROOTFS Label to The Kernel
Given that we haven’t modifies the default uBoot environment parameters, we just need to make a minor change. First we check usb_init parameter which should read as below:
[root@alarm ~]# /usr/sbin/fw_printenv usb_init usb_init=run usb_scan
We run the following command to modify the usb_init parameter to pass the ROOTFS label after completing the USB scan:
[root@alarm ~]# /usr/sbin/fw_setenv usb_init "run usb_scan; setenv usb_root LABEL=ROOTFS"
3- The Linux Kernel to Search For the ROOTFS Partition
For the Linux Kernel to be able to search through the attached USB drives, and to find the partition with the label specified, the Linux Kernel has to mount a temporary root filesystem, which has the necessary drivers the kernel needs to be able to identify disk labels. Such initial temporary root filesystem is called the Initial Ram Disk, which is a compressed ram image file (called uInitrd), that’s uncompressed and loaded into memory during the boot process by uBoot.
By default, ALARM has no initial ramdisk file, and hence we need to create it for this technique to work. I’ve found helpful steps for creating a ramdisk in the following thread:
In summary, we can simply create the initial ramdisk with the following commands:
[root@alarm etc]# mkinitcpio -v -g /boot/kernel.img [root@alarm etc]# mkimage -A arm -O linux -T ramdisk -C gzip -a 0x00000000 -e 0x00000000 -n initramfs -d /boot/kernel.img /boot/uInitrd
if “mkimage” utility is not installed, then you can install it using the following command:
[root@alarm etc]# pacman -Sy uboot-mkimage
Now after creating the initial ramdisk (uInitrd) file, the technique described in this post should word smoothly, and we can boot ALARM on Pogoplug regardless of any other connected USB drives.