Mounting process of linux root file system 1

Source: Internet
Author: User



I recently read the mounting of the file system when Linux is started. I think this article is very good. I just went here and added some file paths for ease of understanding !!

I. Preface

Some time ago, when compiling the kernel, we found that rootfs could not be mounted. You can set the old image with the same root option. To completely solve this problem. The mounting process of rootfs is studied. The following is a summary of this topic, hoping to help those who are confused about this topic.

Ii. Types of rootfs

In general, rootfs is divided into two types: Virtual rootfs and real rootfs. Now the development trend of kernel is to put more functions into the user space. To keep the kernel concise. Virtual rootfs is also widely used by Linux vendors. You can put a part of the initialization work in the virtual rootfs. Switch to the real file system.

In the development of virtual rootfs. The following versions are available:

Initramfs:

Initramfs is a technology introduced in kernel 2.5. In fact, it means to append a cpio package to the kernel image, which contains a small file system, when the kernel starts, the kernel unpacks the cpio package and releases the file system contained in the package to rootfs. Some of the initialization code in the kernel is stored in this file system, run as a user-layer process. The obvious advantage of this is that the kernel initialization code is simplified and the kernel initialization process is easier to customize. In this way, rootfs is included in the kernel image.

Cpio-initrd: rootfs in cpio format

Image-initrd: rootfs in the traditional format

For the creation of these two virtual file systems, please refer to other materials.

Iii. Mounting the rootfs File System

The rootfs mentioned here is different from the rootfs analyzed above. This refers to the root node during system initialization. That is, node. It is the rootfs File System in memory. This section has been analyzed in <Linux Startup Process Analysis> and the file system. For the sake of Knowledge Consistency, repeat here.

Start_kernel () à MNT _ Init (): // starts from the start_kernel () function in/init/Main. C.



// Start_kernel ---> vfs_caches_init () (FS/dcache. c)
---> Mnt_init () (FS/namespace. c)


Void _ init mnt_init (void)

{

......

......

Init_rootfs (); // fs/ramfs/inode. c

Init_mount_tree (); // fs/namespace. c

}

The init_rootfs code is as follows:

Int _ init init_rootfs (void)
// Fs/ramfs/inode. c

{

Int err;

Err = bdi_init (& ramfs_backing_dev_info );

If (ERR)

Return err;

Err = register_filesystem (& rootfs_fs_type );

If (ERR)

Bdi_destroy (& ramfs_backing_dev_info );

Return err;

}

This function is simple. It is the file system registered with rootfs.

The init_mount_tree () code is as follows:
// Fs/namespace. c

Static void _ init init_mount_tree (void)

{

Struct vfsmount * MNT;

Struct mnt_namespace * ns;

Struct path root;

Mnt = do_kern_mount ("rootfs", 0, "rootfs", null );

If (is_err (mnt ))

Panic ("can't create rootfs ");

NS = kmalloc (sizeof (* NS), gfp_kernel );

If (! NS)

Panic ("can't allocate initial namespace ");

Atomic_set (& NS-> count, 1 );

Init_list_head (& NS-> list );

Init_waitqueue_head (& NS-> poll );

NS-> event = 0;

List_add (& MNT-> mnt_list, & NS-> list );

NS-> root = mnt;

MNT-> mnt_ns = ns;

Init_task.nsproxy-> mnt_ns = ns;

Get_mnt_ns (NS );

Root. mnt = NS-> root;

Root. dentry = NS-> root-> mnt_root;

Set_fs_pwd (current-> FS, & root );

Set_fs_root (current-> FS, & root );

}

Mount the rootfs file system here. Its mount point is "/" by default. The root directory of the process to be switched to and the current directory is "/". This is the origin of the root directory. However, this is only initialization. After mounting a specific file system, the root directory is usually switched to a specific file system. Therefore, after the system is started, the mounting information of rootfs cannot be seen by running the mount command.

Iv. Virtual File System mounting

The root directory has been mounted. You can mount a specific file system.

In start_kernel () à rest _ Init () à KERNEL _ Init (): // init/Main. c

Static int _ init kernel_init (void * unused)

