linux开机引导和启动过程(详细)(含配置文件解读)

news/2025/2/22 21:05:46

过程概述

  1. BIOS加电自检
  2. 加载MBR中的Bootloader
  3. 加载内核,初始化initrd
  4. 加载父进程,执行初始化程序
  5. 打开终端

BIOS开机加电自检

BIOS(基本输入输出系统),该系统存储于主板的ROM芯片上,计算机在开机时,会最先读取该系统,然后会有一个加电自检过程。这个过程其实就是检查CPU和内存,计算机最基本的组成单元(控制器、运算器和存储器),还会检查其他硬件,若没有异常就开始加载BIOS程序到内存当中。BIOS的功能大概可以分为3个部分:

  1. 用于电脑刚接通电源时对硬件部分的检测,也叫做加电自检(Power On Self Test,简称POST)。功能是检查电脑是否良好,通常完整的POST自检将包括对CPU,640K基本内存,1M以上的扩展内存,ROM,主板,CMOS存储器,串并口,显示卡,软硬盘子系统及键盘进行测试,一旦在自检中发现问题,系统将给出提示信息或鸣笛警告。自检中如发现有错误,将按两种情况处理:

    • 对于严重故障(致命性故障)则停机,此时由于各种初始化操作还没完成,不能给出任何提示或信号;
    • 对于非严重故障则给出提示或声音报警信号,等待用户处理。
  2. 初始化硬件(这个玩过开发板的应该都很清楚)。包括创建中断向量、设置寄存器、对一些外部设备进行初始化和检测等,其中很重要的一部分是BIOS设置,主要是对硬件设置的一些参数,当电脑启动时会读取这些参数,并和实际硬件设置进行比较,如果不符合,会影响系统的启动。

  3. 引导操作系统程序BIOS会按照硬盘的引导记录去查找第一个磁盘头的MBR信息,并加载和执行MBR中的Bootloader程序,若第一个磁盘不存在MBR,则会继续查找第二个磁盘(启动顺序可以在BIOS的界面中进行设置),一旦BootLoader程序被检测并加载内存中,BIOS就将控制权交接给了BootLoader程序(控制权交接其实就是指CPU跳转到Bootloader程序的内存位置执行)

加载MBR中的BootLoader

MBR(Master Boot Record)主引导记录,MBR存储于磁盘的头部,大小为512 bytes,组成为:[446 bytes(存储BootLoader程序)+64 bytes(存储分区表信息)+2 bytes(用于MBR的有效性检查)]。

这个部分就需要分为3个阶段来执行了:

Stage_1

BIOS加载它找到的第一个引导记录(MBR)中到内存中,并开始执行此代码。Bootloader必须非常小,因为它必须连同分区表放到硬盘的第一个 512 字节的扇区中。 在传统的常规 MBR 中,引导代码实际所占用的空间大小为 446 字节。这个MBR中这个 446 字节的文件通常被叫做引导镜像(boot.img),其中不包含设备的分区信息,分区是一般单独添加到引导记录中。

Stage_1.5

由于boot.img必须做的非常小,所以基本不可能有太多复杂的功能,他唯一能做的就是加载Stage_1.5中的存储的代码,也就是core.img( 25389 25389 25389字节)。该文件通常位于MBR与第一个分区之间,也就是 0 ∼ 63 0\sim63 063扇区之间(未包括 63 63 63),总大小为 62 ∗ 512 = 31744 62*512=31744 62512=31744字节。这个文件,存放了一些通用的文件系统驱动程序,如标准的 EXT 和其它的 Linux 文件系统,如 FATNTFS 等。所以这阶段就是负责执行Stage_1.5中存放的驱动程序,并加载相关的驱动程序。

Grub2core.img 远比老一版的 Grub1 更复杂且更强大。这意味着 Grub2core.img 能够放在标准的EXT 文件系统内,但是不能放在逻辑卷内。故在Grub2中,Stage_1.5中的文件可以存放于 /boot 文件系统中,一般在 /boot/grub2 目录下。

Stage_2

进入Stage_2时,所有的文件(内核initrd等)都已存放于/boot目录及其几个子目录之下。同时,该阶段还可以从 /boot/grub2/i386-pc 目录下加载一些内核运行时模块。所以Stage_2的主要功能是定位和加载 Linux 内核initrd到内存中,并转移控制权。

关于Grub2

linux启动时按下C即可进入Grub2的命令行模式,这里你可以自己手动引导内核和initrd的加载。关于手动引导的相关操作,可以自行百度。这里我们重点来看下配置文件/boot/grub2/grub.cfg,这里有篇文章已经说得很详细,这里就直接与大家分享了:

  • GRUB2配置文件"grub.cfg"详解
  • grub2基础教程-修订版(谷歌文档)

