Linux 内核如何访问其指定的 initramfs/initrd?

Linux 内核如何访问其指定的 initramfs/initrd?

我试图了解从按下电源按钮起整个机器的启动过程。从引导加载程序到 initramfs 阶段,我不太理解其他一些较小的部分。

给定一个条目的 Grub 配置,取自最近的 Ubuntu 默认安装:

insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 96fb7310-5adb-4f66-bf59-04acd08d76a3
echo    'Loading Linux x.y.z ...'
linux   /vmlinuz-x.y.z root=/dev/mapper/some-device-name ro nomodeset 
echo    'Loading initial ramdisk ...'
initrd  /initrd.img-x.y.z

这对系统状态和内存实际上有什么作用?我知道 Grub 的任务是“加载并运行内核”,它有自己的一组模块来访问设备(或网络)上的文件来获取它们。在这里的例子中insmods, set rootand search- 但这只是从 Grub 的角度来看,并没有与内核共享,对吗?

我还猜测 Grub 正在将内核(副本?)加载到内存中(linux命令)并踢它开始执行。 (显然是两个不同的步骤 - 那么,如何?)给出的参数可以在内核中读取并解释(这是映射到内存中某处的大字符串吗?)并提供安排所请求的内容的选项。

我也看到这个initrd选项。这指向我的 gzip 压缩的 initramfs,需要它来引导 指定的实际根设备root=。但是这个initramfs是如何提供给内核的呢?它不会将任何内存地址传递到可以加载它的位置,也无法自行访问它,因为它在内核启动之前就已经加载了。一些内核文档说这个 initramfs 文件系统“设备”可以通过 访问/dev/ram0,但我不知道它如何成为可访问的设备文件。我猜,水下正在发生一些我看不到的事情。

我也不明白这与其他引导加载程序(包括嵌入式平台)有何关系,例如使用 U-boot/Coreboot。这与 Grub 做同样的事情吗(相同的标准内存地址?)?在加载内核/initrd 方面,这些与 Grub 相比有什么程度?

为了澄清我的问题,我想我确实理解为什么存在不同的启动阶段并且什么转变发生了,但我没有看到如何它们的发生以及每个阶段的确切职责是什么。我有一种感觉,我错过了一些“标准”,而这一切都归结为这一点。

我希望对此有一些解释。

答案1

引导加载程序将 initrd 存储到内存中的某个位置,并告诉内核 initrd 映像的内存地址。大多数现代 Linux 系统都使用初始化文件系统方案使用德拉库特,它实际上是一个 cpio 存档(而不是磁盘映像),在执行后不久就会解压到内核创建的 tmpfs 文件系统中。

答案2

一般来说,必须有某种协议,因为通常仅将文件加载到内存中并跳转到特定位置是不够的,但您必须传递其他参数,例如内核参数,即从 DOS 访问内存磁盘参数

由于这取决于硬件(例如,arm 与 x86 不同),因此您必须找到正确的信息,请参阅这篇关于引导臂的文章或者Linux/x86 启动协议举一些例子。

相关内容