LIinux操作系统的启动过程 ——学习和实践

目录

1.启动过程概括

1.1 加载BIOS(Basic Input Output System),硬件自检。

1.2 启动引导管理器

1.3 加载内核与镜像文件系统

1.4 初始化系统以及加载服务

2. BIOS自检阶段

3. 启动引导管理器阶段

3.1 GRUB

3.1.1 GRUB介绍

3.1.2 GRUB的基本组成部分和作用(非grub2)

3.1.3 GRUB核心文件的分布以及加载方法(非grub2)

3.2 GRUB2

3.2.1 grub2介绍

3.2.2 grub2中的img文件

3.2.3 grub2加载流程

3.4 操作grub shell

3.5 grub配置文件

3.3. GRUB2使用实践——安装双系统

4.内核与镜像文件系统的加载

5. 系统初始化及服务加载

5.1 init进程

5.2 systemd

5.3 系统启动流程

5.4 通过systemd实现开机自动挂载

6. 参考资料


1.启动过程概括

计算机启动过程大致可以分为四个阶段:

1.加载BIOS,硬件自检。(UEFI作为BIOS的后继者和取代者已经广泛使用,但是各种资料都是BIOS)

1.1 加载BIOS(Basic Input Output System),硬件自检。

1. 打开计算机电源时,计算机首先加载主板BIOS信息。BIOS执行程序存储在ROM中,当CS:IP(x86架构)指向该程序的起始位置时,BIOS开始执行。

2. BIOS进行服务器硬件环境自检(POST:Power On Self Test)和硬件初始化;

3. 按照设定的顺序搜索处于处于活动状态并可引导的设备,从第一个设备的第一个扇区加载MBR(主引导记录),执行引导程序。

1.2 启动引导管理器

加载和运行系统启动引导管理器(grub2)。

1.3 加载内核与镜像文件系统

1) 确定启动分区;

2) 在启动分区中,根据启动引导管理器的预设或临时配置加载内核文件、镜像文件系统;

3) 加载镜像文件系统中基本的设备驱动,识别和自动挂载根等文件系统。例如加载了磁盘驱动,从而识别磁盘以及磁盘上的分区和文件系统,可以在文件系统上找到后续启动过程所需要的文件和配置。。

1.4 初始化系统以及加载服务

1) 启动init(RHEL 6.x)或systemd(RHEL 7.x)进程;

2) 执行系统初始化sysinit脚本(RHEL 6.x)或systemd的服务单元(RHEL 7.x);

3) 进入指定的运行级别(RHEL 3-6)或模式(RHEL 7-8);

4) 启动相关服务;

5) 开启服务。

2. BIOS自检阶段

在该阶段中BIOS将执行基本的硬件环境的自检和初始化,并移交启动引导管理权至下一阶段。

BIOS基本概念:

1) 位于系统CMOS ROM(只读存储器)内的微型操作系统;

2) CMOS是一种类型的EPROM(可擦除编程只读存储器);

3) 大多数BIOS都可通过特殊的开机按键进入(F10、F1、F2);

BIOS基本作用:

1) BIOS代码包括两个部分——POST和Run Time;

2) POST(Power On Self Test)代码对服务器硬件环境执行基本检查;

3) Run Time代码用于基本操作系统启动;

4) 为键盘、视频设备、串行口初始化核心设备驱动并分配资源;

5) 根据CMOS的设定顺序搜索处于活动状态的并可引导的设备(软盘、硬盘、CD-ROM、PXE);

6) 将磁盘第一个扇区(512字节)装入内存并传递引导权到该区域。(引导盘的第一个数据块都包含一个可执行文件——引导程序)。

UEFI——可扩展固件接口(Unified Extensible Fireware Interface)

现代计算机主板上都集成了UEFI固件;

更好地支持GPT分区以及2TB以上硬盘;

更快地启动速度以及更多功能扩展。

3. 启动引导管理器阶段