加载内核并初始化initrd

由于Linux内核是很精简的,只保留必要的驱动程序,而现实中的设备种类繁多,例如:根文件系统可以存储在包括IDE、SCSI、USB在内的多种介质上,如果将这些设备的驱动都编译进内核那该多么臃肿,所以就干脆将设备特有的驱动与内核分离,单独形成initrd(一般自己编译的系统不需要,发行版需要兼容所以会需要)。需要哪种驱动就提取到initrd中,待启动时提前加载即可。所以内核启动一般分两步:

初始化initrd

linux内核启动前, bootloader会将存储介质中的 initrd 文件加载到内存,内核启动时会在访问真正的根文件系统前先访问该内存中的 initrd 文件系统,这个过程将会完成相关驱动模块的加载,最主要就是加载根文件系统存储介质的驱动模块等,这样内核就可以正常识别设备和真正的根文件系统了。

initrd( boot loader initialized RAM disk),就是由 bootloader 初始化的内存盘,算是一个很mini版的文件系统。

启动内核

之后,内核会以只读方式挂载根文件系统,当根文件系统被挂载后,开始装载第一个进程(用户空间的进程),执行/sbin/init,之后就将控制权交接给了init程序。如果是使用systemd的话,则是加载systemd进程到内存中。

初始化系统

这一节呢,我们分为两个init系统来叙述:

Sysvinit系统

sysvinit 就是 System V 风格的 init 系统,顾名思义,它源于 System V 系列的 UNIX。最初的 linux 发行版几乎都是采用 sysvinit 作为 init 系统。sysvinit 用术语 runlevel 来定义 “预订的运行模式”。比如

  • runlevel 3 是命令行模式,
  • runlevel 5 是图形界面模式,
  • runlevel 0 是关机,
  • runlevel 6 是重启。

这个初始化系统的涉及到的配置文件如下(按init进程读先后顺序):

/etc/inittab

####省去多余注释#######
###表示当前缺省运行级别为5(initdefault),即默认以图形界面启动

id:5:initdefault:
###启动时自动执行/etc/rc.d/rc.sysinit脚本(sysinit)

# 这一项表示在系统启动时执行/etc/rc.d/rc.sysinit程序
si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
# 当切换到runlevel3(命令行模式时),执行一下/etc/rc.d/rc这个程序,并传递参数3
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4

###当运行级别为5时,以5为参数运行/etc/rc.d/rc脚本,init将等待其返回(wait)

l5:5:wait:/etc/rc.d/rc 5
#这个就是同时匹配多个runlevel
l6:23456:wait:/etc/rc.d/rc 6

每个配置项格式如下:

i d : r u n l e v e l : a c t i o n : p r o c e s s id:runlevel:action:process id:runlevel:action:process

各项含义如下:

  1. id

    id是指入口标识符,它是一个字符串,对于getty或mingetty等其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。

  2. runlevel

    runlevel是init所处于的运行级别的标识.runlevel可以是并列的多个值,以匹配多个运行级别,对大多数action来说,仅当runlevel与当前运行级别匹配成功才会执行

    • 0:表示关机
    • 1:表示单用户模式,在这个模式中,用户登录不需要密码,默认网卡驱动是不被加载,一些服务不能用。
    • 2:表示多用户模式,NFS服务不开启
    • 3:表示命令行模式
    • 4:这个模式保留未用
    • 5:表示图形用户模式
    • 6:表示重启系统
  3. action

    • respawn:当process终止后马上启动一个新的
    • wait:当进入指定的runlevels后process才会启动一次,并且到离开这个runlevels终止
    • initdefault:设定默认的运行级别,即我们开机之后默认进入的运行级别,不能是0,6,你懂的
    • sysinit:系统初始化,只有系统开机或重新启动的时候,这个process才会被执行一次
    • powerwait:当init接收到电源失败信号的时候执行相应的process,并且如果init有进程在运行,会等待这个进程完成之后,再执行相应的process
    • powerfail:当init接收到电源失败信号的时候执行相应的process,并且如果init有进程在运行,不会等待这个进程完成,它会直接执行相应的process
    • powerokwait:电源已经故障,但是在等待执行对应操作的时候突然来电了就执行对应的process
    • powerfailnow:当电源故障并且init被通知UPS电源已经快耗尽执行相对应的process
    • ctrlaltdel:当用户按下ctrl+alt+del这个组合键的时候执行对应的process
    • boot:只有在引导过程中,才执行该进程,但不等待该进程的结束;当该进程死亡时,也不重新启动该进程
    • bootwait:只有在引导过程中,才执行该进程,并等待进程的结束;当该进程死亡时,也不重新启动该进程
    • off:如果process正在运行,那么就发出一个警告信号,等待20秒后,再通过杀死信号强行终止该process。如果process并不存在那么就忽略该登记项
    • once:启动相应的进程,但不等待该进程结束便继续处理/etc/inittab文件中的下一个登记项;当该进程死亡时,init也不重新启动该进程
  4. process

    表示启动哪个程序或脚本或执行哪个命令