{

......

......

Do_basic_setup ();
// Init/Main. c

If (! Ramdisk_execute_command)

Ramdisk_execute_command = "/init ";

If (sys_access (const char _ User *) ramdisk_execute_command, 0 )! = 0 ){

Ramdisk_execute_command = NULL;

Prepare_namespace ();
// Init/do_mount.c

}

/*

* OK, we have completed the initial bootup, and

* We're essential up and running. Get rid of

* Initmem segments and start the user-mode stuff ..

*/

Init_post (); // init/Main. c

Return 0;

}

Do_basic_setup () is a key function. All modules directly compiled in the kernel are started by it. The code snippet is as follows:

Static void _ init do_basic_setup (void)
// Init/Main. c

{

/* Drivers will send hotplug events */

Init_workqueues ();

Usermodehelper_init ();

Driver_init ();

Init_irq_proc ();

Do_initcils (); // init/Main. c

}

Do_initcils () is used to start all functions in the _ initcall_start and _ initcall_end segments. The modules compiled to the kernel in a static manner also places its entry in this interval.

All initialization functions related to the root file system are called by rootfs_initcall ()
(Macro definition,/include/Linux/init. h) references. Note the following initialization functions:

Rootfs_initcall (populate_rootfs );

That is to say, populate_rootfs will be called during system initialization for initialization. The Code is as follows:

Static int _ init populate_rootfs (void)
// Init/initramfs. c

{

Char * err = unpack_to_rootfs (_ initramfs_start,

_ Initramfs_end-_ initramfs_start, 0 );

If (ERR)

Panic (ERR );

If (initrd_start ){

# Ifdef config_blk_dev_ram

Int FD;

Printk (kern_info "Checking if image is initramfs ...");

Err = unpack_to_rootfs (char *) initrd_start,

Initrd_end-initrd_start, 1 );

If (! Err ){

Printk ("It is \ n ");

Unpack_to_rootfs (char *) initrd_start,

Initrd_end-initrd_start, 0 );

Free_initrd ();

Return 0;

}

Printk ("It isn' t (% s); looks like an initrd \ n", err );

FD = sys_open ("/initrd. Image", o_wronly | o_creat, 0700 );

If (FD> = 0 ){

Sys_write (FD, (char *) initrd_start,

Initrd_end-initrd_start );

Sys_close (FD );

Free_initrd ();

}

# Else

Printk (kern_info "unpacking initramfs ...");

Err = unpack_to_rootfs (char *) initrd_start,

Initrd_end-initrd_start, 0 );

If (ERR)

Panic (ERR );

Printk ("done \ n ");

Free_initrd ();

# Endif

}

Return 0;

}

Unpack_to_rootfs (init/initramfs. c): Decompress the package and release it to rootfs. It actually has two functions: release a package and check whether the package belongs to the cpio structure. The function selection is based on the last parameter.

In this function, it corresponds to the three virtual root file systems we have previously analyzed. One is initramfs integrated with the kernel. when compiling the kernel, store it in the _ initramfs_start to _ initramfs_end area through the link script. In this case, call unpack_to_rootfs to release it to the root directory. If not. That is, the values of _ initramfs_start and _ initramfs_end are equal and the length is zero. No processing is performed. Exit.

Corresponds to the last two cases. From the code, you must configure config_blk_dev_ram to support image-initrd. Otherwise, it is processed in the form of cpio-initrd.

For cpio-initrd. Release it directly to the root directory. For image-initrd. Release it to/initrd. image. Finally, add the initrd memory region to the partner system. This memory can be used by the operating system for other purposes.

Next, how does the kernel handle these situations? Don't worry. Look down:

Return to the kernel_init () function:

Static int _ init kernel_init (void * unused) // init/Main. c

{

.......

.......

Do_basic_setup ();

/*

* Check if there is an early userspace init. If yes, let it do all

* The work

*/

If (! Ramdisk_execute_command)

Ramdisk_execute_command = "/init ";

If (sys_access (const char _ User *) ramdisk_execute_command, 0 )! = 0 ){

Ramdisk_execute_command = NULL;

Prepare_namespace ();
// Init/do_mount.c

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.