Linux 内核如何能够访问其分配的 initramfs/initrd?

ger*_*ijk 9 boot-loader initramfs linux-kernel

我试图从您按下电源按钮的那一刻起了解整个机器的启动过程。从引导加载程序到 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
Run Code Online (Sandbox Code Playgroud)

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

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

我也看到了这个initrd选项。这指向我的 gzip 压缩 initramfs,需要引导由root=. 但是这个initramfs是如何提供给内核的呢?它不会传递任何内存地址到它可以加载它的地方,也不能访问它本身,因为它在内核启动之前已经加载。一些内核文档说这个 initramfs 文件系统“设备”可以通过 访问/dev/ram0,但我不知道它是如何成为一个可访问的设备文件的。我猜我没看到水下发生了什么。

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

为了明确我的问题,我想我确实理解为什么存在不同的启动阶段以及发生了什么转换,但我不明白它们是如何发生的以及每个阶段的确切职责是什么。我觉得我错过了一些“标准”,这一切都归结为。

我将不胜感激对此的一些解释。

jsb*_*ngs 6

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

  • @gertvdijk 看看 http://www.kernel.org/doc/Documentation/x86/boot.txt 它描述了引导加载程序如何与内核通信,即引导加载程序还必须提供内核参数等。 (3认同)

Ulr*_*gel 5

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

由于这取决于硬件(例如,arm 与 x86 不同),您必须找到正确的信息,请参阅有关引导 armLinux/x86 引导协议的文章以获取一些示例。