本篇 接 上一篇 《《linux操作系统引导与启动——引导(2)》》
时隔一个多月。我们再总结一下上一篇的核心内容。
想起前两天琢磨openstack的时候,网上一位大牛有一句话留的不错:“用输出来激励自己学习,哪怕学习过程中犯了错”。
一、上一篇总结
从bios/efi 的最后一步 进行OS boot loader开始,一直到OS完全启动,大体经历了以下几个过程:
1、boot loader 中文翻译为操作系统引导(loader)。在linux系统中,又称为grub阶段。
1.1 grub 阶段1
1.2 grub 阶段1.5
1.3 grub 阶段 2,跑起来grub menu。
在BIOS+MBR模式下,grub在硬盘盘头 几个sector处。
在UEFI+GPT模式下,grub程序,成了硬盘EFI分区的 xx.efi文件了。
2、操作系统内核启动(kernel start)也就是启动vmlinuz
3、操作系统内核初始化(vmlinuz load initrd init)阶段。
可恶的是英语中 load, start, init的翻译成汉语总是如此的相似,所以网上很多文章将三者混为一谈,或者各执其意,乱的很。而本篇的定义就此确定。
这里不得不说个题外话,IT圈儿里,像这种多个概念混为一谈的情况,我碰到过很多种,罄竹书写如下:
A、linux 操作系统load, start, init国语资料中不区分的情况。——引导 启动 初始化 不分。
B、网络交换机配置中的trunk的概念,究竟是指“端口tag模式”还是指“静态端口绑定”?动态端口绑定 究竟是指 “lacp静态端口绑定” 还是 “lacp动态端口绑定”?
C、大浪司服务器的BMC SEL log日志里,FSB 这个缩写 究竟是指“x86老的前端系统总线”还是指chipset借用bmc看门狗实现的"Fault System Boot"超时重启机制?
D、Physical address 究竟是指 “主存address”,还是指“主存加PCIE空间的system address”?——一般情况下还好根据上下文区分;但是在说PCIE DMA的时候,就乱套了。
言归正传。
如果用之前的图,来概括启动的三阶段那么就如是:
legacy的这样:
UEFI的这般模样:
如果用逻辑模块来描述三阶段就是这样:
上图中的Boot Loader部分,已经通过前三篇知识贴:
linux操作系统引导与启动——1引导
linux操作系统引导与启动——引导(2)
Linux引导之EFI SHELL详解
解释的差不多了。
今天开始操作系统的内核启动和初始化部分。
二、内核启动阶段
这个阶段,主要是vmlinuz文件加载initrd文件。
其实,整个启动过程中,我最不敢写的就是vmlinuz。因为我不是做内核编程的人。
所以,对于vmlinuz,我也就肤浅的涉及或听说到三个方面:
1、是否和硬件arch兼容。
2、静态内核参数是否应该修改、设置重编译。
至于第三项 3、裁剪。——咱一点都不会。
而通过我抓取的日志和自学总结来看,从vmlinuz角度来看,内核启动和初始化做了以下几件事情:
1、实模式early kernel initial 阶段。
vmlinuz从bios 手里接管 bios已经生成的硬件资源表,初始化架构。
ACPI接口初始化;
STOLEN内存/MEM HOLE的起始终止位置;
numa 内存分布,以及内存zone初始化。
中断架构 lapic + ioapic 初始化;
记录mmio起始/结束地址;
2、保护模式 full kernel initial阶段。PID0阶段。
初始化时间/时钟系统;
创建DMAR表;
操作系统 hardlockup检测狗启动
MMCFG初始化;
MMIO初始化;
解压initrd文件。
3、load initrd/initramfs
二次更新clocksource from hpet to tsc;
初始化pstate;
检测cpu类型,加载cpu revision patch(如果有)。
4、启动systemd init start阶段 PID1.阶段
三、内核初始化阶段
这个阶段我们的视角主要focus在initrd/initramfs文件。
其实vmlinuz文件,是靠安装盘上的源文件、或者是源代码编译而成的,与本机的硬件配置松耦合(与架构相关,与个性化硬件配置无关)。
而initrd文件是安装过程到了最后,安装程序根据本服务器的硬件配置,使用dracut工具将必要的硬件设备(也就是/文件系统 所依赖的硬件设备)生成initrd/initramfs文件。
所谓的dracut 就是具有udev功能的能创建initramfs的工具。
linux initramfs启动过程:
我们接着 从上面的”4.启动systemd init start阶段“说。
systemd其实也分成了前半段和后半段。
前半段和后半段的标志就是 ”switch root file system“。
systemd 的后半段,已是操作系统管理的正常范畴了,本文不再描述。
我们重点看 systemd 的前半段,也就是intird运行中神秘的部分。
systemd 前半段的启动过程如下 从左到右:
阶段和阶段之间(下图左列),initrd为我们提供了 hook断点(下图右列):
而这些hook断点,正是我们可以在grub menu中断时设置的rd.break参数。——若我们正确的设置了rd.break=xxxx,那么intird就会在该断点处中断并进入 shell——这是我们进行initrd启动观察和诊断的重要手段。
下一篇将介绍在不同rd.break参数下,对应的rdsosreport输出。
以及在OS安装或启动过程中,经典的 dracut,或 initqueue报错。