Ramfs, rootfs 和 initramfs

news2024/12/28 5:27:55

什么是ramfs

Ramfs 是一个非常简单的文件系统,它将 Linux 的磁盘缓存机制(页面缓存和 dentry 缓存)导出为可动态调整大小的基于 RAM 的文件系统。

通常,Linux 会将所有文件缓存在内存中。从后备存储(通常是文件系统所安装的块设备)读取的数据页面会保留以备再次需要,但会标记为干净(可释放),以防虚拟内存系统需要内存用于其他用途。同样,写入文件的数据在写入后备存储后会立即标记为干净,但会保留以备缓存,直到 VM 重新分配内存。类似的机制(dentry 缓存)大大加快了对目录的访问速度。

使用 ramfs 时,没有后备存储。写入 ramfs 的文件会像往常一样分配 dentry 和页面缓存,但没有地方写入它们。这意味着页面永远不会被标记为干净,因此当 VM 想要回收内存时,它们无法被释放。

实现 ramfs 所需的代码量很小,因为所有工作都由现有的 Linux 缓存基础结构完成。基本上,您将磁盘缓存作为文件系统安装。因此,ramfs 不是可通过 menuconfig 移除的可选组件,因为这样节省的空间可以忽略不计。

ramfs和ramdisk

较旧的“ram disk”机制从 RAM 的某个区域创建一个合成块设备,并将其用作文件系统的后备存储。此块设备的大小是固定的,因此安装在其上的文件系统的大小也是固定的。使用 ram disk 还需要不必要地将内存从伪块设备复制到页面缓存中(并将更改复制回来),以及创建和销毁 dentry。此外,它还需要文件系统驱动程序(例如 ext2)来格式化和解释这些数据。

与 ramfs 相比,这会浪费内存(和内存总线带宽)、给 CPU 带来不必要的工作,并污染 CPU 缓存。(有一些技巧可以通过使用页表来避免这种复制,但它们非常复杂,而且成本与复制差不多。)更重要的是,ramfs 所做的所有工作无论如何都必须发生,因为所有文件访问都要经过页面和 dentry 缓存。RAM 磁盘根本就没有必要;ramfs 内部要简单得多。

ramdisk 半过时的另一个原因是,引入了回送设备,提供了一种更灵活、更方便的方法来创建合成块设备,现在可以通过文件而不是内存块来创建。

ramfs和tmpfs

ramfs 的一个缺点是,您可以不断向其中写入数据,直到填满所有内存,而 VM 无法释放它,因为 VM 认为文件应该写入后备存储(而不是交换空间),但 ramfs 没有任何后备存储。因此,只有 root(或受信任的用户)才应被允许对 ramfs 挂载进行写访问。

ramfs 的衍生产品 tmpfs 是为了增加大小限制和将数据写入交换空间的能力而创建的。普通用户可以对 tmpfs 挂载进行写访问 。

什么是rootfs

Rootfs 是 ramfs(或 tmpfs,如果启用的话)的一个特殊实例,它始终存在于 2.6 系统中。您无法卸载 rootfs 的原因与您无法终止 init 进程的原因大致相同;与使用特殊代码检查和处理空列表相比,内核只需确保某些列表不会变为空,这样更小更简单。

大多数系统只是在 rootfs 上安装另一个文件系统并忽略它。ramfs 的空实例占用的空间很小。

如果启用了 CONFIG_TMPFS,rootfs 将默认使用 tmpfs 而不是 ramfs。要强制使用 ramfs,请在内核命令行中添加“rootfstype=ramfs”。

什么是initramfs

所有 2.6 Linux 内核都包含一个 gzip 压缩的“cpio”格式档案,内核启动时会将其解压到 rootfs 中。解压后,内核会检查 rootfs 是否包含文件“init”,如果是,则以 PID 1 执行该文件。如果找到,则此 init 进程负责启动系统,包括定位和安装实际根设备(如果有)。如果将嵌入式 cpio 档案解压到 rootfs 中后,rootfs 中不包含 init 程序,则内核将转到较旧的代码来定位和安装根分区,然后从中执行 /sbin/init 的某个变体。