/etc/rc.d/rc.sysinit

所有的运行级别下,init依赖/etc/rc.d/rc.sysinit这个脚本对系统进行初始化。按照下面的顺序按部就班的初始化系统:

  • 激活 udev 和 selinux
  • 设置定义在 /etc/sysctl.conf中的内核参数
  • 设置系统时钟
  • 加载 keymaps
  • 启用交换分区
  • 设置主机名(hostname)
  • 根分区检查和 remount
  • 激活 RAID 和 LVM 设备
  • 开启磁盘配额
  • 检查并挂载所有文件系统
  • 清除过期的 locks 和 PID 文件
  • 最后找到指定 runlevel 下的脚本并执行,其实就是启动服务。

/etc/rc.d/rc

这个程序就是根据传入的参数,调用/etc/rc.d/rc0.d~rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务,最后调用/etc/rc.d/rc.local,这个文件里面可以放一些用户自定义的启动脚本等等

Systemd系统

systemdlinux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit 固有的缺点,提高系统的启动速度。

在开始看Systemd进程做的事情之前,请先了解一下开机启动脚本的编写和选项含义,这里直接推荐一篇不错的文章:编写systemd下服务脚本。新旧系统运行等级映射关系如下:

SystemV 运行级别systemd 目标态systemd 目标态别名描述
halt.target停止系统运行但不切断电源。
0poweroff.targetrunlevel0.target停止系统运行并切断电源.
Semergency.target单用户模式,没有服务进程运行,文件系统也没挂载。这是一个最基本的运行级别,仅在主控制台上提供一个 shell 用于用户与系统进行交互。
1rescue.targetrunlevel1.target挂载了文件系统,仅运行了最基本的服务进程的基本系统,并在主控制台启动了一个 shell 访问入口用于诊断。
2runlevel2.target多用户,没有挂载 NFS 文件系统,但是所有的非图形界面的服务进程已经运行。
3multi-user.targetrunlevel3.target所有服务都已运行,但只支持命令行接口访问。
4runlevel4.target未使用。
5graphical.targetrunlevel5.target多用户,且支持图形界面接口。
6reboot.targetrunlevel6.target重启。
default.target这个目标态target是总是 multi-user.targetgraphical.target 的一个符号链接的别名。systemd 总是通过 default.target 启动系统。default.target 绝不应该指向halt.targetpoweroff.targetreboot.target。

Systemd进程在被加载到内后,将依次执行五个目标:

  1. /usr/lib/systemd/system/default.target,这个文件链接到当前目录的graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
  1. 根据上一步中可以看到default.target强依赖于multi-user.target,所以接下来这步就要执行如下两个目录中的目标了:
  • /etc/systemd/system/multi-user.target.wants/
  • /usr/lib/systemd/system/multi-user.target.wants/

大部分的用户程序的目标都在这两个目录下有配置,在这步就一并启动了

#/usr/lib/systemd/system/multi-user.target.wants/multi-user.target
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
  1. 接下来到了basic.target目标了,内容如下:
  • /etc/systemd/system/basic.target.wants/
  • /usr/lib/systemd/system/basic.target.wants/
#/usr/lib/systemd/system/multi-user.target.wants/basic.target
[Unit]
Description=Basic System
Documentation=man:systemd.special(7)

Requires=sysinit.target
After=sysinit.target
Wants=sockets.target timers.target paths.target slices.target
After=sockets.target paths.target slices.target
  1. sysinit.target会启动重要的系统服务例如系统挂载,内存交换空间和设备,内核补充选项.
  • /etc/systemd/system/sysinit.target.wants/
  • /usr/lib/systemd/system/sysinit.target.wants/
[Unit]
Description=System Initialization
Documentation=man:systemd.special(7)
Conflicts=emergency.service emergency.target
Wants=local-fs.target swap.target
After=local-fs.target swap.target emergency.service emergency.target
  1. 然后是最后一个目标local-fs.target,它不会启动用户相关服务,它只处理底层核心服务,这个target会根据/etc/fstab来执行相关磁盘挂载操作

