📜  Linux内核中的初始化和缓存机制

📅  最后修改于: 2021-10-18 12:43:12             🧑  作者: Mango

我获得了基于 Debian 的 Linux 操作系统的更新,但中间系统崩溃了。它自动重新启动,之后我只能看到黑屏和命令行界面,并写了一个词“initramfs”。
图像00

方法是从 initramfs 引导菜单中出来。我启动了一张 ubuntu(相同版本)的 live CD,并在没有安装操作系统的情况下打开了终端。然后我执行了一些命令,如下所示:

# for find out the partition drive in
# which the crashed OS is installed.
sudo fdisk -l|grep Linux|grep -Ev 'swap'  

# to list all superblocks in the partition.
sudo dumpe2fs /dev/sda2 | grep superblock  

# this command will repair the OS by 
# alternate superblock and ‘y’ flag is
# used to allow the terminal to fix.
sudo fsck -b 32768 /dev/sda2 -y  

不使用 Live CD 进行修复
您也可以进入恢复模式,但它无法扫描安装操作系统的完整分区,并将显示 initramsfs 启动菜单。然后你可以给出命令:

fsck /dev/partition \name \where \your \OS \is \installed -y

它得到了修复,但这个错误留下了一个问题——什么是 initramfs?

机制

在 RAM 中,一些空间是为系统文件保留的,也用于管理缓存。 Ramfs 是将 Linux 的磁盘缓存机制导出为基于 RAM 的动态可调整大小的文件系统的文件系统之一。这些类型的机制用于加快对目录的访问。挂载磁盘时,缓存的文件也将作为系统文件挂载。 ramfs 的好处是它需要的磁盘内存量非常少。使用正常机制,当 VM 尝试重新分配内存时会删除缓存文件,但使用 ramfs 内存无法被 VM 释放。

根文件

Rootfs 是 ramfs 的一个特殊实例。您无法卸载 rootfs,因为您有并行运行的信号处理程序,可确保系统不会关闭。它用于检查和处理空列表,然后内核更容易确保某些列表不能变空。
Linux 内核包含一个 gzip 压缩的 cpio(它是一个通用的文件归档实用程序)格式的归档文件,它在内核启动时被提取到 rootfs 中。解压后,内核检查 rootfs 是否包含文件“init”,如果是,则将其作为 PID 执行(它是标识操作系统中每个正在运行的进程的唯一编号)。
现在有两种可能,
案例 #1:如果找到,这个 init 进程将负责使系统恢复正常运行,包括定位和安装真正的根设备(如果有)。

案例#2:如果在嵌入的 cpio 归档文件被提取到 rootfs 之后,它不包含一个 init 程序,内核将使用旧代码来定位和挂载一个根分区,然后执行 /sbin/init 的一些变体。那。

与cpio的关系

配置选项 CONFIG_INITRAMFS_SOURCE(在 menuconfig 的 General Setup 中,位于 usr/Kconfig 中)可用于指定 initramfs 存档的源,它将自动合并到生成的二进制文件中。此选项可以指向现有的 gzipped cpio 存档、包含要存档的文件的目录或文本文件规范。配置文件的优点之一是无需 root 访问权限即可在新存档中设置权限或创建设备节点。

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

指导 Initramfs
使用以下代码创建一个 hello.c 文件:

#include 
#include 
 
int main(int argc, char *argv[])
{
  printf("Hello world!\n");
  sleep(999999999);
}

现在给出命令:

gcc -static hello.c -o init
echo init | cpio -o -H newc | gzip > test.cpio.gz 

qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero

当调试一个普通的根文件系统时,能够用“init = /bin/sh”引导是很好的。 initramfs 等效项是“rdinit = /bin/sh”。

我的笔记:我非常生气,因为我即将丢失整个数据,但当我理解为什么需要时,情况并非如此。开源文化给了你学习任何东西的自由,那么你有责任帮助开发它而不是忽视它。开源贡献是你能为社会做的最好的方式,即使你没有被突出,享受当你的代码或贡献受益于缺乏人时的满足感。