Linux之系统启动流程之(1)流程概述

Linux一般来说是通过引导MBR来启动程序的,所以本片之介绍MBR启动方式流程。

Linux组成:Kernel+rootfs

kernel(系统内核模块)功能:

进程管理、内存管理、网路管理、驱动程序、文件系统、按全功能。

rootfs(根文件系统):相应程序和glibc,根是自引用的,能够自我识别

库:函数集合,function, 调用接口(头文件负责描述)

过程调用:procedure,无返回值

函数调用:function

程序:二进制执行文件

 

内核设计流派:

单内核(monolithice kernel):Linux (LMP)

把所有功能集成于同一个程序

微内核(micro kernel):Windows, Solaris(线程)

每种功能使用一个单独子系统实现

 

Linux内核的特点:

支持模块化: .ko (内核模块对象)

如:文件系统,驱动程序,网络协议等

 (注):支持内核模块的动态装载和卸载

 

启动所需组成部分:

核心文件:/boot/vmlinuz-VERSION-release.img

ramdisk:辅助的伪根系统

CentOS 5ramdisk --> initrd

/boot/initrd-VERSION-release.img

CentOS6, 7ramfs -->initrdamfs

/boot/initramfs-VERSION-release.img

模块文件存放路径:/lib/modules/VERSION-release

 

 

CentOS6启动顺序:

总体顺序:

POST-->BIOS(Boot Sequence)-->MBR(bootloader,446)-->Kernel-initrd-->(ROOTFS)-->/sbin/init

大致顺序:

加电自检-->MBR引导-->GRUB-->加载内核

 

CentOS6启动流程:

1、加载BIOS的硬件信息,获取第一个启动设备

2、读取第一个启动设备MBR的引导加载程序(grub)的启动信息

3、加载核心操作设备

4、核心执行init程序,并获取默认的运行信息

5、init程序执行/etc/rc.d/rc.sysinit文件

6、启动核心的外挂模块(/etc/modprobe.conf)

7、init执行运行的各个批处理文件(scripts)

8、init执行/etc/rc.d/rc.local

9、执行/bin/login程序,等待用户登录

10、登录之后开始以Shell 控制主机

 

详解启动过程

主板及相关硬件作用

POSTPrower-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU

主板、内存、硬盘子系统、串行行接口、键盘、CD-ROM光驱等硬件情况的检查测。

ROMBIOSBasic Inpupt and Ouput System,保存着有关计算机最重要的基本输入输出程序,系统信息设置、开机加电自检和系统启动自举程序等。

RAMCMOS互补金属氧化物半导体,保存BIOS主备的程序各项参数的设定。

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

引导加载部分作用

bootloader(MBR):引导加载器

bootloader类型补充:

windowsntloader,仅是启动OS

        Linux:功能丰富,提供菜单,运行用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存到特定空间中,解压、展开,并把系统控制权移交给内存。

Linux中使用的bootloder

LIIOLInux LOader

GRUBGRand Unified Bootloader

               GRUB 0.XGRUB LegacyGRUB2

 

MBR:系统盘的前446字节:bootloader,64:分区表,2 :55AA

 

GRUB:GRand Unified Bootloader

primary boot loader

Stage1MBR,第1阶段

secondary boot loader

Stage1_5:识别常见的不同文件系统类型,第1,.5阶段

Stage2/root/grub/,第2阶段

 

kernel部分:

  自身初始化:

探测可识别到的所有硬件设备

加载硬件驱动(可能借助于ramdisk加载驱动)

以自读方式挂载根文件系统

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

 

init程序的类型:

SysVinit, CentOS 5及之前

配置文件:/etc/inittab

Upstartinit, CentOS6

