资讯动态

【2016-08-13】【转】基于 SquashFS 构建 Linux 可读写文件系统

发布时间:2026/9/15 9:18:03 来源:尧图企业网站定制
[历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2016-08-13 标题【转】基于 SquashFS 构建 Linux 可读写文件系统分类操作系统 / linux 标签linux·SquashFS【转】基于 SquashFS 构建 Linux 可读写文件系统基于 SquashFS 构建 Linux 可读写文件系统嵌入式 Linux 启动过程图 1. 可启动 linux 镜像文件结构只读式压缩文件系统介绍Squash 压缩文件系统的创建注释清单 1. 创建空的根文件系统清单 2. 挂载空的根文件系统清单 3. 拷贝根文件目录统图 2. 根文件系统内容注释清单 4. 创建根文件系统加载压缩文件系统所使用的工具加载 Squash 压缩文件系统图 3. 可读写文件系统原理注释清单 5. 构建可读写文件系统脚本图 4. 被挂载的根文件系统内容图 5. 根文件系统的写操作结束语本文转自【 https://www.ibm.com/developerworks/cn/linux/1306_qinzl_squashfs/ 】基于 SquashFS 构建 Linux 可读写文件系统在当前的嵌入式操作系统开发中Linux 操作系统通常被压缩成 Image 后存放在 Flash 设备中。在系统启动过程中这些 Image 被直接挂载到根文件系统 然而这时的根文件系统是只读的 用户不能在这个文件系统中进行任何写的操作。 如果把 Image 解压后直接拷贝到内存中也可以实现写的功能但是嵌入式系统一直存在内存大小方面的限制所以将整个 Linux 系统拷入内存是不可取的。 本文将介绍一种直接挂载 Image 到根目录下同时实现文件系统可读写的功能。嵌入式 Linux 启动过程本文所描述的的 Linux Image 由 BootLoader、kernel、initrd、rootfs 组成它们共同存在于一个可以启动的存储设备中本文以 USB 为例。组成架构如下图 1. 可启动 linux 镜像文件结构各个模块的作用如下Boot Loader由 BIOS 加载用于将后续的 Kernel 和 initrd 的装载到内存中kernel为 initrd 运行提供基础的运行环境initrd检测并加载各种驱动程序rootfs根文件系统用户的各种操作都是基于这个被最后加载的文件系统其调用顺序是 Boot Loader-kernel-initrd-rootfs。当机器上电时首先 BIOS 会启动然后装载 USB 设备中的 Boot Loader、kernel,、nitrd 到内存中由于这些文件大小总和小于 10M所以我们直接拷贝到内存中再执行不会有问题。最后要加载的 rootfs 是用户最终进行读写操作的文件系统。在非嵌入式系统中这部分文件通常储存在可直接读写的硬盘上因此直接挂载到根目录后例如mount /dev/sda1 /mnt就可以进行读写操作。在嵌入式系统中它是一个压缩的文件系统大小通常是好几百兆解压后的大小都超过 1G如果直接 mount 到系统目录那么系统目录是只读的不可进行写入操作。而如果把它加压到内存中可以实现读写的操作但是这么大的文件直接解压到内存中对于嵌入式设备来说是不可接受的。因此我们需要找到一种不拷贝 rootfs 到内存中同时又可以对最终的根文件系统进行读写的方法。只读式压缩文件系统介绍在嵌入式的环境之下内存和外存资源都需要节约使用。如果使用 RAMDISK把内存当作 disk方式来使用文件系统那么在系统运行之后首先要把外存 (Flash) 上的映像文件解压缩到内存中构造起 RAMDISK 环境才可以开始运行程序。但是它也有很致命的弱点。在正常情况下同样的代码不仅在外存中占据了空间 ( 以压缩后的形式存在 )而且还在内存中占用了更大的空间 ( 以解压缩之后的形式存在 )这违背了嵌入式环境下尽量节省资源的要求。以下两种方案的诞生就是为了解决这个问题CramFSCramFS 文件系统是专门针对闪存设计的只读压缩的文件系统它并不需要一次性地将文件系统中的所有内容都解压缩到内存之中而只是在系统需要访问某个位置的数据的时侯马上计算出该数据在 CramFS 中的位置将其实时地解压缩到内存之中然后通过对内存的访问来获取文件系统中需要读取的数据。CramFS 中的解压缩以及解压缩之后的内存中数据存放位置都是由 CramFS 文件系统本身进行维护的用户并不需要了解具体的实现过程因此这种方式增强了透明度对开发人员来说既方便又节省了存储空间。SquashFSSquashFS 也是一个只读的文件系统它可以将整个文件系统压缩在一起存放在某个设备某个分区或者普通的文件中。如果您将其压缩到一个设备中那么您可以将其直接 mount 起来使用而如果它仅仅是个文件的话您可以将其当为一个 loopback 设备使用。更多信息请参考“SquashFS”和“CramFS”。本文主要介绍基于 SquashFS 的可读写文件系统构建。回页首Squash 压缩文件系统的创建“下载并安装 Squash 工具”步骤 1创建空的根文件系统文件系统的大小为 65536 × 24000/1024/10241.5G。接下来我们会在这个空的根文件系统中存放文件。注释dd: 读取源文件的内容并创建一个新文件if 指定源文件内容of 指定新文件名字bs 和 count 指定新文件的大小mke2fs: 将新创建的 rootfs 格式化为 Linux 可识别的文件系统清单 1. 创建空的根文件系统ddif/dev/zeroofrootfsbs65536count24000mke2fs-Frootfs步骤 2挂载空的根文件系统将 1.5G 的文件系统挂载在 mnt 目录下然后通过 mnt 目录将内容写入根文件系统。清单 2. 挂载空的根文件系统mkdirmntmountrootfs mnt-oloop步骤 3拷贝根文件目录的内容到文件系统清单 3. 拷贝根文件目录统cp-rpyourRootDir mntumountmnt拷贝完后根文件系统的内容如图 2 所示图 2. 根文件系统内容步骤 4完成根文件系统的创建这时的 rootfs 没有被压缩接下来我们用工具将其压缩成 Squash 格式的文件系统注释mksquashfs-4.1 是在安装 Squash 工具的过程中生成的命令用于将一个文件夹下的内容打包并压缩成一个文件系统。其后第一个参数为文件夹第二个参数为生成的文件系统。清单 4. 创建根文件系统mkdirsquashfs-dirmvrootfs squshfs-dir mksquashfs-4.1 squashfs-dir squashRootfs到这里我们就完成了 Squash 压缩文件系统的创建。接下来我们将讨论如何在 Linux 启动的过程中加载这个压缩文件系统。回页首加载压缩文件系统所使用的工具在加载压缩文件系统之前我们需要确定您的 Linux 内核支持这种文件系统。 Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制在该机制下用户可以很方便的根据自己的需要制定实现存储资源的管理策略。确保在 initrd 中已经集成“device-mapper”回页首加载 Squash 压缩文件系统可读写文件系统原理如图 3 所示图 3. 可读写文件系统原理squashRootfs 里面存储了我们原始的根文件系统我们在根文件系统中所有的写操作会直接写入 cowfile.out(cow:copy-on-write) 当我们读取根文件系统时如果读取的内容没有变化将直接从 squashRootfs 中读取如果读取的内容被更新过将从 cowfile.out 中读取。cowfile.out 文件的大小一般要比 squshRootfs 小如果 cowfile.out 被写满根文件系统的读写操作将会出错因此有必要给 cowfile.out 设置一个合理的大小以防止被写满。由于 rootfs 是被 initrd 加载的因此我们需要在 initrd 里面加入装载 rootfs 的代码。initrd 整个的执行过程是调用 /sbin/init 这个脚本文件因此我们在这个脚本的最后加入以下代码逻辑即可。注释dm-mirror 为 device mapper 工作所需要的驱动mknod: 创建一些设备文件参数 1设备文件名 参数 2设备类型 参数 3主设备号 参数 4次设备号将 squashRootfs 通过 loop 设备的形式挂载在目录 /realroot/mnt/ 下将 /realroot/mnt/rootfs 设置为 loop 设备并和 /dev/loop1 绑定|之前的部分是构建 dmsetup 的参数其中 $(blockdev --getsize /dev/loop1) 表示创建镜像文件的大小/dev/loop1 /dev/loop2 表示镜像文件是以 /realroot/mnt/rootfs 和 /realroot/mnt/cowfile.out 为蓝本进行创建的在前面的操作中 loop1 和 loop2 分别进行了绑定操作清单 5. 构建可读写文件系统脚本# 加载驱动 ,参见注释 1 modprobe dm-mirror# 创建设备 ,参见注释 2 mknod /dev/zero c 1 5mknod/dev/loop0 b70mknod/dev/loop1 b71mknod/dev/loop2 b72mkdir/dev/cowmknod/dev/cow/ctl b241255mknod/dev/cow/0 b2410# 挂载 squash 根文件系统挂载完后您可以在 /realroot/mnt/ 下找到 rootfs 文件 ,参见注释 3 mount /realroot/mnt/squashRootfs /realroot/mnt/ -o loop# 设置 rootfs 为 loop 设备 ,参见注释 4 losetup /dev/loop1 /realroot/mnt/rootfs# 创建 cowfile.out 并挂载为 loop 设备我们将来的写操作都会写入 cowfile.outddif/dev/zeroof/realroot/mnt/cowfile.outbs2Kcount137500losetup /dev/loop2 /realroot/mnt/cowfile.out# 将 /realroot/mnt/rootfs 和 /realroot/mnt/cowfile.out 结合起来创建一个逻辑根文件设备# 设备文件为 /dev/mapper/root_fs,参见注释 5 echo 0 $(blockdev --getsize /dev/loop1) snapshot /dev/loop1 /dev/loop2 p 64 |dmsetup create root_fs# 将上面创建的逻辑根文件设备 /dev/mapper/root_fs 挂载就可以看到一个可读写的根文件系统mount/dev/mapper/root_fs /realroot/mnt/Image# 切换到最终可读写的根文件系统cd/realroot/mnt/Imagechroot./sbin/init-i加下来您就可以看到 rootfs 的所有内容如图 4 所示图 4. 被挂载的根文件系统内容还可以在这个文件系统中进行写操作如图 5 所示图 5. 根文件系统的写操作最重要的是 rootfs 没有被拷贝到内存中。回页首结束语由于篇幅的限制本文只给出了基本的描述。希望有更一步了解的读者可以通过对以下 linux 命令的学习来深入了解。构建 Squash 压缩文件系统构所使用的主要命令**mksquashfs:**创建 Squash 压缩文件系统使用 Squash 压缩文件系统构所使用的主要命令**mknod:**创建 Squash 压缩文件系统**losetup:**设置并控制 Loop 设备**chroot:**改变根目录**dmsetup:**低水平逻辑卷管理

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价