Linux系统启动流程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统启动流程相关的知识,希望对你有一定的参考价值。

加点自检

POST:加电自检。Power on self testing。当前x86的CPU在通电后会自动的到指定位置找到一段代码执行加点自检。

代码放在ROM里。ROM的代表组件叫CMOS,在ROM中有Bios


Boot Sequence

按次序查找各引导设备,第一个有引导程序的设备即为本次启动要用到的设备。

引导加载器/启动加载器

bootloader,这个程序存放在磁盘上。

Windows bootloader叫做ntloader

Linuxbootloader叫做LILO LInux LOder 这个启动器对磁盘容量有限制,该启动器不能加载1024个柱面之后的数据 Andriod底层就是Linux ,它使用的就是LILO。

Grub是另一个启动器, CentOS5 和CentOS6使用的是Grub 0.x CentOS7使用的是GRUB1.X

Grub0.X叫做Grub Legacy

Grub1.X叫做Grub2

引导加载器的作用是提供一个菜单,允许用户选择要启动的系统或不同的内核版本,并且把指定内核加载到内存的特定空间中,解压展开,然后把系统控制权交给内核。


引导加载器存放在哪里?

MBR。Main Boot Record。磁盘的第一个扇区(0号扇区)512字节

一个扇区是512字节,被分成三部分。

    1、前446字节,存放bootloader,这是个程序,用于引导启动操作系统的。

    2、中间64字节,存放分区表,每16字节表示一个分区,一共只能有4个分区

    3、最后两个字节,MBR区域的有效标识:55AA(正常值),其他值都无效

Grub将整个程序分为两部分,第一阶段存放在bootloader中,第二阶段存放在磁盘上/boot/grub中。

Grub的第一阶段中bootloader的主要作用不是加载系统内核,而且加载第二阶段中存放的一段代码(包含加载的内核代码),这样就可以在加载系统之前运行一些小程序。其实在第一阶段和第二阶段之间有个中间层阶段。因为如果要加载磁盘分区的代码就需要磁盘的驱动,这个阶段就需要挂载文件系统后才能挂载、读取第二阶段的代码。

注意:由于bootloader代码很小,不能驱动高级功能,比如LVM,RAID。那么/boot的文件不能放在逻辑卷上。内核文件只能放在基本磁盘分区上。



EFI

这个也是一个引导程序,是由Intel自己研发的用以替代BIOS的底层程序。BIOS担负着初始化硬件,检测硬件功能以及引导操作系统的责任。当系统加电时处理器的第一条指令的地址会被定位到BIOS的存储器中,便于初始化程序得到执行。

传统BIOS的缺点是设备加电启动时,处理器切换到16位的操作模式下,因为BIOS是以16位汇编编写的,执行也只能以16位系统执行,降低了使用效率。

Intel安腾处理器上摒弃了BIOS程序,使用了EFI程序。EFI可扩展固件接口(Extensible Firemware Interface)。在EFI系统下的驱动并不是由可以直接运行在CPU上的代码组成,而是用EFI Byte Code编写的。这是一组专用于EFI驱动的虚拟机器指令,必须在EFI驱动运行环境下被解释运行。由EFI编写的程序可以以32位或者64位系统运行。

虽然EFI在概念上非常类似于一个低阶的操作系统,并且具备操控所有硬件资源的能力。但是EFI的创造者们已经将EFI的能力做了限制。首先它只是硬件和预启动软件间的接口规范,其次EFI环境下不提供终端的访问机制,每个EFI驱动程序必须用轮询的方式来检查硬件状态,并且需要以解释的方式运行。

EFI是一个类bash的操作系统。而且不能使用MBR引导分区,只支持GPT引导分区。EFI带来了快速启动和2TB以上的分区(这个功能是由GPT提供的)

EFI的缺点:EFI的运行程序是由C语言编写的,BIOS是由汇编编写的。所以以后EFI的程序安全问题会比BIOS严重的多。

 

EFI初始化模块和驱动执行环境通过被集成在一个只读存储器中。Pre-EFI初始化程序在系统开机时会最先执行。它负责最初的CPU、主桥和存储器的初始化工作,紧接着载入EFI驱动执行环境(DXE)。当DXE被载入运行时,系统便具备了枚举并加载其他EFI驱动的能力。在基于PCI架构的系统中,各PCI桥及PCI适配器的EFI驱动会被相继加载及初始化。这时,系统进而枚举并加载各种桥接器及适配器后面的各种总线及设备驱动程序。直到最后一个设备的驱动程序被成功加载。所以EFI驱动程序可以放置于系统的任何位置,只要能保证它可以按顺序被正确枚举。

EFI规范中,引入了GUID磁盘分区系统(GPT)。在新结构中,磁盘的分区数不再受限于4个主分区,并且分区类型将由GUID来表示。在众多的分区类型中,EFI系统分区可以被EFI系统存取,用于存放部分驱动和应用程序

UEFI

EFI是由Intel单独开发的,为了能够与其他厂商共同研发EFI程序,就产生了UEFI

GPT

GPT磁盘是指使用GUID分区表的磁盘,是源自EFI标准的一种较新的磁盘分区结构表的标准。

