3

I'm running an embedded board that is booted from an SDCard. The location of the rootfs gets passed to the kernel via kernel parameters:

Kernel command line: console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10

I've noticed that changing to a different kernel version changes the index to mmcblk1 which causes the device to not boot.

The kernel is built without a initramfs.

The output of udevadm for the two versions:

mmcblk1

$ udevadm info --name=/dev/mmcblk1 --attribute-walk
  looking at device '/devices/platform/soc/1c0f000.mmc/mmc_host/mmc1/mmc1:0001/block/mmcblk1':
    KERNEL=="mmcblk1"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{alignment_offset}=="0"
    ATTR{capability}=="50"
    ATTR{discard_alignment}=="0"
    ATTR{ext_range}=="256"
    ATTR{force_ro}=="0"
    ATTR{inflight}=="       0        0"
    ATTR{range}=="8"
    ATTR{removable}=="0"
    ATTR{ro}=="0"
    ATTR{size}=="7716864"
    ATTR{stat}=="    2203     1698   122077    22625      654      554    26088     8770        0    12855    31530"

  looking at parent device '/devices/platform/soc/1c0f000.mmc/mmc_host/mmc1/mmc1:0001':
    KERNELS=="mmc1:0001"
    SUBSYSTEMS=="mmc"
    DRIVERS=="mmcblk"
    ATTRS{cid}=="9f544930303030300000000201011a3b"
    ATTRS{csd}=="400e00325b5900001d6f7f800a4000a1"
    ATTRS{date}=="10/2017"
    ATTRS{dsr}=="0x404"
    ATTRS{erase_size}=="512"
    ATTRS{fwrev}=="0x0"
    ATTRS{hwrev}=="0x0"
    ATTRS{manfid}=="0x00009f"
    ATTRS{name}=="00000"
    ATTRS{ocr}=="00200000"
    ATTRS{oemid}=="0x5449"
    ATTRS{preferred_erase_size}=="4194304"
    ATTRS{scr}=="02b5800000000000"
    ATTRS{serial}=="0x00000201"
    ATTRS{ssr}=="000000000200000004049000080a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    ATTRS{type}=="SD"

  looking at parent device '/devices/platform/soc/1c0f000.mmc/mmc_host/mmc1':
    KERNELS=="mmc1"
    SUBSYSTEMS=="mmc_host"
    DRIVERS==""

mmcblk0

~# udevadm info --name=/dev/mmcblk0 --attribute-walk
  looking at device '/devices/platform/soc/1c0f000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0':
    KERNEL=="mmcblk0"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{alignment_offset}=="0"
    ATTR{capability}=="50"
    ATTR{discard_alignment}=="0"
    ATTR{ext_range}=="256"
    ATTR{force_ro}=="0"
    ATTR{inflight}=="       0        0"
    ATTR{range}=="8"
    ATTR{removable}=="0"
    ATTR{ro}=="0"
    ATTR{size}=="7716864"
    ATTR{stat}=="    2156     1248   105313    35020       85      263      952     1530        0     8180    36530"

  looking at parent device '/devices/platform/soc/1c0f000.mmc/mmc_host/mmc0/mmc0:0001':
    KERNELS=="mmc0:0001"
    SUBSYSTEMS=="mmc"
    DRIVERS=="mmcblk"
    ATTRS{cid}=="9f5449303030303000000003ba011a5d"
    ATTRS{csd}=="400e00325b5900001d6f7f800a4000a1"
    ATTRS{date}=="10/2017"
    ATTRS{dsr}=="0x404"
    ATTRS{erase_size}=="512"
    ATTRS{fwrev}=="0x0"
    ATTRS{hwrev}=="0x0"
    ATTRS{manfid}=="0x00009f"
    ATTRS{name}=="00000"
    ATTRS{ocr}=="00200000"
    ATTRS{oemid}=="0x5449"
    ATTRS{preferred_erase_size}=="4194304"
    ATTRS{scr}=="02b5800000000000"
    ATTRS{serial}=="0x000003ba"
    ATTRS{ssr}=="000000000200000004049000080a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    ATTRS{type}=="SD"

  looking at parent device '/devices/platform/soc/1c0f000.mmc/mmc_host/mmc0':
    KERNELS=="mmc0"
    SUBSYSTEMS=="mmc_host"
    DRIVERS==""