配置文件:/etc/inittab, /etc/init/*.conf

Systemdsystemd, CentOS7

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

  /etc/systemd/system

ramdisk类型:

内核中的特性之一:使用缓冲和缓存来加速对磁盘上的文件访问

ramdisk  -->  ramfs 提供速度

CentOS 5initrd,工作程序:mkinitrd

CentOS 6initramfs,工具程序:mkinitrd,dracut

注意:ramkdisk为表示模拟一个虚拟磁盘来进行根切换,而ramfs直接是模拟了一种文件系统所有缓存和解压的速度更快。

 

系统初始化:

POST-->BootSequence(BIOS)-->Bootloader(MBR)-->kernel(ramdisk)-->

(ROOBTFS虚拟根文件系统切换)-->init(或者systemd)

 

 

系统的运行级别(CentOS6之前):/sbin/init(切换级别的命令)

0halt  关机

1single user mode,  单用户模式, 直接以管理员切入(init  s | single)

2mulit user mode, no NFS 没有NFS服务的字符界面多用户模式

3mulit user mode, text mode 字符界面多用户模式

4reseved  保留级别,可同3级别

5multi  user  mode,  graphic mode  带图形界面的多用户模式

6reboot 重启

 

默认级别:3,5

切换级别:init #

查看级别:runlevel ; who -r

 

 

init初始化:

init进程其初始化文件:/etc/inittab

初始化运行级别(RUN LEVEL

系统初始化脚本

对应运行级别的脚本目录

捕获某个关键字顺序

定义UPS电源终端/恢复脚步

在虚拟控制台生成getty

在运行级别5初始化X(图形界面程序)

各个启动过程使用的配置文件的作用

/sbin/init:(/etc/inittab)

upstartubuntu组织开发,(RHEL 6版本以后)d-dusevent-driven,基于事件驱动

systemd(完整的并行进程)

 

/etc/inittab配置文件介绍:

每一行定义一种action以及与之对应的 process,格式:

id:runlevels:action:process

id:表示符

runlevels:在哪个运行级别运行此行;

action:在什么情况执行此行,一般常见有下面几种情况:

wait:切换至此级别运行一次;

respawn:此process终止,就重新启动

initdefault:设置默认运行级别;process字段可省略

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

process:要运行程序;

 

 

举例说明/etc/inittab:

按默认3级别基本的默认/etc/inittab文件配置说明:

id:3:initdefault:#默认运行级别为3级别,init程序读取此行按3级别进入系统

si::sysinit:/etc/rc.d/rc.sysinit#加载文件rc.sysinit,并执行此脚本中的设置

 

l3:3:wait:/etc/rc.d/rc 3

#根据上面3级别进入系统后,执行对应的rc.d/rc脚步,后面参数为3,然后进入搜索对应级别下的服务脚步,及/etc/rc.d/rc3.d/下的服务脚步,然后按顺序关闭文件中对应 K开头的服务,开启S开头的服务。

 

/etc/rc.d/rc.init:系统初始化脚本

1、设置主机名

2、设置欢迎信息

3、**udevselinux

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

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

6、设置系统时钟

7、**swap设备

8、根据/etc/sysctl.conf文件设置内核参数

9、**lvmsoftware raid设备

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

11、清理操作

 

/etc/rc.d/rc脚步说明:

/etc/rc.d/rc中核心服务控制语句类似以下脚本类型:

[[email protected] kernel]# cat rc.sh 
#!/bin/bash
#
[ $# -lt 1 ] && exit 1;
runlevel=$1
path="/etc/rc.d"
for k in ${path}/rc${runlevel}.d/K*;do
   echo "$k  stopped...";     #原本rc应该是 $k  stop,接收stop参数来关闭对应服务
done
 
for s in ${path}/rc${runlevel}.d/S*;do
   echo "$s  start....";     #原本rc应该是$s  start,解析start参数来开启对应服务
done


解析:因为这是一个测试语句,就不传指定的{start|stop|status|restart}参数了,这里使用echo输出来模拟代替。当然真正的rc脚步必须要介绍一个参数来决定来决定对那个运行级别下的服务类脚步来操作,这里输入3测试:

#测试脚步执行

[[email protected] kernel]# ./rc.sh 3

说明:然后会发现先输出K后跟数字的先关闭,然后S后跟数字的再启动。数字越小,越先操作,数字越小的越后操作,因此可以猜测到3级别在启动的时候会先关闭那么不需要的服务,而又需要开启哪些服务。

 

rc脚步启动总结说明:

rc #  --> 意味着读取/etc/rc.d/rc#.d/ 下的文件

K*K####运行次序;数字越小先执行及关闭;数字越小的服务,通常为依赖到别的服务;

S*S####运行次序;数字越小先执行及开启;数字越小的服务,通常为被依赖到的服务;

 

 

系统服务管理命令(CentOS5、6):

chkconfig  命令

chkconfig - updates and queries runlevel information for system services

更新和查询系统服务的运行级别信息

选项及用法:

 

查看服务所在运行级别状态:

chkconfig  --list:查询所有独立守护服务的启动设定,注意:独立守护进程!

chkconfig  --list  SERVICE_NAME  #查询指定服务所有级别的启动或关闭情况

 

添加服务

chkconfig --add SERVICE_NAME(脚步名称)

添加的SysV的服务脚步放置于/etc/rc.d/init.d (/etc/init.d)目录下

添加的脚步的前几行需要特定标示格式加入:

#!/bin/bash

#runlevels     

解析:runlevles表示初始在哪些基本下启动,-表示都不启动,可以单个可以多个,如23表示23级别下,而3表示只在3级别启动

#chkconfig:  runlevels  SS  KK

解析:当chkconfig命令来为此脚本在rc#.d目录创建链接时,runlevel表示默认创建S*开头的链接,除此之外的级别都创建为K*开头的链接。

注:链接的开头说明:

S后面的启动优先级为SS所表示的数字;

K后面关闭优先次序为KK所表示的数字;

#description:  

解析:用于说明此脚本的简单功能:\ 表示续行符号,如 start what \ aa

 

删除服务:

chkconfig  --del  SERVICE_NAME   #删除指定服务脚步在对于级别下创建的链接文件

 

修改指定的链接类型:

chkconfig  [--level  runlevels]  name  <on|off|reset|resetpriorities>

--level  runlevles:要设置的级别;省略时表示2345级别

 

添加删除、设置自定义服务案例:

1、编写一个模拟SysV风格的服务脚步,及能够接收{start|stop|status|restart}4钟参数:

[[email protected] kernel]# vim myservice.sh

#表现内容如下,用判断一个文件是否存在来判断服务是否启动

[[email protected] kernel]# cat myservice.sh 
#!/bin/bash
#
prog="/var/lock/subsys/`basename $0`";
 
start() {
  [ ! -f ${prog} ] && touch ${prog}
  [ $? -eq 0 ] &&  echo "`basename $0` start Ok" || echo "`basename $0` running....";
}
 
stop() {
  [ -f ${prog} ] && rm -f ${prog} 
  [ $? -eq 0 ] && echo "`basename $0` stop OK" ||  echo "`basename $0` stopped...";
}
 
status() {
  [ -f ${prog} ] && echo "`basename $0` running..." || echo "`basename $0` stopped...";
}
 
usages() {
  echo "Unkown Usages:`basename $0` {start|stop|restart|status}";
}
 
declare -a arr=(start stop restart status);
 
case $1 in 
${arr[0]})
   start 
   ;;
${arr[1]})
   stop 
   ;;
${arr[2]})
   stop
   start
   ;;
${arr[3]})
   status
   ;;
*)
   usages
   ;;
esac

#给脚步加执行权限,然后测试脚步

[[email protected] kernel]# chmod +x myservice.sh

#给脚步的代码行前面加入chkconfig的SysV服务启动脚本风格片段

 Linux之系统启动流程之(1)流程概述

解析:这里的35以及下面的description描述信息可以省略不写,只是对此脚本做一个介绍,而chkconfig:设定的参数必须写,添加此服务时读取此行,会在35下级别对应的目录(/etc/rc.d/rc3.d/)下生成以S66开头的符号链接文件和K22开头符号链接文件。

 

2、将刚才编写的myservic模拟服务脚步添加到启动服务列表

#测试成功后,将此脚本拷贝至/etc/rc.d/init.d/目录***意不要加.sh后缀

[[email protected] kernel]# cp -p ./myservice.sh /etc/rc.d/init.d/myservice

#查看myservice脚步是否已经拷贝成功

[[email protected] kernel]# ls -l /etc/rc.d/init.d/myservice 
-rwxr-xr-x 1 root root 697 Sep 11 21:55 /etc/rc.d/init.d/myservice

#然后cd切换到此目录(/etc/rc.d/init.d)进程操作

[[email protected] kernel]# cd /etc/rc.d/init.d/
[[email protected] init.d]# pwd
/etc/rc.d/init.d

#使用chkconfig命令添加定义的服务脚步

[[email protected] init.d]# chkconfig --add myservice

 

3、查看是否根据在chkconfig文件头的级别、文件***参数在对应目录生成了链接文件

#查看myservervie的SysV级别表示

[[email protected] init.d]# grep '^#chkconfig' myservice
#chkconfig: 35 66 22

#查看对应的35级别是否生成了对应的文件链接

[[email protected] init.d]# ls -l /etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx 1 root root 19 Sep 11 22:13 /etc/rc.d/rc3.d/S66myservice -> ../init.d/myservice
[[email protected] init.d]# ls -l /etc/rc.d/rc5.d/*myservice*
lrwxrwxrwx 1 root root 19 Sep 11 22:13 /etc/rc.d/rc5.d/S66myservice -> ../init.d/myservice

解析:可以看到在3和5级别服务脚步链接目录下都是只生成了S开头的文件,所有,此时表示在每次运行3和5级别时,会自动开启此服务。

#查看当前此服务所有级别的自动开启和关闭状态

[[email protected] init.d]# chkconfig --list myservice
myservice      0:off1:off2:off3:on4:off5:on6:off

解析:这里显示myservice服务3级别和5级别都是启动状态,和对应级别服务目录生成的符号链接文件所对应,都是S开头,下面关闭此服务35运行级别自动启动:

#使用chkconfig命令关闭 3级别的自启动状态

[[email protected] init.d]# chkconfig --level 3 myservice off

#再次查看myservice服务所有运行级别的状态

[[email protected] init.d]# chkconfig --list myservice
myservice      0:off1:off2:off3:off4:off5:on6:off

解析:这里发现3级别已经变成了off,那么对应的3级别服务目录下的链接文件会变吗?

#查看3级别服务目录(/etc/rc.d/rc3.d/)下mysevice链接文件

[[email protected] init.d]# ls -l /etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx 1 root root 19 Sep 11 22:23 /etc/rc.d/rc3.d/K22myservice -> ../init.d/myservice

解析:这里发现已经根据/etc/rc.d/init.d/myservice脚步里设置的K开头22参数,改变了文件的链接命令,从S66变成了K22。

 

4、测试/etc/rc.d/rcN.d/*的链接文件和chkconfig服务列表的关系

#下面反过来,直接使用重命令来修改链接文件名,查看是否会修改chkconfig列表里的状态:

#修改K22myservice链接文件名为S66myservce(安照chkconfig行定义好的)

[[email protected] init.d]# mv /etc/rc.d/rc3.d/K22myservice /etc/rc.d/rc3.d/S66myservice

#检查文件名是否已经改变

[[email protected] init.d]# ls -l /etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx 1 root root 19 Sep 11 22:23 /etc/rc.d/rc3.d/S66myservice -> ../init.d/myservice

#此时使用chkconfig命令来查看3级别下是否已经变成on及自启动服务

[[email protected] init.d]# chkconfig --list myservice 
myservice      0:off1:off2:off3:on4:off5:on6:off

解析:OK,原来内部只是不断已经连接名来对指定运行级别的服务脚步进行开启或关闭处理,当然,此脚本必须要在/etc/rc.d/init.d存在,否则chkconfig不会识别,而且此服务脚步文件还必须需要有chkfonig标示行,及指定级别、生成***等。

 

5、额外的图形字符界面工具ntsyv

不仅可以使用chkconfig命令,还有专用的图形工具(ntsysv),不过只针对当前运行级别设置

 

#查看当前终端所在的运行级别

[[email protected] init.d]# runlevel 
N 3
[[email protected] init.d]# who -r
         run-level 3  2016-09-01 06:32                   last=S

解析:以上连个命令都会显示所在的运行级别,从上面输出得知,当前在3级别运行。

#输入ntsvsy列出当前运行级别的服务列表

[[email protected] init.d]# ntsysv

#ntsvsy打开的Services列表中找到自定义的myservice服务

Linux之系统启动流程之(1)流程概述 

说明:这里前面的[ ]里面有个*符号,说明在当前运行级别已经设置自启动,也就是3级别。

#对Cancel按钮按回车退出,使用chkconfig查看3级别myservice是否自启动

[[email protected] init.d]# chkconfig --list myservice
myservice      0:off1:off2:off3:on4:off5:on6:off

解析:这里显示时on状态,和 ntsysv工具里的对应。

#再次打开ntsysv工具,对myservice此行按空格,让*符号消失

Linux之系统启动流程之(1)流程概述 

注意:这里设置好后,使用tab键切换到ok按回车才能保存设置并退出。

#使用chkconfig命令myservice在3级别是否已经变成off

[[email protected] init.d]# chkconfig --list myservice 
myservice      0:off1:off2:off3:off4:off5:on6:off

#再次查看3级别的服务链接文件是否为K22*开头

[[email protected] init.d]# ls -l /etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx 1 root root 19 Sep 11 22:47 /etc/rc.d/rc3.d/K22myservice -> ../init.d/myservice

#清除myservice对应的所有符号链接文件

[[email protected] init.d]# chkconfig --del myservice

#再次使用chkconfig命令以及出现找不到此服务,说明所有级别下链接已经清除完

[[email protected] init.d]# chkconfig --list myservice 
service myservice supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add myservice')

#但是此脚本并没有删除

[[email protected] init.d]# ls -l /etc/rc.d/init.d/myservice 
-rwxr-xr-x 1 root root 772 Sep 11 22:11 /etc/rc.d/init.d/myservice

#删除此脚本文件即可恢复开始原状

[[email protected] init.d]# rm -f /etc/rc.d/init.d/myservice


总结:

linuxCentos6发行版来说,开机启动流程为:

1、POST加电自检,然后找到BLOS中设置的第一个启动设备;

2、然后从此设备及硬盘中找到磁盘的前446字节,及bootloader,完成第一阶段;

3、然后根据bootloader中的grub信息找到boot分区;

4、读取/boot/grub/grub.conf配置文件中读取vmlinuz内核文件,然后解压并加载内核;

5、在加载完成后然后解压initrd initramfs.img)模拟加载器来切换到真正的根文件系统,这时实际上运行了initramfs 中有一段核心脚步为init,及grub.conf中定义的根分区(如root=/dev/sda2),然后进入系统;

6、随之根据内核文件中定义会默认运行/sbin/init第一个系统启动程序;

7、/sbin/init默认读取/etc/initab文件,读取设置的默认运行级别;

8、然后运行/etc/rc.d/rc.sysinit文件来设置一些系统的级别级别配置(如加载内核模块、设置主机名,重新挂载文件系统等);

9、然后根据默认运行级别来找对应级别下的目录服务脚步链接文件来执行,也就是执行/etc/rc.d/rc,当然这里的脚步读有一个上述说到的SysV风格的chkconfig标识(#chkconfig  level  SS  KK),然后安装关闭K开头链接脚步和开启S开头的链接脚步,最终启动所有服务;

10、执行完所有服务后这里最后会执行/etc/rc.d/rc.local (这里包含了一些可以自定义的程序);

11、最终打开根据下面的定义的终端个数来确定打开几个终端,会借助agettymingetty来找到/bin/login程序来打开用户交互式登录界面,此时登录后就打开了/bin/bash程序了。