MBR中用于存放分区信息的容量为64个字节,一共4个分区,那么每个分区的信息是16个字节,用于存放分区总扇区数信息的容量仅有4字节,那么一共是32位存放总扇区数,232次方个扇区,每个扇区512字节,那么每个分区大小不能大于2TB。不然分区总扇区数无法显示。

GPT相对于MRB的优势有以下几点:

1、支持2TB以上的硬盘

2、每个磁盘的分区数为128(Windows系统的限制)

3、用64位的证书表示扇区号。264次方个扇区。

4、分区表自带备份。在磁盘的首尾部分分别保存了一份相同的分区表。

5、每个分区可以有一个名称

技术分享图片


加载内核

内核加载后的第一件事就是自身初始化

第一步:探测可识别的所有硬件设备

第二步:加载硬件设备驱动程序(有可能借助ramdisk加载驱动)

第三步:以只读的方式挂载根文件系统(防止内核将根文件系统损坏,当系统运行正常后再以读写的方式挂载)

第四步:运行用户空间的第一个应用程序/sbin/init

技术分享图片

/sbin/init也只是一个链接文件

init程序类型

CentOS5:SYSV Init

              配置文件 /etc/inittab

CentOS6:Upstart

              配置文件:/etc/inittab(为了兼容之前版本) /etc/init/*.conf(这个是主要配置文件)

CentOS7:Systemd

              配置文件:/usr/lib/systemd/system,/etc/systemd/system

ramdisk

这个技术借用了Linux的特性之一(使用缓冲和缓存来加速对磁盘上的文件的访问)

在CentOS5上使用的是initrd 创建该文件系统的工具是mkinitrd

在CentOS6 7上使用的是initramfs 创建该文件系统的工具室dracut,mkinitrd(调用的还是dracut)

总结下

系统初始化流程(内核级别):POST->BootSequence(BIOS)->Bootloader(MBR)->Kernel(+ramdisk)->roofs(readonly)->/sbin/init


/sbin/init过程(CentOS5)

运行级别

为了系统运行或维护的目的而设定的机制

0-6:7个级别

   0:表示关机 shutdown

   1:单用户模式 single user root用户 无需认证;维护模式

   2:多用户模式 multi user,带网络功能的的维护模式 但不会启动NFS

   3:多用户模式 multi user,这是个正常模式,CLI模式

   4:预留级别

   5:多用户模式 multi user,这是个正常模式,GUI模式

   6:重启 reboot

默认级别:3 5

级别切换:init #

级别查看

技术分享图片

N代表上一次的级别

现在切换到3级别模式 init 3

技术分享图片

之前是5 现在是3

再切换到5

init配置文件

/etc/initab

技术分享图片

CentOS7中的inittab文件不可用,需要使用system文件

每行定义一种action以及与之对应的process  这个方式仅适用于CentOS5

id:runlevel:aciton:process

ID:任务名称

runlevel在哪些级别启动该任务

action 在什么条件下启动该任务

process 具体任务


action有几个选项:

1wait 等待切换至此任务所在的级别时执行一次 比如从3级别切换至5级别

2respawn:此任务终止时就自动重启。

3initdefault 设定默认运行级别此时process会省略

4sysinit 设定系统初始化方式,此处一般指定为/etc/rc.d/rc.sysinit脚本。

 

例子:

lo:0:wait:/etc/rc.d/rc 3

lo是任务的名称

0是运行级别

wait:表示当切换到0级别时

/etc/rc.d/rc 3 执行这个命令

rc3.d K开头的服务要关闭(数字越小,越优先关闭) S开头的服务要开启(数字越小,越是优先启动)


设置默认运行级别 CentOS7

systemctl get-default

systemctl set-default graphical.target  相当于level 5

                                   multi-user.target 相当于level 3

技术分享图片

这是当前默认的运行级别


设置默认运行级别 CentOS6

/etc/inittab

id:5:initdefault:


系统初始化脚本(CentOS5)

/etc/rc.d/rc.sysinit

1、设置主机名

2、设置欢迎信息

3、激活udevselinux

4、挂载/etc/fstab文件中定义的所有文件系统

5、检测根文件系统,并以读写方式重新挂载根文件系统

6、设置系统时钟。

7、根据/etc/sysctl.conf文件的设置,来设定内核参数。

8、激活LVM及软RAID设备

9、加载额外设备的驱动程序

10、清理操作


/sbin/init过程(CentOS6)

这里只说不一样的

init程序:upstart 但依然为/sbin/init,其配置文件为/etc/init/*.conf文件,/etc/inittab(仅用于定义默认运行级别)


/sbin/init过程(CentOS7)

init程序:systemd,配置文件/usr/lib/systemd/system/*和/etc/systemd/system/*


这里注意:就算配置文件中指定了系统启动后自动启动的进程,但是CentOS7不会启动进程,直到用户第一次访问或者使用到该进程。

完全兼容sysV脚本机制,因此service命令依然可用



总结(用户空间启动流程)

/sbin/init(/etc/inittab/etc/init/*.conf,/usr/lib/systemd/system/)

设置默认运行级别->运行系统初始化脚本,完成系统初始化->关闭对应级别下要停止的服务,启动对应级别下需要开启的服务->设置登录终端->启动图形界面(可选)

以上是关于Linux系统启动流程的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统启动流程

Linux系统启动流程

Linux系统启动流程

Linux系统启动流程分析与关机流程

Linux系统启动流程

Linux系统的启动流程