编制本文时刚开始查找到的grub资料,要么只介绍grub,要么只介绍grub2,搞得我一头懵逼(咋查到的资料不一样呢)。所以本文将先后介绍grub和grub2。grub大抵是不怎么用了,也没必要详细地了解,知道有这么回事就行了。要直接了解grub2可以直接跳转到3.2节。

3.1 GRUB

3.1.1 GRUB介绍

  • BIOS通过访问磁盘主引导记录(MBR)来加载启动引导管理程序(GRUB)。

     1) MBR位于磁盘上0磁道0柱面1扇区的前446字节,后64字节为分区表,2字节签名信息;

      2) MBR的头446字节通常用于装载系统引导程序GRUB的部分代码(stage 1)并执行。

  • 通过运行启动引导管理程序来获取和加载必须的启动信息(启动分区位置、内核文件位置、镜像文件系统位置以及相关选项)。
  • Linux系统中最常用的多重启动引导管理程序为GRUB(GRand Unified Bootloader)。

      1) 有GRUB和GRUB2两个版本;GRUB2支持更多的功能。

      2) GRUB或GRUB2的部分内容会被安装在磁盘主引导记录MBR中。

3.1.2 GRUB的基本组成部分和作用(非grub2)

stage1

  • stage1由GRUB源码的Stage1.S汇编生成,默认将被安装到磁盘MBR的前446字节内;
  • BIOS自检完成后会将stage1载入内存执行,标志着该阶段开始;
  • stage1唯一作用:将磁盘0磁道0柱面2扇区装载到内存中执行。

start.S

  • 位于0磁道0柱面2扇区;
  • 由GRUB源码Start.S汇编得到;
  • Start.S的作用:

        1) 读取0磁道0柱面3扇区至N扇区的位置到内存(取决于文件系统支撑代码大小);

        2) 作为进入和访问stage1_5或stage2的入口;

            如果加载stage1_5,则可通过文件系统而非硬件跳转来访问stage2;

            如果不加载stage1_5,则通过硬件跳转而非文件系统方式来访问stage2.

        3) 而系统默认将使用INIT 13中断通过硬件跳转来访问GRUB主要功能(stage2).

stage1_5:

        通常安装于磁盘0磁道0柱面3扇区之后到文件系统的位置;

        stage1_5提供文件系统识别能力,支持通过文件系统访问stage2,是stage1和stage2之间的桥梁;

        尽管stage1_5会被安装,但现代Linux操作系统绝大多数情况下将跳过stage1_5而直接执行和使用stage2;

        只有手动安装grub的情况下才会先通过stage1_5获得访问文件系统能力,并通过文件系统访问stage2以及其他信息。

stage2

提供了GRUB的所有功能,包括GRUB启动菜单和交互的GRUB shell以实现GRUB操作管理;

用于管理GRUB配置文件grub.conf,自动和手动加载内核、ramdisk镜像文件系统等工作;

GRUB/GRUB2配置文件

  • /boot/grub/grub.conf,/boot/grub2/grub.cfg;
  • 用以定义启动分区、内核文件、镜像文件和根文件系统位置;
  • 定义多系统启动引导参数。

3.1.3 GRUB核心文件的分布以及加载方法(非grub2)

GRUB会在系统安装的最后阶段写入磁盘,并且可以选择安装在磁盘或者分区头部。

GRUB默认情况下会被安装在磁盘头部(例如/dev/sda):

stage1安装到启动盘的MBR中;

start.S位于0磁道0柱面2扇区;

stage1_5安装于磁盘0磁道0柱面3扇区之后到文件系统的位置。

3.2 GRUB2

3.2.1 grub2介绍

grub2使用img文件,不再使用grub中的stage1、stage1_5和stage2。   

grub2将boot.img转换后的内容安装到MBR中的boot_loader部分,将diskboot.img和kernel.img结合成为core.img,同时还会嵌入一些模块或加载模块的代码到core.img中,然后将core.img转换后的内容安装到磁盘的指定位置处。

3.2.2 grub2中的img文件

这部分内容主要来自:grub2详解(翻译和整理官方手册)-CSDN博客

grub2生成了几个img文件,有些分布在/usr/lib/grub/i386-pc目录下,有些分布在/boot/grub2/i386-pc目录下。

boot.img

在BIOS平台下,boot.img是grub启动的第一个img文件,它被写入到MBR,因为boot sector的大小是512字节,所以该img文件的大小也是512字节。

boot.img唯一的作用是读取属于core.img的第一个扇区并跳转到它身上,将控制权交给该扇区的img。由于体积大小的限制,boot.img无法理解文件系统的结构,因此grub2-install会将core.img的位置硬编码到boot.img中,这样就一定能找到core.img的位置。

core.img

core.img根据diskboot.img、kernel.img和一系列的模块被grub2-mkimage程序动态创建。core.img中嵌入了足够多的功能模块以保证grub能访问/boot/grub,并且可以加载相关的模块实现相关的功能,例如加载启动菜单、加载目标操作系统的信息等,由于grub2大量使用了动态功能模块,使得core.img体积变得足够小。

diskboot.img

如果启动设备是硬盘,core.img第一个扇区的内容就是diskboot.img。diskboot.img的作用是读取core.img中剩余的部分到内存中,并将控制权交给kernel.img,由于此时还不识别文件系统,所以将core.img的全部位置以block列表的方式编码,使得diskboot.img能够找到剩余的内容。

该img文件因为占用一个扇区,所以大小为512字节

cdboot.img

如果启动设备是光驱(cd-rom),core.img第一个扇区的内容就是cdboot.img。它的作用和diskboot.img一样。

pexboot.img

如果是从网络的PXE环境启动,core.img第一个扇区的内容就是pxeboot.img。

kernel.img

kernel.img文件包含了grub的基本运行时环境:设备框架、文件句柄、环境变量、救援模式下的命令行解析器等。很少直接使用它,因为它们已经嵌入到了core.img中。注意,kernel.img是grub的kernel,和操作系统的内核无关。大小约28k。

*.mod

各种功能模块,部分模块已经嵌入到core.img中,或者会被grub自动加载,但有时也需要使用insmod命令加载。

3.2.3 grub2加载流程

本节主要来自《Linux操作系统学习——启动.md》。

boot.img由boot.S编译而成,512字节,安装在启动盘的第一个扇区,即MBR。由于空间有限,其代码十分简单,仅仅是起到一个引导的作用,指向后续的核心镜像文件,即core.img。core.img包括很多重要的部分,如lzma_decompress.img、diskboot.img、kernel.img等,结构如下图。

整个加载流程如下:

1、boot.img加载core.img的第一个扇区,即diskboot.img,对应代码为diskboot.S
2、diskboot.img加载core.img的其他部分模块,先是解压缩程序 lzma_decompress.img,再往下是 kernel.img,最后是各个模块 module 对应的映像。这里需要注意,它不是 Linux 的内核,而是 grub 的内核。注意,lzma_decompress.img 对应的代码是 startup_raw.S,本来 kernel.img 是压缩过的,现在执行的时候,需要解压缩。
3、加载完core之后,启动grub_main函数。
4、grub_main函数初始化控制台,计算模块基地址,设置 root 设备,读取 grub 配置文件,加载模块。最后,将 GRUB 置于 normal 模式,在这个模式中,grub_normal_execute (from grub-core/normal/main.c) 将被调用以完成最后的准备工作,然后显示一个菜单列出所用可用的操作系统。当某个操作系统被选择之后,grub_menu_execute_entry 开始执行,它将调用 GRUB 的 boot 命令,来引导被选中的操作系统。
   在这之前,我们所有遇到过的程序都非常非常小,完全可以在实模式下运行,但是随着我们加载的东西越来越大,实模式这 1M 的地址空间实在放不下了,所以在真正的解压缩之前,lzma_decompress.img 做了一个重要的决定,就是调用 real_to_prot,切换到保护模式,这样就能在更大的寻址空间里面,加载更多的东西。

  开机时的16位实模式与内核启动的main函数执行需要的32位保护模式之间有很大的差距,这个差距谁来填补?head.S做的就是这项工作。就像 kernel boot protocol 所描述的,引导程序必须填充 kernel setup header (位于 kernel setup code 偏移 0x01f1 处) 的必要字段,这些均在head.S中定义。在这期间,head程序打开A20,打开pe、pg,废弃旧的、16位的中断响应机制,建立新的32位的IDT……这些工作都做完了,计算机已经处在32位的保护模式状态了,调用32位内核的一切条件已经准备完毕,这时顺理成章地调用main函数。后面的操作就可以用32位编译的main函数完成,从而正式启动内核,进入波澜壮阔的Linux内核操作系统之中。

3.4 操作grub shell

当系统正常加载GRUB后,下一步的启动需要依靠GRUB指定必要的配置信息:

  • 内核和镜像文件系统所在分区
  • 内核文件名称和位置、根文件系统位置、根文件系统挂载方式以及其他启动选项。
  • 镜像文件系统名称和位置。

启动系统时当出现grub菜单界面,通过按“c”可进入grub shell指定启动信息。

(补充操作图)

3.5 grub配置文件

grub2配置文件中的部分关键字

default=N 使用第几个启动项

timeout=5 启动项菜单停留时间

3.3. GRUB2使用实践——安装双系统

排查某个性能问题过程中,需要修改内核为可抢占模式和原生系统(CPU不可抢占)进行IO性能对比测试。

1. 修改linux源码下.config,设置可抢占式为yes,在Makefile文件中在版本号中添加一些字符避免和原系统的版本号一致,我这里添加的就是_jr。

2. 编译内核(make -j 88)、打包成rpm包make binrpm-pkg;

3.在/root/rpmbuild/RPMS/x86_64获取打包完成的kernel-xxx_jr.x86_64.rpm

4. 使用命令rpm -ivh kernel-xxx.x86_64.rpm将编译的新系统安装到机器上。可以看到/boot目录下增加了一个系统配置文件config-xxx_jr.x86_64、镜像文件initramfs-xxx_jr.x86_64.img、内核文件vmlinuz-xxx_jr.x86_64。在/lib/modules下多了一个目录xxx_jr.x86_64,其中包括了编译出的各模块的ko。

5.在grub2配置文件/boot/grub2/grub.cfg中新增一个menuentry项,将其中关键字linux设置为vmlinuz-xxx_jr.x86_64,修改menuentry的名称,将关键字initrd设置为initramfs-xxx_jr.x86_64.img,将关键字timeout增大为10便于在启动到grub菜单界面时来得及选择启动项。

6.重启机器,在启动到grub菜单界面时,选择我们新建的启动项,计算机便会加载我们新编译的内核和模块。

4.内核与镜像文件系统的加载

内核加载阶段的主要工作:

  1. 内核文件被解压;内核被装载到内存中并执行初始化;
  2. 挂载镜像文件系统并以只读的方式加载其中的静态驱动模块;
  3. 加载基本的设备驱动和文件系统后,退出镜像文件系统,识别和挂载真正的根分区。

系统内核文件:

通过kernel包安装,位于/boot目录下,命名命名:vmlinuz-<version>。加载并执行内核后,系统将具有进程管理、内存管理等核心能力。

系统镜像文件系统

  • 命名initramfs-<version>.img,kernel安装之后通过dracut建立。在linux系统上通过命令"rpm -qa --scripts kernel"可以查看到rpm的postinstall阶段中有以下命令:/sbin/new-kernel-pkg --package kernel --mkinitrd --dracut --depmod --update 5.10-xxx.xx"。这个命令就会在/boot目录下产生initramfs-xxx.img。
  • 镜像文件系统中包含了一些基本的设备驱动、文件系统ko文件,通过安装这些模块,内核可以获得基本的访问磁盘、网卡设备的能力,例如包含有:iscsi、ext4、device_mapper等模块。