~# udevadm info --query=property --name=/dev/mmcblk0
    DEVLINKS=/dev/disk/by-id/mmc-00000_0x000003ba /dev/disk/by-path/platform-1c0f000.mmc
    DEVNAME=/dev/mmcblk0
    DEVPATH=/devices/platform/soc/1c0f000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0
    DEVTYPE=disk
    ID_NAME=00000
    ID_PART_TABLE_TYPE=dos
    ID_PART_TABLE_UUID=27e953fe
    ID_PATH=platform-1c0f000.mmc
    ID_PATH_TAG=platform-1c0f000_mmc
    ID_SERIAL=0x000003ba
    MAJOR=179
    MINOR=0
    SUBSYSTEM=block
    TAGS=:systemd:
    USEC_INITIALIZED=4723799

Looking at /etc/udev I found no explicit rules that are addressing the naming for the mmcblk.

# tree /etc/udev
/etc/udev
├── hwdb.bin
├── hwdb.d
├── rules.d
└── udev.conf

The naming does seem to be related to the device tree. Changing different device trees with the same zImage results in different indexes.

Question

What is responsible for setting the index and is there a config to set it to a different starting index?

4

This seems to be the kernel code responsible for making sense of root=/dev/mmcblk0p2.

Given that no initramfs is present, there is no udev daemon running to name the devices and /dev/mmcblk1 doesn't really exist yet anywhere.

The kernel then somehow converts that name into the responsible driver with the function dev_t name_to_dev_t(const char *name):

    ...
    if (strncmp(name, "/dev/", 5) != 0) {
        unsigned maj, min, offset;
        char dummy;

        if ((sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2) ||
            (sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3)) {
            res = MKDEV(maj, min);
            if (maj != MAJOR(res) || min != MINOR(res))
                goto fail;
        } else {
            res = new_decode_dev(simple_strtoul(name, &p, 16));
            if (*p)
                goto fail;
        }
        goto done;
    }

A reference from a lkml discussion points that the changes in the naming could be caused by the ordering in the device tree:

Changes in device ordering can be provoked by the order in which entries in the DT file appear, and hence the order in which the host SD interfaces are probed by the kernel.

1

Ordering of devices in the kernel is not guaranteed anymore. It's for this reason that most distributions have switched to other ways of figuring out what the root filesystem is. You can do one of the following:

  • Use a labeled filesystem:

    tune2fs -L / /dev/mmcblkXpY
    

    (it's safe to do this while the filesystem is mounted). Now boot with root=LABEL=/

  • Use a UUID:

    blkid /dev/mmcblkXpY
    

    ... will tell you what the UUID of your filesystem is. Boot with root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

  • Ok, but this all seems to assume a system that booted up. In my case it's about what device to pass as the kernel parameter to the kernel. – TheMeaningfulEngineer Aug 2 '18 at 17:40
  • @TheMeaningfulEngineer - your problem is the lack of initramfs - that's why you can't boot the way Wouter suggests... – don_crissti Aug 2 '18 at 20:44
  • We are talking about embedded devices here, so there is no need to complicate the boot process. – RalfFriedl Aug 6 '18 at 6:14
  • @RalfFriedl -- you are mistaken. The kernel doesn't guarantee device ordering. It makes much more sense to use a root device name that does not assume any particular ordering than to use a device name that does. LABEL=/ is extremely easy to use, and also doesn't depend on a particular UUID being in use; I prefer using that on the embedded devices that I use over anything else. – Wouter Verhelst Aug 11 '18 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.