前言
沙子龙的镳局已改成客栈。东方的大梦没法子不醒了。---- 老舍《断魂枪》
云计算大潮到来了,我把IT技术像五虎断魂枪一样收起来了。我不会将它压到箱底,偶尔我也会练练聊聊,纪念一下那个搞技术的黄金时代。
本文聊个很有嚼头的技术问题,Linux系统的启动过程,当我们不用自己安装系统以后,丧失了这么多乐趣。
正文
主板加电和硬件自检,就是开机第一屏启动界面。
CPU和内存插得有问题服务器会滴滴乱叫,而网卡和硬盘插不插都无所谓,因为这些外设都不属于经典的计算机系统。
早期小内存服务器一般有内存检测的功能,但256G内存的服务器启动的速度也太慢了,重启一分钟能启动的服务还能恢复,重启三分钟可能群集性状就变了,所以我们经常顺手就把他关掉了。
2. 读取主板引导配置,现在终于要从外部设备读取数据了。
主板大都是BIOS引导,也有是UEFI引导,但从服务器用户看区别也不大。
主板可选从USB/SATA/NIC这几类接口上获取引导数据,而且可以排队式加载,第一个加载不成功就尝试第二个。系统安装镜像都有个防止误操作的倒计时,而网络引导一般是排在末位,硬盘引导就是通用的系统启动的方式。
爱折腾桌面电脑的朋友从这一步开始就玩双系统/WINPE/U盘版Ubuntu/无盘工作站了,还好服务器维护人员比较单纯专一。
3. 读取MBR(可略过)。
如果是BIOS启动,做为一个老古董它只能会去读MBR,MBR去读取GRUB;而UEFI略过MBR,直接读取GRUB。
BIOS将启动权限交给MBR的446字节,而446字节连Linux启动界面的logo都装不下,MBR也只是个搬运工,会将启动权限交给GRUB。
遇到过几次倒霉事以后,我习惯用dd备份每台服务器的前512字节,但自从我做完备份以后,就再也没倒霉过。
##不好意思没图
4. GRUB引导启动vmlinuz内核。
GRUB2如果细说有stage1、stage1.5、stage2多个步骤,我们可以简单认为前面两步是为了苟到stage2加载为止。
我们用GRUB来选定要加载的内核,并向其传递大量启动参数,这样就可以在多OS、多Kernel、多runlevel之间来回切换。网上的GRUB调试教程都集中在这一步,我们还可以直接传参以单用户模式启动,直接无密码登陆服务器。
有些人习惯给/boot一个128M的小分区,可能是老师的老师说过这样比较“安全”。那是在更早的版本GRUB程序读不了GB级磁盘分区,没办法加载vmlinuz内核,现在已经只是一个迷信而已。
5. 内核启动加载驱动,但这还没触及任何业务。
不同硬件同一个版本的vmlinuz内核hash值是相同的,因为驱动信息放在initrd*.img里。Initrd*.img是一个精简但带了所有驱动的linux镜像,一般系统安装完之后自动生成,也可以事后手动生成。
曾经某偏门软件推荐用集成镜像安装,装完了就是起不来,我把同内核版本、同硬件配置的init*.img替换以后系统就正常启动。
Kernel加载了所有驱动后就会卸载initrd*.img,早期linux版本在系统启动过程中还能看到很多“umount filesystem”的提示,那不是卸载正式文件系统,而是卸载了initrd*.img这个迷你系统,
##不好意思没图
6. Init进程启动,服务正式启动。
从看到“Welcome use CentOS”的彩色欢迎文字开始,init服务已经启动了。
在这之前的启动过程也就读取BIOS/MBR/GRUB和/boot分区,现在终于开始读/etc目录的配置文件了。
首先被读取到的是/etc/fstab,各个磁盘都挂载就位。这个文件注释很简单但水很深,我们该用标签还是UUID来标识磁盘,文件系统自检功能要不要开,这都可以聊好几个小时。
看看各服务的启动优先级也是一个讲究多多的过程,iptables会比network先启动这类依存关系很好理解;但我也遇到过云平台的DHCP获取太慢,而云主机操作系统启动快、Network还没从DHCP那里获取到IP地址,然后Mysqld等需要监听端口的服务启动失败。
后记
以上内容只能算精简科普版的Linux系统启动过程,正式版的启动过程可以写十万字,有兴趣的朋友可以自己查维基百科,或拿我说的关键字去百度搜索。
曾经我把这些技能当做资历,但现在大家都上云了,它们就只是闲聊的谈资了。但客户上云就能少招一个研究这事的工程师,上云确实也很有意义啊。
夜静人稀,沙子龙关好了小门,一气把六十四枪刺下来;而后,拄着枪,望着天上的群星,想起当年在野店荒林的威风。叹一口气,用手指慢慢摸着凉滑的枪身,又微微一笑,“不传!不传!” ---- 老舍《断魂枪》