Systemd系统服务配置修改

  • /usr/lib/systemd/system/xx服务.service:官方默认配置文件,不建议修改这个位置的文件,而应该像下面这项这样操作;
  • /etc/systemd/system/xx服务.service.d/custom.conf:在 /etc/systemd/system 下面创建与配置文件相同文件名的目录,但是要加上 .d 的扩展名。然后在该目录下创建配置文件即可。另外,配置文件最好附文件名取名为 .conf。 在这个目录下的文件配置会合并到 /usr/lib/systemd/system/xx服务.service
  • /etc/systemd/system/xx服务.service.wants/*:此目录内的文件为链接文件,设置相依服务的链接。意思是启动了 xx服务.service 之后,最好再加上这目录下面建议的服务。
  • /etc/systemd/system/xx服务.service.requires/*:此目录内的文件为链接文件,设置相依服务的链接。意思是在启动 xx服务.service 之前,需要事先启动哪些服务的意思。

打开终端

sysvinit系统

在sysvinit系统中,由于/etc/inittab中的配置如下:

1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# 只有我们进入5运行级别,会打开图形用户终端,并且一旦终端终止,就会再创建一个新的
x:5:respawn:/etc/X11/prefdm -nodaemon

在2345运行级别下,会调用/sbin/mingetty启用6个命令行界面的终端,并且一旦终端终止,就会再创建一个新的。

Systemd系统

在上面初始化的第1步中等待了display-manager.service这个服务就是用于启动终端界面的,内容如下:

[Service]
ExecStart=/usr/sbin/gdm
ExecStartPost=-/bin/bash -c "TERM=linux /usr/bin/clear > /dev/tty1"
KillMode=mixed
Restart=always
IgnoreSIGPIPE=no
BusName=org.gnome.DisplayManager
StandardOutput=syslog
StandardError=inherit
EnvironmentFile=-/etc/locale.conf
ExecReload=/bin/kill -SIGHUP $MAINPID

[Install]
Alias=display-manager.service

http://www.niftyadmin.cn/n/1180411.html

相关文章

Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先) 作者提示:在阅读本文之前,请确保您已经理解并掌握了基本的Tarjan算法,不会的请到http://hi.baidu.com/lydrainbowcat/blog/item/42a6862489c98820c89559f3.html阅读。 基…

毕业生的职场五大忠告

毕业生的职场五大忠告http://fellow.51cto.com 2010-10-18 11:26 佚名 新浪网 我要评论(0)摘要:在人力资源行业从事多年,最大的好处就是能有机会与职场中各类人群广泛接触,对其也算有一定的观察和了解。职场中最难就业的人群可以说是毕业…

Vue学习笔记——常见简写修饰符

最近在看vue-element-admin框架的源码,发现其中还是有不少的语法糖。感觉对初次接触Vue的开发者还是会造成些困惑,虽然之前我有使用过React,但是对比起来Vue还是有不少从未见过的语法糖或简写,为了以便时而查阅,这里就将自己觉得比…

oracle假启动

没错,这个文章你找对地方了!慢慢往下看!是不是客户机连服务器遇到过这种错误?ORA-12518 TNS:监听程序无法分发客户机连接是不是服务器本机上不写服务名,直接连接也连不上,提示这种错误?ORA-1256…

行大小计算测试

数据库中每一行到底占用多少空间,在这里,做个小测试~~~这里只做了堆表的计算,如果包含索引,按照文档把索引的列也加上就OK啦~ 建个测试表,然后用DBCC PAGE打印出Slot的信息 CREATE TABLE TstA (col1 CHAR(5) NULL,col2…

[iphone]XML 解析 之 TBXML 介绍

总的来说,iphone 上可用的解析XML的方式大概有2种类型的。1.Tree-based API:这种API的处理方式是将XML的结构看成是树,然后把树的各部分看成一个对象来处理,这就是我们说的DOM (Document Object Model)方式。在iPhone的SDK里包含了…

vue-element-admin源码解读——项目启动过程

vue-element-admin源码解读——项目组件布局及状态管理vue-element-admin源码解读——项目启动过程vue-element-admin源码解读——数据Mock vue-element-admin是一款优秀的前端框架,使用了最新的前端技术,内置了(Vue-i18)国际化解决方案,动态…

三大平衡树(Treap + Splay + SBT)总结+模板

Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板&#xff1a; #include <cstdio> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath…