现象
板子上插入SD卡启动Linux系统后,emmc的设备名称是/dev/mmcblck1;板子上没有插入SD卡,Linux启动后,emmc的设备名称是/dev/mmcblck0.
uboot传递给内核的cmdline参数bootargs 中root=/dev/mmcblck0p14,这个配置在没有插SD卡的时候工作正常,但是插入SD卡后,就无法正常启动Linux系统,因为无法找到root设备。
思考解决方案
要么改内核,使得emmc的设备名称固定;要么改bootargs,使root不依赖设备名称。
过程
先查找内核文档cmdline中root说明,https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt
文档说查看“init/do_mounts.c” 中关于name_to_dev_t的注释。
root= [KNL] Root filesystem
See name_to_dev_t comment in init/do_mounts.c.
rootdelay= [KNL] Delay (in seconds) to pause before attempting to
mount the root filesystem
rootflags= [KNL] Set root filesystem mount option string
rootfstype= [KNL] Set root filesystem type
rootwait [KNL] Wait (indefinitely) for root device to show up.
Useful for devices that are detected asynchronously
(e.g. USB and MMC devices).
Cross Reference: /init/do_mounts.c http://androidxref.com/kernel_3.18/xref/init/do_mounts.c
183 * Convert a name into device number. We accept the following variants:
184 *
185 * 1) <hex_major><hex_minor> device number in hexadecimal represents itself
186 * no leading 0x, for example b302.
187 * 2) /dev/nfs represents Root_NFS (0xff)
188 * 3) /dev/<disk_name> represents the device number of disk
189 * 4) /dev/<disk_name><decimal> represents the device number
190 * of partition - device number of disk plus the partition number
191 * 5) /dev/<disk_name>p<decimal> - same as the above, that form is
192 * used when disk name of partitioned disk ends on a digit.
193 * 6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the
194 * unique id of a partition if the partition table provides it.
195 * The UUID may be either an EFI/GPT UUID, or refer to an MSDOS
196 * partition using the format SSSSSSSS-PP, where SSSSSSSS is a zero-
197 * filled hex representation of the 32-bit "NT disk signature", and PP
198 * is a zero-filled hex representation of the 1-based partition number.
199 * 7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
200 * a partition with a known unique id.
201 * 8) <major>:<minor> major and minor number of the device separated by
202 * a colon.
203 *
204 * If name doesn't have fall into the categories above, we return (0,0).
205 * block_class is used to check if something is a disk name. If the disk
206 * name contains slashes, the device name has them replaced with
207 * bangs.
208 */
209
210dev_t name_to_dev_t(char *name)
尝试
尝试使用<hex_major><hex_minor> device number方式。插SD卡和不插SD卡进入系统后,分别查看mmcblck0p14的设备号对应什么。
插入SD卡的情况
root@ARTiGO-A820:/dev/block # ls -l mmc*
brw------- root root 179, 8 1970-01-02 07:06 mmcblk0
brw------- root root 179, 16 1970-01-02 07:06 mmcblk0boot0
brw------- root root 179, 24 1970-01-02 07:06 mmcblk0boot1
brw------- root root 179, 9 1970-01-02 07:06 mmcblk0p1
brw------- root root 179, 10 1970-01-02 07:06 mmcblk0p2
brw------- root root 179, 11 1970-01-02 07:06 mmcblk0p3
brw------- root root 179, 12 1970-01-02 07:06 mmcblk0p4
brw------- root root 179, 13 1970-01-02 07:06 mmcblk0p5
brw------- root root 179, 14 1970-01-02 07:06 mmcblk0p6
brw------- root root 179, 15 1970-01-02 07:06 mmcblk0p7
brw------- root root 259, 0 1970-01-02 07:06 mmcblk0p8
brw------- root root 259, 1 1970-01-02 07:06 mmcblk0p9
brw------- root root 179, 32 1970-01-02 07:06 mmcblk0rpmb
brw------- root root 179, 0 1970-01-02 07:06 mmcblk1
brw------- root root 179, 1 1970-01-02 07:06 mmcblk1p1
未插入SD卡时候的情况
root@ARTiGO-A820:/dev/block # ls -l mmc*
brw------- root root 179, 0 1970-01-02 07:16 mmcblk0
brw------- root root 179, 8 1970-01-02 07:16 mmcblk0boot0
brw------- root root 179, 16 1970-01-02 07:16 mmcblk0boot1
brw------- root root 179, 1 1970-01-02 07:16 mmcblk0p1
brw------- root root 179, 2 1970-01-02 07:16 mmcblk0p2
brw------- root root 179, 3 1970-01-02 07:16 mmcblk0p3
brw------- root root 179, 4 1970-01-02 07:16 mmcblk0p4
brw------- root root 179, 5 1970-01-02 07:16 mmcblk0p5
brw------- root root 179, 6 1970-01-02 07:16 mmcblk0p6
brw------- root root 179, 7 1970-01-02 07:16 mmcblk0p7
brw------- root root 259, 0 1970-01-02 07:16 mmcblk0p8
brw------- root root 259, 1 1970-01-02 07:16 mmcblk0p9
brw------- root root 179, 24 1970-01-02 07:16 mmcblk0rpmb
可以看到,同样地分区,major和minor并不固定。当然有些是固定的,比如p8,p9.
碰巧我们使用的分区在两种情况下Major和Minor是固定没有变化的。所以我们设置bootargs root=259:1,然后成功两种情况下都启动了。
附录
如果以上方法不行,则后备方法是修改内核,使得枚举emmc设备的时候,序号固定,可参考如下方法: