Linux学习笔记:系统启动引导过程

时间:2022-04-18 15:35:02

Linux系统启动引导过程

最近发现自己在只是掌握上有几个比较硬的伤:

  • 一、知识体系碎片,比如Linux,这学点那学点,结果没有成体系,串不起来;

  • 二、记忆时间短暂,很多的内容学了就忘,最后的结果是遇见一个知识点就能想起来自己的确学过,但是现在记不起来了。

  • 三、理解程度浅显,比如说今天要整理关于Linux引导的内容,之前大体是知道的,不能称之为理解,我认为在学着一个知识点的时候至少要能系统有条理地讲出来,而不是有个模模糊糊的大体认识。

个别名词解释

1.BIOS(Basic Input Output System):基本输入输出系统。其实,它是一组固化到计算机内主板上一个ROM芯片上的程序,它保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序,它可从CMOS中读写系统设置的具体信息。

2.MBR(Master Boot Record):主引导记录。硬盘的0柱面、0磁头、1扇区称为主引导扇区(也叫主引导记录MBR)。

MBR是不属于任何一个操作系统,也不能用操作系统提供的磁盘操作命令来读取它,但可以通过命令来修改和重写。

3.GRUB(GRand Unified Bootloader):GNU GRUB是一个来自GNU项目的多操作系统启动程序。GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。

Linux引导过程预览

从按下电源键后执行的操作:

Created with Raphaël 2.1.0 按下电源键 加载BIOS 读取MBR Boot Loader Boot Loader 用户层init依据inittab文件来设定运行等级 init进程执行rc.sysinit 启动内核模块 执行不同运行级别的脚本程序 执行/etc/rc.d/rc.local 执行/bin/login程序,进入登录状态 开机完成

详细分析引导过程

第一步、加载BIOS

BIOS的功能由两部分组成,分别是POST码和Runtime服务。POST阶段完成后它将从存储器中被清除,而Runtime服务会被一直保留,用于目标操作系统的启动。BIOS两个阶段所做的详细工作如下:

  1. 步骤1:上电自检POST(Power-on self test),主要负责检测系统外围关键设备(如:CPU、内存、显卡、I/O、键盘鼠标等)是否正常。例如,最常见的是内存松动的情况,BIOS自检阶段会报错,系统就无法启动起来;

  2. 步骤2:步骤1成功后,便会执行一段小程序用来枚举本地设备并对其初始化。这一步主要是根据我们在BIOS中设置的系统启动顺序来搜索用于启动系统的驱动器,如硬盘、光盘、U盘、软盘和网络等。我们以硬盘启动为例,BIOS此时去读取硬盘驱动器的第一个扇区(MBR,512字节),然后执行里面的代码。实际上这里BIOS并不关心启动设备第一个扇区中是什么内容,它只是负责读取该扇区内容、并执行。
    至此,BIOS的任务就完成了,此后将系统启动的控制权移交到MBR部分的代码。

第二步、读取MBR

系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。其实被复制到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是lilo或者grub了。

补充:

一个扇区的硬盘主引导记录MBR由4个部分组成。

  1. 主引导程序(偏移地址0000H–0088H),它负责从活动分区中装载,并运行系统引导程序。

  2. 出错信息数据区,偏移地址0089H–00E1H为出错信息,00E2H–01BDH全为0字节。

  3. 分区表(DPT,Disk Partition Table)含4个分区项,偏移地址01BEH–01FDH,每个分区表项长16个字节,共64字节为分区项1、分区项2、分区项3、分区项4。

  4. 结束标志字,偏移地址01FE–01FF的2个字节值为结束标志0xAA55或0x55AA,称为“魔数”(magic number)。如果该标志错误系统就不能启动。

第三步、Boot Loader

Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。Boot Loader有若干种,其中Grub、Lilo是常见的Loader。系统读取内存中的grub配置信息(一般为menu.lst或grub.lst),并依照此配置信息来启动不同的操作系统。

第四步、加载内核

根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出“Uncompressing Linux”的提示。当解压缩内核完成后,屏幕输出“OK, booting the kernel”。

系统将解压后的内核放置在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来,基于Linux的程序应该可以正常运行。

第五步、用户层init依据inittab文件来设定运行等级

内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。

/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。Linux的运行等级设定如下:

  • 0:关机
  • 1:单用户模式
  • 2:无网络支持的多用户模式
  • 3:有网络支持的多用户模式
  • 4:保留,未使用
  • 5:有网络支持有X-Window支持的多用户模式
  • 6:重新引导系统,即重启

第六步、init进程执行rc.sysinit

在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。

第七步、启动内核模块

具体是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块。

第八步、执行不同运行级别的脚本程序

根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。

第九步、执行/etc/rc.d/rc.local

你如果打开了此文件,里面有一句话,读过之后,你就会对此命令的作用一目了然:

This script will be executed after all the other init scripts.
You can put your own initialization stuff in here if you don’t
want to do the full Sys V style init stuff.

rc.local就是在一切初始化工作后,Linux留给用户进行个性化的地方。你可以把你想设置和启动的东西放到这里。

第十步、执行/bin/login程序,进入登录状态

此时,系统已经进入等待用户输入username和password状态,用户可以用自己的帐号登入系统