root equals what?

Published on November 23, 2014

Archived Notice

This article has been archived and may contain broken links, photos and out-of-date information. If you have any questions, please Contact Us.

The upcoming 3.10.31 release of the Linux kernel for our i.MX6 boards will be introducing a slight incompatibility regarding the naming of SD card devices. Because of this, the root= clause in the kernel command line will need to change, and some background information is in order.

How it was broken

In 3.10.17 and earlier kernels, SD card devices were named /dev/mmcblk0.../dev/mmcblk2 in the order in which they are enumerated, which conceals a flaw in many of our boot scripts:

Our default U-Boot command line iterates through each SD card, looking for 6x_bootscript. This allows you to have a bootable SD in either slot on our Nitrogen6x, Nitrogen6_Max, or BD-SL-i.MX6 (SABRE Lite) boards.

U-Boot's number is used to load the kernel and Device Tree Blob, but we always assumed /dev/mmcblk0 when crafting the root= clause of the kernel command line (the bootargs variable in U-Boot).

Because of this, things would not function properly if you had both SD cards populated, but had your boot script in mmc 1 as defined by U-Boot.

How this is fixed in new kernels

The new kernel does a much more reasonable thing: it defines the mmcblkN numbering based on the SDIO bus number, which maps completely and directly to the SD card numbering in U-Boot.

Fortunately, all three of the boards above have the same mapping:

U-Boot Kernel SABRE Lite Nitrogen6X Nitrogen6_Max
mmc 0 /dev/mmcblk3 Full-sized slot Top micro SD slot removable SD
mmc 1 /dev/mmcblk4 micro SD slot Bottom micro SD slot eMMC

How we'll handle the transition

The 3.10.31 kernel is still in Beta though, and it will take a while before everybody is up and running on the new kernel.

Because of this, we've introduced a new sdphys variable in our boot scripts that will choose between the two numbering schemes.

Take a look at this new if statement. If it sees that the sdphys variable is an empty string, it will assume /dev/mmcblk0 is the root device. If not, it will map the U-Boot SD card number (${disk}) to a corresponding mmcblkN.

Since none of our U-Boot images have this variable defined, the immediate effect is nothing. Once the 3.10.31 kernel is in widespread use, we'll update the U-Boot default to have this set.

In the mean-time, if you're testing either the 3.10.31-beta kernel or a main-line Linux kernel, you can use this bit of script to properly map your boot device by

U-Boot > setenv sdphys 1U-Boot > saveenvU-Boot > boot

For images that support RAM disks

Images that boot via RAM disks, including our Ubuntu images (Trusty and later), there's a better way.

The /dev/disk/by-path is generally defined by udev to provide a mapping of drives by their SDIO bus, and these can be used on either the older or newer kernels without the test. The trick here is that the first-level boot is to a RAM disk that doesn't even look at the root= clause and that clause is interpreted after udev populates the /dev/disk/by-path and /dev/disk/by-label directories.

What about Android?

Android also boots via RAM disk and uses the equivalent of /dev/disk/by-path, so Android users can ignore this post.Test