一.背景
文件系统安装在sd卡的第一个分区中,使用的是ext4文件系统,linux内核版本为4.14
二.思考
在内核启动之前,uboot给内核传递了参数root=/dev/mmcblk0p1,但是为何还会出现:
VFS: Cannot open root device "mmcblk0p1" or unknown-block(179,1): error -19
Please append a correct "root=" boot option; here are the available partitions:
三.扒一扒内核代码
init/do_mouts.c
void __init mount_block_root(char *name, int flags)
{
... retry:
for (p = fs_names; *p; p += strlen(p)+1) {
int err = do_mount_root(name, p, flags, root_mount_data);
switch (err) {
case 0:
goto out;
case -EACCES:
case -EINVAL:
continue;
}
/*
* Allow the user to distinguish between failed sys_open
* and bad superblock on root device.
* and give them a list of the available devices
*/
#ifdef CONFIG_BLOCK
__bdevname(ROOT_DEV, b);
#endif
printk("VFS: Cannot open root device "%s" or %s: error %d
",
root_device_name, b, err); 此处的打印信息被输出
printk("Please append a correct "root=" boot option; here are the available partitions:
");此处的打印信息被输出
printk_all_partitions();
#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify "
"explicit textual name for "root=" boot option.
");
#endif
panic("VFS: Unable to mount root fs on %s", b); 发生panic的地方在这里
...
}
static int __init do_mount_root(char *name, char *fs, int flags, void *data)
{
struct super_block *s;
int err = sys_mount(name, "/root", fs, flags, data); 此处返回的err是我们需要关心的,这里的err=-19,那么为何会等于-19呢?
if (err)
return err;
sys_chdir("/root");
s = current->fs->pwd.dentry->d_sb;
ROOT_DEV = s->s_dev;
printk(KERN_INFO
"VFS: Mounted root (%s filesystem)%s on device %u:%u.
",
s->s_type->name,
sb_rdonly(s) ? " readonly" : "",
MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
return 0;
}
再分析sys_mount
fs/namespace.c
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,char __user *, type, unsigned long, flags, void __user *, data)
{
...
ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
...
}
long do_mount(const char *dev_name, const char __user *dir_name,const char *type_page, unsigned long flags, void *data_page)
{
...
retval = do_new_mount(&path, type_page, sb_flags, mnt_flags,dev_name, data_page);
...
}
/* * create a new mount for userspace and request it to be added into the
* namespace's tree
*/
static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
int mnt_flags, const char *name, void *data)
{
...
type = get_fs_type(fstype);
if (!type)
return -ENODEV;
...
}
-ENODEV=-19
从最后的get_fs_type可以得知:当前不支持某种文件系统,进而type等于非0,因此就会返回-19这个值
四.解决
当前sd卡上的第一个分区装入的文件系统为ext4,然而内核此时并不支持此文件系统,因此加入CONFIG_EXT4_FS的配置项重新编译内核即可