root=/dev/mmcblk0p2根文件系统挂载

  • Post author:
  • Post category:其他


linux挂载跟文件系统,一般通过ramdisk方式。如果没有使用ramdisk方式,而是使用磁盘上分区文件系统,那么在prepare_namespace中进行。

static noinline void __init kernel_init_freeable(void)
{
	/*
	 * Wait until kthreadd is all set-up.
	 */
	wait_for_completion(&kthreadd_done);

	/* Now the scheduler is fully set up and can do blocking allocations */
	gfp_allowed_mask = __GFP_BITS_MASK;

	/*
	 * init can allocate pages on any node
	 */
	set_mems_allowed(node_states[N_MEMORY]);
	/*
	 * init can run on any cpu.
	 */
	set_cpus_allowed_ptr(current, cpu_all_mask);

	cad_pid = task_pid(current);

	smp_prepare_cpus(setup_max_cpus);

	do_pre_smp_initcalls();
	lockup_detector_init();

	smp_init();
	sched_init_smp();

	do_basic_setup();

	/* Open the /dev/console on the rootfs, this should never fail */
	if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
		pr_err("Warning: unable to open an initial console.\n");

	(void) sys_dup(0);
	(void) sys_dup(0);
	/*
	 * check if there is an early userspace init.  If yes, let it do all
	 * the work
	 */

	if (!ramdisk_execute_command)   //启动参数bootargs中没有指定init进程,那么采用默认的/init
		ramdisk_execute_command = "/init";

	//搜索当前系统中是否有/init,如果前面已经挂载了ramdisk,就会存在/init
	//ramdisk由uboot搬移到内存中,并传递给kernel,所以ramdisk可以很早就进行加载
	//当实际物理设备上的根分区需要 驱动都初始化好后才能加载,所以这里是等待驱动加载完成后,才prepare_namespace挂载文件系统
	if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
		ramdisk_execute_command = NULL;
		prepare_namespace();
	}

	/*
	 * Ok, we have completed the initial bootup, and
	 * we're essentially up and running. Get rid of the
	 * initmem segments and start the user-mode stuff..
	 */

	/* rootfs is available now, try loading default modules */
	load_default_modules();
}

比如bootargs中 参数: root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait

表示跟分区在mmcblk0p2 ,文件系统类型为ext4,挂载点为/dev/root(默认)

由于前面设备驱动已经加载好,所以能够找到mmcblk0p2

static int __init root_dev_setup(char *line)
{
	strlcpy(saved_root_name, line, sizeof(saved_root_name));
	return 1;
}

__setup("root=", root_dev_setup);
/*
 * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
 */
void __init prepare_namespace(void)
{
	int is_floppy;

	if (root_delay) {
		printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
		       root_delay);
		ssleep(root_delay);
	}

	/*
	 * wait for the known devices to complete their probing
	 *
	 * Note: this is a potential source of long boot delays.
	 * For example, it is not atypical to wait 5 seconds here
	 * for the touchpad of a laptop to initialize.
	 */
	wait_for_device_probe();

	md_run_setup();

	if (saved_root_name[0]) {
		root_device_name = saved_root_name;  //saved_root_name中保存了/dev/mmcblk0p2
		if (!strncmp(root_device_name, "mtd", 3) ||
		    !strncmp(root_device_name, "ubi", 3)) {
			mount_block_root(root_device_name, root_mountflags);
			goto out;
		}
		ROOT_DEV = name_to_dev_t(root_device_name); //根据设备名mmcblk0p2 生成设备号 dev_t,主设备号和次设备号
		if (strncmp(root_device_name, "/dev/", 5) == 0)
			root_device_name += 5;  //root_device_name 前移5,由/dev/mmcblk0p2 变为mmcblk0p2
	}

	if (initrd_load())
		goto out;

	/* wait for any asynchronous scanning to complete */
	if ((ROOT_DEV == 0) && root_wait) {
		printk(KERN_INFO "Waiting for root device %s...\n",
			saved_root_name);
		while (driver_probe_done() != 0 ||
			(ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
			msleep(100);
		async_synchronize_full();
	}

	is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;

	if (is_floppy && rd_doload && rd_load_disk(0))
		ROOT_DEV = Root_RAM0;

	mount_root(); //这里进行挂载
out:
	devtmpfs_mount("dev");
	sys_mount(".", "/", NULL, MS_MOVE, NULL);
	sys_chroot(".");
}
void __init mount_root(void)
{

#ifdef CONFIG_BLOCK
	create_dev("/dev/root", ROOT_DEV); //这里利用mksnod创建设备文件/dev/root,对应设备号和mmcblk0p2相同
	mount_block_root("/dev/root", root_mountflags);//开始挂载根文件分区,后续会根据/dev/root找到分区mmcblk0p2
#endif
}

后续再讲其它。



版权声明:本文为qq_45683435原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。