Linux 内核/启动
当您启动计算机时,内核会做什么?在您启动 GNU/Linux 系统时,登录屏幕出现之前会发生几个主要步骤。按顺序它们是
您的计算机固件/BIOS(基本输入输出系统)是一个小型计算机程序,当您的系统通电时,它的起始地址会被加载到计算机 CPU 的程序计数器寄存器中。固件/POST(加电自检)会对您的计算机系统执行一些基本的测试(通常是内存检查,包括可能使用条纹内存筛查例程检查您的内存,检查您的系统上是否有键盘、鼠标、硬盘驱动器等。然后,它会遍历一个用户定义的设备列表,查找一个名为引导加载程序的小程序。设备列表可以是 CD-ROM、DVD 驱动器、硬盘驱动器等。当它找到引导加载程序时,它会将引导加载程序的起始地址加载到 CPU 的程序计数器寄存器中。
Linux 引导加载程序可以是 LILO,或者现在更常见的是 GRUB。引导加载程序可能只有一个操作系统要启动,或者它可能有多个,如果有多个,它会列出要加载的系统。操作系统不必是 GNU/Linux。
如果选择了 GNU/Linux 操作系统,并且系统在 Intel X86/32 硬件上,那么引导加载程序在“真实”x86 模式下运行(运行方式就像 CPU 是 8086 一样),即使处理器可能是 Pentium 4/Celeron/Xeon。
引导加载程序的工作是重置所有 CPU 寄存器,将操作系统加载到内存中,并通过将起始地址加载到 CPU 的程序计数器中启动它。由于 Intel 8086 无法支持超过 640k 的内存,而现代 Linux 内核大于 640k,因此使用特殊的跳转指令(跳板)将压缩的 Linux 内核(称为 zImage)加载到内存中。
引导加载程序加载了几个程序来帮助它完成这项工作,包括 setup.S 和 system。
setup.S 负责从 BIOS 获取系统数据,并将其放到系统内存中的适当位置。setup.S 向 BIOS 请求内存、磁盘和其他参数,并将自身和系统从加载它的低内存位置重新定位到一个“安全”位置:0x90000-0x901FF (INITSEG),即引导块曾经存在的位置。然后,setup.S 在起始地址 0x10000 或 64K 处解压缩压缩的 (zImage) 内核映像,就在固件数据空间 (SYSSEG) 之后。然后,它将解压缩的内核从地址 0x10000 移动到地址 0x1000(4k,留下一个低内存页面),从“真实”x86 模式切换到 emm386 模式,并将内核的起始地址加载到 CPU 的程序计数器寄存器中(启动内核运行)。
setup.S 所做的最后一件事之一是运行视频设置和检测代码,video.S。将内核在内存中来回移动是为了克服 PC BIOS 内存寻址的限制(640k),并释放数百 KB 的系统内存(实际释放的内存量由系统报告)。4k 用于处理虚拟内存。特殊的加载指令(跳板)是用来“欺骗”系统的,因为这些指令将内核的一部分加载到超过 (当时正在运行的“真实模式”) 系统知道的 640k 限制的内存位置。在将内核来回移动的过程中,BIOS 最初写入的内存,以及 setup 和 system 程序被加载到的内存会被内核映像覆盖,因此需要将它们移动到一个安全的地方,超出解压缩内核映像被加载的地方。实际的加载在 x86 系统上稍微复杂一些,因为并非所有 BIOS 都在相同的寄存器上报告它们的内存,以不同的方式报告信息,或者以非传统的方式映射它们的内存/系统资源。此外,某些 BIOS 可能需要多次被提醒提供信息,或者存在 A20 门问题。
其他计算机架构可能没有 Intel x86 处理器的限制,因此加载 Linux 内核的方式要简单得多。