为什么在init之前kernel要挂载rootfs?
在linux启动的时候,仅仅启动kernel是不行的,还要相应的通过/etc、/sbin,启动一些必须依赖的管理模块比如说systemd,同时,为了考虑到/etc、/sbin都是文件系统,是文件系统就需要将整个系统挂载到/
的这个根目录下,因此在启动的时候需要提供**/**
目录来方便**/etc**
、**sbin**
等启动关键程序和配置,这时候就需要一个专门提供挂载点的fs,这也就是rootfs。
这里引用一些参考[1]中的代码块
start_kernel
vfs_caches_init
mnt_init
init_rootfs //注册rootfs文件系统
init_mount_tree // 挂载rootfs文件系统
vfs_kern_mount
mount_fs
type->mount // 其实是rootfs_mount
mount_nodev
fill_super 其实是ramfs_fill_super
inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
sb->s_root = d_make_root(inode);
static const struct qstr name = QSTR_INIT("/", 1); // 设置根目录名字为 /
__d_alloc(root_inode->i_sb, &name);
…
mnt->mnt.mnt_root = root; // 目录
mnt->mnt.mnt_sb = root->d_sb; // 设置超级快
mnt->mnt_mountpoint = mnt->mnt.mnt_root; // 文件挂载点,因为是/所有自己指向自己
mnt->mnt_parent = mnt; // 父挂载点也是自己
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);
…
rest_init
kernel_thread(kernel_init, NULL, CLONE_FS);
————————————————
版权声明:本文为CSDN博主「leon1741」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LEON1741/article/details/78159754
由于初始化的时候硬盘并未挂载进来,初始化的rootfs其实是ramfs或者是tmpfs(一般是tmpfs)。
// COPY FROM https://houmin.cc/posts/7c0e6000/
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(); // tmpfs初始化
is_tmpfs = true;
} else {
err = init_ramfs_fs(); // ramfs初始化
}
if (err)
unregister_filesystem(&rootfs_fs_type);
return err;
}
Q: 读完这里你可以还有疑问为什么/boot
可以直接挂载进来?A:因为其本身就可以被Bootloader启动,直接读入内存,是BootLoader先引导这两部分进内存之后,才启动rootfs
df -h
/dev/nvme0n1p2 976M 221M 688M 25% /boot
/dev/nvme0n1p1 511M 6.7M 505M 2% /boot/efi
将rootfs挂载之后会如何做呢?
之后的目标就是通过init
进程启动整个系统。这个时候就轮到initramfs
登场了,在完成rootfs
注册之后,kernel会将initramfs
复制到rootfs
上,然后作为内核初始的根文件系统,它的任务是挂载系统真正的根文件系统。(也就是挂载在/
上的物理卷或者虚拟卷,甚至是块存储)。在initramfs
中会有init
进程,此时,init
程序会作为pid为1的进行开始运行,从而启动整个系统。
Q:rootfs跟initramfs是什么关系呢?
A:initramfs是一种rootfs,在rootfs启动后,会删除rootfs的内容,将initramfs挂在进来,然后通过chroot的方式,将initramfs置为/
备注:这里面删除rootfs,那么之前的命令也没了,之后基于busybox使用switch_root的方式去处理这个过程,详细可以看3。
这个还有一个简单的趣闻:
initramfs在/boot里面是以initrd命名的,但是其只是延续了2.6之前内核的命名方式而已,实现方式已经改变了。initramfs是基于ramfs的而之前的initrd是基于ramdisk的。有兴趣的可以接着看
- initrd和initramfs的区别是什么? : https://www.zhihu.com/question/22045825
- [3] https://houmin.cc/posts/7c0e6000/
参考:
- [1] rootfs介绍:https://blog.csdn.net/LEON1741/article/details/78159754
- [2] initramfs介绍:https://wiki.gentoo.org/wiki/Initramfs/Guide/zh-cn
- [3] ramfs、tmpfs、initramfs介绍:https://houmin.cc/posts/7c0e6000/