我的问题是关于从单独的/ boot分区引导Linux系统。如果大多数配置文件位于单独的/分区中,内核如何在引导时正确地将其安装?
在这方面的任何阐述都是很棒的。我感觉好像缺少一些基本知识。我最关心的是操作的过程和顺序。
谢谢!
编辑:我想我需要问的是更多的root内核参数中使用的dev文件。例如,假设我将我的根参数设置为root = / dev / sda2。内核如何映射/ dev / sda2文件?
我的问题是关于从单独的/ boot分区引导Linux系统。如果大多数配置文件位于单独的/分区中,内核如何在引导时正确地将其安装?
在这方面的任何阐述都是很棒的。我感觉好像缺少一些基本知识。我最关心的是操作的过程和顺序。
谢谢!
编辑:我想我需要问的是更多的root内核参数中使用的dev文件。例如,假设我将我的根参数设置为root = / dev / sda2。内核如何映射/ dev / sda2文件?
Answers:
Linux最初使用ramdisk(称为initrd
“ INITial RamDisk” 称为ramdisk)引导/
。该磁盘仅具有足够的容量,可以查找实际的根分区(包括所需的任何驱动程序和文件系统模块)。它将根分区挂载到上的临时挂载点initrd
,然后调用pivot_root(8)
以交换根挂载点和临时挂载点,将initrd
位置保留在umount
ed上,并将实际的根文件系统放在上/
。
在远古时代,内核被硬编码为知道根fs的设备主/次编号,并在初始化所有内置在内核中的设备驱动程序之后挂载该设备。该rdev
实用程序可用于修改内核映像中的根设备编号,而不必重新编译它。
最终,引导加载程序出现了,并且可以将命令行传递给内核。如果root=
传递了参数,则会告诉内核根fs而不是内置值在哪里。需要访问的驱动程序仍然必须内置在内核中。尽管该参数看起来像/dev
目录中的普通设备节点,但显然/dev
在挂载根fs之前没有目录,因此内核无法在其中查找dev节点。而是将某些众所周知的设备名称硬编码到内核中,以便可以将字符串转换为设备编号。因此,内核可以识别诸如之类的东西/dev/sda1
,而不能识别诸如/dev/mapper/vg0-root
UUID或卷UUID之类的奇特事物。
后来,initrd
进入了图片。引导程序会与内核一起加载initrd
映像,该映像是某种压缩的文件系统映像(gext ext2映像,romfs压缩映像,squashfs最终成为主导)。内核会将该映像解压缩到ramdisk中,并将ramdisk挂载为根fs。该映像包含一些其他驱动程序和引导脚本,而不是real init
。这些引导脚本执行了各种任务,以识别硬件,激活RAID阵列和LVM之类的东西,检测UUID并解析内核命令行以找到真实的根目录,这些根目录现在可以由UUID,卷标和其他高级东西指定。然后将真正的根fs挂载到/initrd
,然后执行pivot_root
系统调用以进行内核交换/
和/initrd
,然后/sbin/init
在实际根目录上执行,然后将其卸载/initrd
并释放虚拟磁盘。
最后,今天我们有了initramfs
。这类似于initrd
,但它是压缩的cpio归档文件,而不是作为加载到ramdisk中的压缩文件系统映像。将tmpfs挂载为根,然后将归档文件提取到那里。引导脚本不是使用pivot_root
被认为是肮脏的hack,而是initramfs
将真实的根目录装入其中/root
,删除tmpfs根目录中的所有文件,然后删除chroot
至/root
和exec /sbin/init
。
听起来您正在询问内核如何“知道”哪个分区是根分区,而又无法访问/ etc上的配置文件。
内核可以像其他程序一样接受命令行参数。GRUB或大多数其他引导加载程序可以接受命令行参数作为用户输入,或存储它们并通过菜单提供各种命令行参数组合。引导加载程序在加载时将命令行参数传递给内核(我不知道该约定的名称或机制,但可能类似于应用程序从运行中的内核中从调用进程接收命令行参数的方式)。
这些命令行选项之一是root
,您可以在其中指定根文件系统,即root=/dev/sda1
。
如果内核使用initrd,则引导加载程序负责告诉内核它在哪里,或者将initrd放在标准内存位置(我认为),至少这是它在我的Guruplug上的工作方式。
完全可能不指定一个,然后在开始抱怨找不到根文件系统后立即让内核崩溃。
可能还有其他方法可以将此选项传递给内核。
/dev/sda1
因为它是文件系统中的条目。您可以做cp -p /dev/sda1 /tmp/foo
并且/tmp/foo
将代表同一台设备。在内核命令行上,内核使用内置的解析器,该解析器遵循通常的设备命名约定:sda1
表示第一个类似SCSI的磁盘的第一个分区。
initrd
或initramfs
我的意思。它必须是/dev/sdx
形式上的“简单”分区吗?
init/do_mounts.c
。
来吧,GRUB不会“挂载” / boot,它只会读取“ menu.lst”和某些模块,它也不是LINUX内核的一部分。调用内核时,您将通过根分区传递“ root”参数。最糟糕的是,内核知道/ boot已经挂载(LOL)。
下一步:geekosaur是正确的,Linux使用压缩映像格式的初始ramdisk,然后通过调用挂载实际的根文件系统pivot_root
。因此,Linux从映像开始运行,然后从本地磁盘驱动器运行。