5. 系统初始化及服务加载

5.1 init进程

历史上,Linux 的启动一直采用init进程(1号进程)。可以通过以下命令启动服务:

/etc/init.d/apache2 start

service apache2 start

不过这种方法有两个缺点。

一是系统启动时间长。init进程是串行启动,只有前一个服务启动完,才会启动下一个服务。

二是启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。

5.2 systemd

Systemd 就是为了解决init的问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。

根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。

使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。

Systemd 并不只是一个进程或一个命令,而是一组命令,涉及到系统管理的方方面面。详细可参考文章:全面易懂的 Systemd 服务管理教程

5.3 系统启动流程

参考:技术|走进Linux之systemd启动过程

  • 运行systemd进程(https://linux.cn/article-5457-1.html1号进程);
  • systemd执行的第一个目标是default.target。但实际上default.target是指向graphical.target的软链接。文件Graphical.target的实际位置是/usr/lib/systemd/system/graphical.target。在下面的截图里显示了graphical.target文件的内容。Requires=multi-user.target,表示该target依赖multi-user.target,在当前target启动时同时启动multi-user.target,若multi-user.target启动失败,则当前target也跟着终止。下图中,Wants字段也类似Requires表示依赖关系,不过Wants=后的display-manager.service启动失败不影响当前target的启动。

  •  multi-user.target这个target将自己的子单元放在目录“/etc/systemd/system/multi-user.target.wants”里。这个target为多用户支持设定系统环境。非root用户会在这个阶段的引导过程中启用。防火墙相关的服务也会在这个阶段启动。若某个unit的WantedBy=multi-user.target,则该unit被激活时,其符号链接将被放入到目录 “/etc/systemd/system/multi-user.target.wants/“。启动 multi-user.target时,在这个组里的所有服务,都将开机启动。

  • "multi-user.target"会将控制权交给另一层“basic.target

  • "basic.target"单元用于启动普通服务特别是图形管理服务。basic.target之后将控制权交给sysinit.target。

  • "sysinit.target"会启动重要的系统服务例如系统挂载,内存交换空间和设备,内核补充选项等等。sysinit.target在启动过程中会传递给local-fs.target。这个target单元的内容如下面截图里所展示。

  • local-fs.target,这个target单元不会启动用户相关的服务,它只处理底层核心服务。这个target会根据/etc/fstab和/etc/inittab来执行相关操作。

5.4 通过systemd实现开机自动挂载

目的:实现开机自动挂载指定的NAS存储"22.22.121.121:/NAS-01"到目录/mnt/point上。

操作如下:

在目录/etc/systemd/system下新建文件mnt-point.mount,文件名和文件内容中Where字段所指示的挂载点要对应,其中挂载点路径中的“/”转换为文件名中的“-”。在文件中填写以下内容。

[Unit]
Description=mount nas
Wants=network.target

[Mount]
What=33.33.133.133:/NAS-01
Where=/mnt/point
Type=nfs

[Install]
WantedBy=multi-user.target

其中WantedBy表示Wants当前服务的模块,它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .wants 后缀构成的子目录中。

执行以下命令,激活Unit

systemctl enable mnt-point.mount

激活后可以看到在/etc/systemd/system/multi-user.target.wants目录下生成了一个软链接mnt-point.mount指向我们刚创建的文件/etc/systemd/system/mnt-point.mount。重启系统,就能自动挂载指定的nas存储。

如果想立即启动这个mount服务,挂载这个nas,执行以下命令即可:

systemctl start mnt-point.mount

6. 参考资料

技术|走进Linux之systemd启动过程

Linux操作系统启动原理和故障分析(第二讲)_哔哩哔哩_bilibili

grub2详解(翻译和整理官方手册)-CSDN博客
 

Linux操作系统学习——启动.md

  • 33
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值