这与旧的 initrd 有以下几个不同之处:

  • 旧的 initrd 始终是一个单独的文件,而 initramfs 档案链接到 linux 内核映像中。(该目录linux-*/usr专门用于在构建期间生成此档案。)

  • 旧的 initrd 文件是一个经过 gzip 压缩的文件系统映像(采用某些文件格式,例如 ext2,需要内置驱动程序到内核中),而新的 initramfs 存档是一个经过 gzip 压缩的 cpio 存档(类似于 tar,但更简单,请参阅 cpio(1) 和initramfs 缓冲区格式)。内核的 cpio 提取代码不仅非常小,而且它还是可以在启动过程中丢弃的 __init 文本和数据。

  • 旧 initrd(称为 /initrd,而不是 /init)运行的程序进行了一些设置,然后返回到内核,而 initramfs 中的 init 程序预计不会返回到内核。(如果 /init 需要移交控制权,它可以使用新的根设备覆盖 / 并执行另一个 init 程序。请参阅下面的 switch_root 实用程序。)

  • 当切换另一个根设备时,initrd 会先pivot_root,然后卸载ramdisk。但是 initramfs 是rootfs:您既不能pivot_root rootfs,也不能卸载它。相反,删除rootfs中的所有内容以释放空间(find -xdev / -exec rm ‘{}’ ‘;’),用新的根覆盖rootfs(cd /newmount; mount --move . /; chroot .),将stdin/stdout/stderr附加到新的/dev/console,然后执行新的init。

由于这是一个非常棘手的过程(并且需要在运行命令之前删除它们),klibc 包引入了一个辅助程序(utils/run_init.c)来为您完成所有这些工作。大多数其他包(例如 busybox)将此命令命名为“switch_root”。

填充initramfs

2.6 内核构建过程始终会创建一个 gzip 压缩的 cpio 格式的 initramfs 存档并将其链接到生成的内核二进制文件中。默认情况下,此存档为空(在 x86 上占用 134 个字节)。

配置选项 CONFIG_INITRAMFS_SOURCE(位于 menuconfig 中的常规设置中,位于 usr/Kconfig 中)可用于指定 initramfs 存档的源,该源将自动合并到生成的二进制文件中。此选项可以指向现有的 gzip 压缩的 cpio 存档、包含要存档的文件的目录或文本文件规范,例如以下示例:

dir /dev 755 0 0
nod /dev/console 644 0 0 c 5 1
nod /dev/loop0 644 0 0 b 7 0
dir /bin 755 1000 1000
slink /bin/sh busybox 777 0 0
file /bin/busybox initramfs/busybox 755 0 0
dir /proc 755 0 0
dir /sys 755 0 0
dir /mnt 755 0 0
file /init initramfs/init.sh 755 0 0

运行“usr/gen_init_cpio”(内核构建之后)以获取记录上述文件格式的使用消息。

配置文件的一个优点是不需要 root 访问权限即可在新存档中设置权限或创建设备节点。(请注意,这两个示例“文件”条目希望在 linux-2.6.* 目录下的“initramfs”目录中找到名为“init.sh”和“busybox”的文件。 有关更多详细信息,请参阅早期用户空间支持。)

内核不依赖外部 cpio 工具。如果您指定目录而不是配置文件,内核的构建基础结构将从该目录创建一个配置文件(usr/Makefile 调用 usr/gen_initramfs.sh),然后继续使用该配置文件打包该目录(通过将其提供给 usr/gen_init_cpio,后者是从 usr/gen_init_cpio.c 创建的)。内核构建cpio 时创建代码完全是自包含的,内核的启动提取也是自包含的。

您可能需要安装外部 cpio 实用程序来创建或提取您自己预先准备好的 cpio 文件以提供给内核构建(而不是配置文件或目录)。

以下命令行可以将 cpio 映像(通过上述脚本或内核构建)提取回其组件文件中:

cpio -i -d -H newc -F initramfs_data.cpio --no-absolute-filenames 

下面的 shell 脚本可以创建一个预建的 cpio 档案,您可以用它代替上面的配置文件:

#!/bin/sh
if [ $# -ne 2 ]
then
echo "usage: mkinitramfs directory imagename.cpio.gz"
exit 1
fi

if [ -d "$1" ]
then
echo "creating $2 from $1"
(cd "$1"; find . | cpio -o -H newc | gzip) > "$2"
else
echo "First argument must be a directory"
exit 1
fi

外部initramfs镜像

如果内核启用了 initrd 支持,也可以将外部 cpio.gz 存档传递到 2.6 内核中以代替 initrd。在这种情况下,内核将自动检测类型(initramfs,而不是 initrd)并在尝试运行 /init 之前将外部 cpio 存档提取到 rootfs 中。

这具有 initramfs(无 ramdisk 块设备)的内存效率优势,但具有 initrd 的单独打包优势(如果您有非 GPL 代码想要从 initramfs 运行,而又不将其与 GPL 许可的 Linux 内核二进制文件混淆,那么这非常好)。

它还可用于补充内核的内置 initramfs 映像。外部存档中的文件将覆盖内置 initramfs 存档中的任何冲突文件。一些分销商还喜欢使用特定于任务的 initramfs 映像自定义单个内核映像,而无需重新编译。

为什么选择cpio而不是tar

  1. cpio 是一个标准。它已有几十年历史(从 AT&T 时代开始),并且已在 Linux 上广泛使用(在 RPM 中,Red Hat 的设备驱动程序磁盘)。它不像 tar 那样流行,因为传统的 cpio 命令行工具需要 truly_hideous 命令行参数。但这并没有说明存档格式,还有其他替代工具。
  2. 内核选择的 cpio 存档格式比任何(实际上有几十种)不同的 tar 存档格式都更简单、更干净(因此更容易创建和解析)。完整的 initramfs 存档格式在 buffer-format.rst 中进行了说明,在 usr/gen_init_cpio.c 中创建,并在 init/initramfs.c 中提取。这三个文件加起来总共不到 26k 的人类可读文本。
  3. GNU 项目对 tar 的标准化与 Windows 对 zip 的标准化大致相同。Linux 不属于任何一个组织,并且可以自由地做出自己的技术决策。
  4. 由于这是内核内部格式,因此它很容易成为一种全新的格式。内核提供了自己的工具来创建和提取此格式。使用现有标准是可取的,但不是必需的。

未来方向

如今 (2.6.16),initramfs 始终被编译,但并非始终被使用。内核会回退到旧式引导代码,只有当 initramfs 不包含 /init 程序时才会使用。回退是旧式代码,用于确保平稳过渡并允许早期引导功能逐渐移至“早期用户空间”(即 initramfs)。

迁移到早期用户空间是必要的,因为查找和安装真正的根设备很复杂。根分区可以跨越多个设备(RAID 或单独的日志)。它们可以在网络上(需要 DHCP、设置特定的 MAC 地址、登录到服务器等)。它们可以存在于可移动媒体上,具有动态分配的主/次编号和持续的命名问题,需要完整的 udev 实现来解决。它们可以被压缩、加密、写时复制、环回安装、奇怪的分区等等。

这种复杂性(不可避免地包括策略)在用户空间中得到了正确的处理。klibc busybox/uClibc 都在开发简单的 initramfs 包,以便将其放入内核构建中。

klibc 软件包现已被纳入 Andrew Morton 的 2.6.17-mm 树。内核当前的早期启动代码(分区检测等)可能会被迁移到默认的 initramfs 中,由内核构建自动创建和使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2266764.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

7-8 N皇后问题

目录 题目描述 输入格式: 输出格式: 输入样例: 输出样例: 解题思路: 详细代码(dfs): 简单代码(打表): 题目描述 在NN格的国际象棋盘上摆放N个皇后,使其不能互相攻击,即任…

现代网络负载均衡与代理导论

大家觉得有有参考意义和帮助记得及时关注和点赞!!! Service mesh 是近两年网络、容器编排和微服务领域最火热的话题之一。Envoy 是目前 service mesh 数据平面的首选组件。Matt Klein 是 Envoy 的设计者和核心开发。 文章循序渐进&#xff0…

Kubernetes Gateway API-2-跨命名空间路由

1 跨命名空间路由 Gateway API 具有跨命名空间路由的核心支持。当多个用户或团队共享底层网络基础设施时,这很有用,但必须对控制和配置进行分段,以尽量减少访问和容错域。 Gateway 和 Route(HTTPRoute,TCPRoute,GRPCRoute) 可以部署到不同的命名空间中,路由可以跨命名空间…

Wend看源码-Java-集合学习(List)

摘要 本篇文章深入探讨了基于JDK 21版本的Java.util包中提供的多样化集合类型。在Java中集合共分类为三种数据结构:List、Set和Queue。本文将详细阐述这些数据类型的各自实现,并按照线程安全性进行分类,分别介绍非线程安全与线程安全的实现方…

集成方案 | Docusign + 蓝凌 EKP,打造一站式合同管理平台,实现无缝协作!

本文将详细介绍 Docusign 与蓝凌 EKP 的集成步骤及其效果,并通过实际应用场景来展示 Docusign 的强大集成能力,以证明 Docusign 集成功能的高效性和实用性。 在当今数字化办公环境中,企业对于提高工作效率和提升用户体验的需求日益迫切。蓝凌…

突围边缘:OpenAI开源实时嵌入式API,AI触角延伸至微观世界

当OpenAI宣布开源其名为openai-realtime-embedded-sdk的实时嵌入式API时,整个科技界都为之震惊。这一举动意味着,曾经遥不可及的强大AI能力,如今可以被嵌入到像ESP32这样的微型控制器中,真正地将AI的触角延伸到了物联网和边缘计算…

webrtc-internals调试工具

Google 的 Chrome(87 或更高版本)WebRTC 内部工具是一套内置于 Chrome 浏览器中的调试工具; webrtc-internals 能够查看有关视频和音频轨道、使用的编解码器以及流的一般质量的详细信息。这些知识对于解决音频和视频质量差的问题非常有帮助。 webrtc-int…

使用Webpack构建微前端应用

英文社区对 Webpack Module Federation 的响应非常热烈,甚至被誉为“A game-changer in JavaScript architecture”,相对而言国内对此热度并不高,这一方面是因为 MF 强依赖于 Webpack5,升级成本有点高;另一方面是国内已…

[bug]java导出csv用Microsoft Office Excel打开乱码解决

[bug]java导出csv用Microsoft Office Excel打开乱码 ‍ 现象 首先这个csv文件用macbook自带的 "Numbers表格" 软件打开是不乱码的, 但是使用者是Windows系统,他的电脑没有"Numbers表格"工具, ​​ 他用Microsoft Office Excel打开之后出现乱码,如下图…

关于分布式数据库需要了解的相关知识!!!

成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于关于分布式数据库方面的相关内容&a…

tortoisegit推送失败

tortoisegit推送失败 git.exe push --progress -- "origin" testLidar:testLidar /usr/bin/bash: gitgithub.com: No such file or directory fatal: Could not read from remote repository. Please make sure you have the correct access rights and the reposit…

moviepy将图片序列制作成视频并加载字幕 - python 实现

DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球(free)” -------------------------------------------------------------…

清空DNS 缓存

如果遇到修改了host文件,但是IP和域名的映射有问题的情况,可以尝试刷新DNS缓存。 ipconfig/flushdns win建加R建,然后输入cmd,然后回车 然后回车,或者点击确定按钮。 出现如下所示标识清空DNS 缓存成功。

2024最新鸿蒙开发面试题合集(二)-HarmonyOS NEXT Release(API 12 Release)

上一篇面试题链接:https://mp.csdn.net/mp_blog/creation/editor/144685078 1. 鸿蒙简单介绍和发展历程 HarmonyOS 是新一代的智能终端操作系统,为不同设备的智能化、互联与协同提供了统一的语言。带来简洁,流畅,连续&#xff0…

Yocto 项目 - 共享状态缓存 (Shared State Cache) 机制

引言 在嵌入式开发中,构建效率直接影响项目的开发进度和质量。Yocto 项目通过其核心工具 BitBake 提供了灵活而强大的构建能力。然而,OpenEmbedded 构建系统的传统设计是从头开始构建所有内容(Build from Scratch),这…

idea 8年使用整理

文章目录 前言idea 8年使用整理1. 覆盖application配置2. 启动的时候设置编辑空间大小,并忽略最大空间3. 查询类的关系4. 查看这个方法的引用关系5. 查看方法的调用关系5.1. 查看被调用关系5.2. 查看调用关系 6. 方法分隔线7. 选择快捷键类型8. 代码预览插件9. JReb…

04软件测试需求分析案例-用户登录

通读文档,提取信息,提出问题,整理为需求。 从需求规格说明、设计说明、配置说明等文档获取原始需求,通读原始需求,分析有哪些功能,每种功能要完成什么业务,业务该如何实现,业务逻辑…

【MySQL】踩坑笔记——保存带有换行符等特殊字符的数据,需要进行转义保存

问题描述 从DBeaver中导出了部分业务数据的 insert sql,明明在开发、测试环境都可以一把执行通过,却在预发环境执行前的语法检查失败了,提示有SQL语法错误。 这条SQL长这样,default_sql是要在odps上执行的sql语句,提…

windos挂载目录到linux

验证环境麒麟V10 1: 在windows任意目录设置共享文件夹 2:记住网络路径\LAPTOP-86JV6NT1\gantie13_sdk 在linux中替换为本机ip级相对路径 比如本级ip是192.168.23.23,linux环境需要ping通本地地址 3: sudo apt-get install cifs-utils sud…

springboot494基于java的综合小区管理系统(论文+源码)_kaic

摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统综合小区管理系统信息管理难度大,容错率低&am…