内核在哪里定义SD卡命名索引?

内核在哪里定义SD卡命名索引?

我正在运行一个从 SDCard 启动的嵌入式板。 rootfs 的位置通过内核参数传递给内核:

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

我注意到更改为不同的内核版本会更改mmcblk1导致设备无法启动的索引。

内核是在没有 initramfs 的情况下构建的。

udevadm两个版本的输出:

内存块1

$ 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==""

内存块0

~# 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

我发现/etc/udev没有明确的规则来解决mmcblk.

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

命名似乎确实与设备树有关。使用相同的 zImage 更改不同的设备树会导致不同的索引。

问题

什么负责设置索引?是否有配置将其设置为不同的起始索引?

答案1

似乎是内核代码负责理解root=/dev/mmcblk0p2.

由于不initramfs存在,因此没有运行 udev 守护进程来命名设备,并且/dev/mmcblk1在任何地方都不存在。

然后内核以某种方式使用以下函数将该名称转换为负责的驱动程序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;
    }

参考来自讨论指出命名的变化可能是由设备树中的顺序引起的:

DT 文件中条目出现的顺序以及内核探测主机 SD 接口的顺序可能会引发设备顺序的更改。

答案2

不再保证内核中设备的顺序。正是由于这个原因,大多数发行版已经转而使用其他方式来确定根文件系统是什么。您可以执行以下操作之一:

  • 使用带标签的文件系统:

    tune2fs -L / /dev/mmcblkXpY
    

    (在安装文件系统时执行此操作是安全的)。现在启动root=LABEL=/

  • 使用 UUID:

    blkid /dev/mmcblkXpY
    

    ...会告诉您文件系统的 UUID 是什么。启动时用root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

相关内容