红联Linux门户
Linux帮助

(cmdline)uboot传递给内核的root设备序号动态变化导致启动失败

发布时间:2017-02-17 09:28:03来源:linux网站作者:w8u
现象
板子上插入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设备的时候,序号固定,可参考如下方法:
(cmdline)uboot传递给内核的root设备序号动态变化导致启动失败
 
本文永久更新地址:http://www.linuxdiyf.com/linux/28470.html