给定 vmlinuz 和 initrd.gz,我如何知道内核将从哪里加载 /(根)文件系统?

给定 vmlinuz 和 initrd.gz,我如何知道内核将从哪里加载 /(根)文件系统?

我正在尝试各种 Linux 安装方式(从 iso、flash、flash 上的 iso、flash 上的内核、flash 上的 iso 文件中的 root FS...),并想了解发生了什么。

我的问题是:考虑到来自发行版(vmlinuz 和 initrd)的构建内核和 ramfs 文件,是否有可能找出它们将在哪里查找“/”文件系统?是否可以在不重新编译内核的情况下进行配置?

还有一个:当内核从 .iso 文件系统创建的环回设备加载根文件系统时,我如何配置这个过程?谢谢!

编辑: 事实上,GRUB配置包含GRUB root,即不是真正的内核根文件系统位置,但只是一个包含 GRUB 内容的文件夹。

init真正的根在脚本中配置,initrd如所述这里

这就是 Debian 内核在从硬盘启动时找到 ISO 文件的方式 - initramfs 找到它:http://www.debian.org/releases/stable/i386/apas02.html.en#howto-getting-images-hard-disk;注意 GRUB 配置不包含任何对 ISO 位置的引用

答案1

它是在启动时由您给出的引导装载程序,例如 Grub。

要查看您的内核是使用哪些参数启动的,请执行以下操作:

$ cat /proc/cmdline

对我来说,这个输出:

BOOT_IMAGE=/vmlinuz-3.5.0-13-generic root=/dev/mapper/crypt-precise--root ro

因此 initrd/initramfs 将尝试将我的/dev/mapper/crypt-precise--root(加密的 LVM)逻辑卷挂载为/.

您可以重新配置 Grub 以使用相同的内核(多重引导)从硬盘加载其他操作系统,或者通过e在选择(尚未引导)Grub 条目时按 来编辑此行运行时。

对于最近基于 Debian 的发行版,永久更改它的方式如下:
(小心,您可能无法再次启动到原来的操作系统!)

在文件中自行/etc/default/grub设置一些内容GRUB_CMDLINE_LINUX="root=/dev/mydevice"并通过执行以下操作更新 Grub update-grub

但是,我建议您配置多重引导,否则无法轻松更改或更新您的 Grub 配置。

答案2

给定启动映像,您可以使用file命令找到内部内核版本字符串:

%> file /boot/vmlinuz-linux
/boot/vmlinuz-linux: Linux kernel x86 boot executable bzImage, version 3.5.3-1-NAME (X@Y) #1 SMP PREEMPT WEEK MON DAY, RO-rootFS, swap_dev 0x5, Normal VGA

答案3

在大多数安装中,您为引导加载程序指定根设备。根设备作为名为 的参数传递给内核root。根据引导加载程序,这可能是内核命令行参数的一部分(可能看起来像ro quiet root=/dev/sda1)或单独的设置。对于一些常见的引导加载程序:

  • Lilo:在配置文件(/etc/lilo.conf)中,有一个root指示 Linux 根设备的指令。
  • Grub 旧版(版本 0.9x):在配置文件(通常)中,根设备作为内核命令行(指令)/boot/grub/menu.lst的一部分传递。请注意, Grub 本身kernel有一个不同的指令;root它告诉 Grub 在哪里寻找文件,例如内核。在许多系统上,Grub 配置文件是由update-grub脚本生成的,该脚本从已安装的系统中填充根设备(使用/boot/grub/device.map)。
  • Grub 2(版本 1.9x):在配置文件(通常)中,根设备作为内核命令行(指令)/boot/grub/grub.cfg的一部分传递。linux请注意,有一个不同的root变量 ( set root=(hd0,1)) 告诉 Grub 在哪里查找文件(例如内核)。在许多系统上,Grub 配置文件是由update-grub脚本生成的,该脚本从已安装的系统中填充根设备(使用/boot/grub/device.map)。
  • U-Boot:根设备作为命令行参数的一部分传递到bootargs环境变量中。 U-Boot 二进制文件包含编译时内置的默认值,可以通过闪存中的设置覆盖该默认值(如果设备允许)。

