系统构建--根文件系统的挂载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rikeyone/article/details/88378085

在开始讲解根文件系统挂载之前,首先需要明确如下几个概念:
ramdisk/rootfs/initramfs/initrd。

ramdisk

以一块固定大小的内存作为一个block设备创建文件系统,其中的内容只存在于内存中,修改它的内容不会记录到磁盘中。它用内存模拟了block设备,所以其中的内容还要先加载到page cache中,本身它是内存,创建的page cache也是内存,这产生了对很多内存的浪费,另外它另一个特点就是固定大小。

我们创建一个ext类型的文件系统,然后交给bootloader加载,bootloader把这个文件系统的内容预先加载进入一块内存,然后通过cmdline传入给kernel,对于kernel来说,直接面对的就是一块内存,因此叫他ramdisk。

rootfs/initramfs

为什么把他们放在一起呢?因为实际上他们指的是同一个东西,kernel 2.6版本之后引入了rootfs的功能,这个功能就是在kernel代码中实现一个很小的rootfs,这个rootfs中除了一些必须的file list,其他都是空的。系统启动时会直接先加载这个rootfs,既然它是空的,那么怎么填充它呢,initramfs就是填充到rootfs中的内容。如果系统启动时检测到rootfs根目录下填充的有init程序,那么就把系统交给这个init程序接管,由它进行后面的初始化行为。如果检测没有,那么就认为这个rootfs不可用,而按照旧的方式挂载根分区,也就是从cmdline中读取root=xxx这种参数去挂载。initramfs可以是一个cpio格式的压缩文件,也可以是一个目录。可以在defconfig中指定,这样就能直接编译到内核中,也可以通过cmdline传参数。

initrd

initrd是传递给内核用于挂载根文件系统的文件,现在它分为两种,一种是image格式zip压缩包,这是最原始的作用,传入的是ramdisk,另一种是cpio格式,传入的是initramfs,内核在解析时会自动解析它的格式,从而按照不同的方式进行处理。

ramdisk和initramfs的区别:

  • 1.在切换根文件系统时,rootfs是不能执行卸载的,想要挂载其他的根文件系统,只能通过switch_root的方式,ramdisk可以通过priv_root切换后,执行umount卸载操作。
  • 2.ramdisk只能通过外部传入initrd的方式存在,initramfs支持两种方式,可以和kernel编译在一起,也可以以initrd的方式传入。
  • 3.ramdisk在使用时,启动时会先执行/initrd进行一些初始化后需要返回到kernel继续执行,而initramfs检测到/init程序后,后续初始化交由init进程,不再返回kernel运行。

root分区挂载的方式:

1.ramdisk挂载 cmdline传入root=/dev/ramX,initrd=addr,size。
2.物理分区挂载 cmdline传入root=/dev/mmcblk0。
3.initramfs挂载:这种方式不需要传入"root=XXX",因为这个roofs是内核自带的,但是要保证其中填充了内容,特别是根目录要存在init程序。如果根目录没有init程序,那么根目录会挂载失败,当然我们可以通过传入"rdinit=/XXX"来指定其他的程序名,只要这个名字存在也同样能挂载rootfs。 如果initramfs是独立于kernel存在的cpio压缩包,那么同样需要initrd=addr,size来传递给内核。
4.切换根目录 这个功能是在init中实现的,也是和initramfs搭配常用的方法。iniramfs它实际上还依然是一个存在于内存中的文件系统,我们可以通过switch_root的方式重新挂载根文件系统。比如重新挂载某一个磁盘分区为根文件系统。

猜你喜欢

转载自blog.csdn.net/rikeyone/article/details/88378085