Mounting rootfs in linux

[linux kernel] rootfs for mounting root file system

For the linux kernel, the file system can be said to add endless «fun» to the kernel. When linux is running, for a file system, only when it is mounted to a directory in the directory tree in memory, the file system will be accessed by linux. The concept of «parent-child» is used in many places in the linux kernel. This concept is also used in the file system part. For the first file system in the linux kernel, it cannot be mounted through the mount command or system call. At this time, the root file system will be mounted through the following two mechanisms.

The concept of root file system here is from the perspective of kernel and user. From the perspective of linux kernel, the root file system is rootfs; From the user’s point of view, the root file system is the root file system specified by the user, which is specified by the kernel parameter root = during linux boot. The relationship between the two is: after the linux kernel startup process, the root file system specified by the user will be mounted to the root directory of the rootfs file system.

2, rootfs root file system

In the process of linux kernel startup, the first mounted root file system is rootfs file system, which is a memory file system, that is, it is memory based and hidden from users. The file system is very important. The standard input, standard output and standard error used by each process correspond to file descriptors 0, 1 and 2. These three file descriptor levels correspond to the character device file «/ dev/console» in the rootfs file system. Let’s take a look at rootfs from the perspective of source code.

Читайте также:  Linux удаление файлов корзина
(2-1) initialize rootfs

Initialize rootfs file system by init_ The rootfs() function is completed and is defined as follows:

int __init init_rootfs(void) < int err = register_filesystem(&rootfs_fs_type); if (err) return err; if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && (!root_fs_names || strstr(root_fs_names, "tmpfs"))) < err = shmem_init(); is_tmpfs = true; >else < err = init_ramfs_fs(); >if (err) unregister_filesystem(&rootfs_fs_type); return err; >

In the above code snippet, register will be called_ File system() registers rootfs file system type rootfs with linux kernel_ fs_ type. It is defined as follows:

static struct dentry *rootfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) < static unsigned long once; void *fill = ramfs_fill_super; if (test_and_set_bit(0, &once)) return ERR_PTR(-ENODEV); if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) fill = shmem_fill_super; return mount_nodev(fs_type, flags, data, fill); >static struct file_system_type rootfs_fs_type = < .name = "rootfs", .mount = rootfs_mount, .kill_sb = kill_litter_super, >;
(2-2) mount rootfs file system

The rootfs file system is mounted by init_ mount_ The tree() function is completed. From the name of the function, we can vividly know that the function of the function is to initialize the mount tree. This function is defined as follows:

static void __init init_mount_tree(void) < struct vfsmount *mnt; struct mnt_namespace *ns; struct path root; struct file_system_type *type; type = get_fs_type("rootfs"); if (!type) panic("Can't find rootfs type"); mnt = vfs_kern_mount(type, 0, "rootfs", NULL); put_filesystem(type); if (IS_ERR(mnt)) panic("Can't create rootfs"); ns = create_mnt_ns(mnt); if (IS_ERR(ns)) panic("Can't allocate initial namespace"); init_task.nsproxy->mnt_ns = ns; get_mnt_ns(ns); root.mnt = mnt; root.dentry = mnt->mnt_root; mnt->mnt_flags |= MNT_LOCKED; set_fs_pwd(current->fs, &root); set_fs_root(current->fs, &root); >

Line 11 above, use vfs_kern_mount() mounts the rootfs file system.

Line 16, use create_ mnt_ The NS (MNT) function creates the first mount command space.

Читайте также:  Hashcat gpu kali linux

Line 20 above sets the mounting namespace of thread 0.

Lines 27 and 28 set the current working directory and root directory of thread 0 as the root directory of rootfs file system.

(2-3) create simple rootfs root file system directories and files

Next, default_ The rootfs () function will create the necessary directories and file nodes in the rootfs file system. The following code is shown (/ init/noinitramfs.c):

static int __init default_rootfs(void) < int err; err = ksys_mkdir((const char __user __force *) "/dev", 0755); if (err < 0) goto out; err = ksys_mknod((const char __user __force *) "/dev/console", S_IFCHR | S_IRUSR | S_IWUSR, new_encode_dev(MKDEV(5, 1))); if (err < 0) goto out; err = ksys_mkdir((const char __user __force *) "/root", 0700); if (err < 0) goto out; return 0; out: printk(KERN_WARNING "Failed to create a rootfs\n"); return err; >rootfs_initcall(default_rootfs);

As can be seen from the above code, the / dev directory will be created; Create the character device file / dev/console of the console. The master device number is 5 and the slave device number is 1

The / root directory will also be created. Finally, rootfs will be used_ The initcall macro will default_ The rootfs function is added to the initialization section.

[special note] for default_ The rootfs function will be compiled without setting initrd/initramfs. If the [initial ram file system and ramdisk (initramfs/initrd) support] option is set. Then default_ The rootfs () function will not be compiled into the linux kernel!

(2-4) open 0, 1 and 2 file descriptors

In the linux kernel thread function No. 1, the kernel will be called_ init_ Freeable() function, in which the character device file / dev/console of the console will be opened to get the file descriptor 0, and then the file descriptor 0 will be assigned twice to get the file descriptors 1 and 2. The following code snippet:

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

Thread 1 of the linux kernel uses try_to_run_init_process() attempts to load programs in user space, so as to convert the kernel to user space. In this process, thread 1 will be the parent process of other threads, so that the child thread will inherit the open file table and file descriptors 0, 1 and 2. This is why the standard input, standard output and standard error used by each process are unified.

Читайте также:  Компас 3d linux аналоги

3, Mount the root file system specified by the user

When booting the linux kernel, you can use the kernel parameter root to specify the name of the storage device and the rootfstype kernel parameter to specify the type of the root file system. To mount the user's root file system. The specific implementation is performed by prepare_ The namespace () function is completed. See this article for this part:< [linux kernel] how does the linux kernel mount the root file system>

Posted by andybrooke on Wed, 06 Apr 2022 22:56:14 +0930

  • Java - 5996
  • Python - 2604
  • Algorithm - 1737
  • Javascript - 1708
  • Back-end - 1577
  • Front-end - 1561
  • Linux - 1389
  • C++ - 1378
  • data structure - 1135
  • Database - 953
  • Spring - 922
  • C - 836
  • MySQL - 835
  • Android - 683
  • Spring Boot - 660
  • Vue.js - 549
  • Design Pattern - 543
  • Operation & Maintenance - 509
  • Deep Learning - 487
  • Interview - 459

Источник

Оцените статью
Adblock
detector