在没有root命令行参数的情况下,initrd 或 initramfs(如果使用)可能会尝试查找要挂载的根分区。即使存在root参数,initrd 或 initramfs 也可能决定使用不同的设备。代码调用switch_root从 initrd 切换到实际根目录。

没有root命令行参数时的默认根设备是在编译时确定的。您可以使用以下命令更改二进制图像中的该值rdev公用事业。

在启动的内核上,您可以root在 中看到传递给内核的参数(如果有)/proc/cmdline。您可以/在 中看到安装的实际设备/proc/mounts

答案4

不确定这是否仍然令人感兴趣,但为了像我这样的未来谷歌用户:

root从 grub 引导/安装时有两个单独的目录在起作用。有的是蛴螬根linux根目录(我不确定这是否是技术术语)。


蛴螬根可以在 中设置grub.cfg,并确定哪些文件在 grub 中可见。默认 grub 根目录应该是引导 grub 的驱动器的根目录,因此如果可引导驱动器的内容是:

/boot/
/boot/grub2/
/boot/grub2/grub.cfg
...

然后 grub.cfg 的位置蛴螬根/boot/grub2/grub.cfg

可以使用 在 grub.cfg 中更改 grub 根目录set root=

您可以使用它将根目录设置为当前根目录中的目录(set root=/boot/将导致grub.cfg位于/grub2/grub.cfg),其行为类似于chrootLinux 中的 a 。

您还可以将当前根目录更改为另一个驱动器(set root=(hd0,1)将您的根目录设置为 hd0,分区 1。有关您可以使用的设备的完整列表,请参阅有关它的 grub 页面http://www.gnu.org/software/grub/manual/grub.html#Device-syntax)。

虽然更改 grub 根目录可能很有用,但您也可以在任何路径前添加您要使用的任何路径(例如,linux (hd0,1):/boot/OS/RHEL/isolinux/vmlinuz而不是set root=(hd0,1)第一个)。还,一旦内核启动,grub root 就无关紧要了


至于Linux根目录,这是加载内核(vmlinuz)时可以传递的参数。为此,您可以向内核传递一个参数root=(该值将出现在 /proc/cmdline 中)

但值得注意的是,这个新根目录预计将包含 Linux 根文件系统(查找 /etc/ /var/ 等)。安装时,您提供包含这些元素的 initrd(INITial Ram Disk),因此您可能不想/不需要在安装过程中更改 Linux 根目录。

如果您确实更改了 Linux 根目录,请注意 Linux 安装介质不是 Linux 根文件系统,尽管其中包含的 initrd.img 是。


如果您想要做的是使用 iso 中的文件作为内核的参数,那么有一个解决方案。如果您在 grub 中创建一个环回设备,该设备将在内核启动时持续存在(因此您应该看到一个/dev/loop0Linux根目录安装期间)

我将给出与 ISO 和 RHEL 特别相关的 grub.cfg 的一小段:

menuentry "RHEL" {
    set isofile='/boot/iso/RHEL.iso' #this is just a grub variable

    loopback loop $isofile           #mount the $isofile with label=loop as a loopback device

    set root=(loop)                  #set the grub root to the mounted iso (so / is the top level directory in the iso)

    #this starts the kernel and passes the paramter inst.stage2 using the ISO and kickstart as a location on the loopback device created by grub (the syntax for this line is liable to change between distros)
    linux /isolinux/vmlinuz noeject inst.ks=hd:/dev/loop0:/ks/ks.cfg inst.stage2=hd:LABEL=USBDRIVELABEL:/$isofile  

    initrd /isolinux/initrd.img      #provide an initial ramdisk (which will become the **Linux root**
}

请注意 grub.cfg 中内核行的语法是:

linux [path to kernel] [kernel argument 1] [kernel argument 2] ...

内核参数将全部出现在/proc/cmdline.需要注意的是,因为它们是由内核处理的 grub 语法是无效的。

您可以在 grub 文档中找到更多相关信息(http://www.gnu.org/software/grub/manual/grub.html#Introduction

和内核参数 archwiki 页面(https://wiki.archlinux.org/index.php/kernel_parameters#GRUB

以及相关发行版的启动选项(RHELhttps://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/chap-anaconda-boot-options.html#list-boot-options-sources

相关内容