CentOS系统启动流程(上)

CentOS系统启动流程(上)

 

作为系统运维人员,详细的了解操作系统的启动流程,对于我们日常排除故障大有益处,遇到相关的问题处理,能快速定位,迅速锁定关键点。

下面详细介绍一下,CentOS系统的启动过程,以供各位参考。由于linux各个发行版使用的启动方法略有不同,比如CentOS5使用的是initdCentOS6使用的是较为接近的Upstart,而CentOS7则是使用画风完全不同的Systemd,因而,对于其中有区别的部分,我也会对应不同的发行版本来分别介绍。

一个基本的操作系统,无非就是由内核+系统级别的库+应用程序所组成。其中,内核负责进行内存管理、进程管理、安全管理、网络管理以及硬件驱动程序的管理。库提供了上层应用程序向下层操作系统的调用接口。应用程序,顾名思义,就是能提供各种功能各种服务的软件了。这其中,内核是整个系统的根本,没有内核,则应用程序也无法单独存在。因而,每个操作系统,内核是必不可少的,想要使用电脑,则必需先启动内核。因而,操作系统的启动,实际上也就是内核启动的过程。

回到正题,一般操作系统启动的过程,大致可分为以下几个步骤:

加电自检(POST)–>BootLoader选择引导的内核–>内核启动,建立内核空间–>加载根文件系统–>建立用户空间,并启动用户空间的第一个程序,然后创建交互式接口,等待用户的操作指令

 

加电自检(POST)

通过固化在主板上CMOSROM芯片,执行指定程序,进行硬件检测。该步骤主要检查硬件几大部件,CPU、主板、内存、显卡等设备,维持计算机运行的主要部件。如设备有问题,自检不通过,设备也点不亮。当然,也会顺带检测其它一些非必要的硬件设备,比如外设:鼠标键盘网卡声卡等。

 

BootLoader

BIOS(Basic Input and Output System)设置里,有个选项是关于引导顺序(BOOT Sequence)的,加电自检完成后,系统会根据BOOT Sequence里设定的顺序,查找可用的MBR(主引导记录),一旦找到设备有MBR(就是第一个找到的MBR设备),则会选择从该设备引导系统。MBR记录中,有bootloader程序,大小为446字节,该部分记录了引导系统的重要信息。该程序的主要功能,是提供一个菜单,允许用户选择要启动的系统或不同的内核版本,把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核,从而完成内核的引导。

这里插入一段小插曲,以前比较老的系统,BootLoader的任务由LILO(LInux LOader)的软件所承担,而该软件也能很好的完成它的任务。因为以前的硬盘容量都比较小,因而446字节的信息描述足以完成对内核的加载。而随着现今硬盘容量的激增,每个分区都很大,而内核程序有可以保存在每一个分区中,这样,对于大容量硬盘,LILO则显得有点力不从心了。不过Linux界从来都不缺明星呀,新一代的BootLoader软件–GRUB: GRand Unified Bootloader (GRUB)闪亮登场。

GRUB传统版本用于CentOS56,版本号是0.X,新的CentOS7则升级到1.X版本。GRUB采用了分阶段运行的方式,成功的绕开了446字节的限制,实现了对大容量硬盘的支持。第1阶段,GRUB依然是驻留在MBRbootloader中,这一阶段的BRUB,主要完成对内核所在设备的链接,找到内核驻留到的存储设备。然后,GRUB有个过渡阶段,可称为1.5阶段吧,该阶段利用找到的存储设备上的文件,识别内核所在硬盘分区上的文件系统,加载内核所在设备的驱动程序。能识别内核所在硬盘分区的文件系统,事情就好办了,第2阶段,将内核加载到内存的特定位置,运行,并将系统的控制权移交到该内核。至此,内核完成加载并开始启动。

 

内核启动,建立内核空间,加载根文件系统,建立用户空间:

Kernel启动后,会进行以下操作:

    自身初始化;

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

    加载硬件驱动程序:(有可能会借助于ramdisk加载驱动);

    以只读方式挂载根文件系统;

    运行用户空间的第一个应用程序;

 

其中用户空间的第一个应用程序的创建,各个发行版本因应使用的技术,在实现上略有不同,在CentOS5上沿用的是sysv风格的initd;而CentOS6使用的是在initd升级改良而来的UpstartCentOS7,则采用了全新的systemd技术。鉴于CentOS5 CentOS6采用的技术较为雷同,在此,以CentOS5所使用的initd进行讲解,至于CentOS7所使用的systemd技术,我会在下篇中说明,在这里先卖个小广告,敬请大家期待。

 

CentOS5运行用户空间的第一个应用程序是 /sbin/initinit以守护进程的形式而存在,且是所有用户空间进程的父进程,所有用户空间进程均由init进程创建派生而来。同时,在init运行的同时,init会利用脚本程序,对系统环境进行大量的操作,以便完成系统初始化。

 

对于系统初始化,我们特别定制了一个特殊的脚本:/etc/rc.d/rc.sysinit。这个脚本在系统初始化时运行,并执行一些特殊的操作,其主要实现的功能有:

 (1)设置主机名:

 (2)设置欢迎信息:

 (3)激活udevselinux

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

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

 (6)设置系统时钟

 (7)激活swap设备

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

 (9)激活lvmsoftware raid设备

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

 (11)清理操作

 

然后,CentOS有个运行级别的概念。什么是运行级别呢?运行级别就是为了系统的运行或维护等应用目的而设定的运行等级。

CentOS5/67个运行级别,分别是:

      0:关机

      1:单用户模式(root,无须登录,无需密码),single,维护模式

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

      3:多用户模式,正常模式,文本界面

      4:预留级别,暂不使用,但可视为同3级别一样

       5:多用户模式,正常模式,图形界面

       6:重启系统

其中,默认级别是级别3 或级别5

 

Init程序运行时,会读取 /etc/inittab的配置文件,根据配置文件的不同而执行相应的动作。这里贴出一个inittab配置文件的例子:

 

[root@www ~]# cat /etc/inittab

# inittab is only used by upstart for the default runlevel.

#

# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

#

# System initialization is started by /etc/init/rcS.conf

#

# Individual runlevels are started by /etc/init/rc.conf

#

# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf

#

# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,

# with configuration in /etc/sysconfig/init.

#

# For information on how to write upstart event handlers, or how

# upstart works, see init(5), init(8), and initctl(8).

#

# Default runlevel. The runlevels used are:

#   0 – halt (Do NOT set initdefault to this)

#   1 – Single user mode

#   2 – Multiuser, without NFS (The same as 3, if you do not have networking)

#   3 – Full multiuser mode

#   4 – unused

#   5 – X11

#   6 – reboot (Do NOT set initdefault to this)

#

id:3:initdefault:

 

文件前面的都是注释说明,实际只有一行,即最后一行是实际配置。它的格式为:

id:runlevel:action:process

其中:

Id:就是每行的id值,不重复即可;

Runlevel:就是上面提到的运行级别的数值;

Action:action分别有如下的动作:

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

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

    initdefault:设定默认运行级别,  process省略

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

    

上面例子中的:id:3:initdefault:  #就是默认运行3级别的意思

 

划分了运行级别,到底有什么作用呢?让我们看看/etc/rc.d目录下的内容:

 

[root@www /]# ls -lh /etc/rc.d

total 60K

drwxr-xr-x. 2 root root 4.0K Apr  7 18:52 init.d

-rwxr-xr-x. 1 root root 2.6K Oct 16  2014 rc

drwxr-xr-x. 2 root root 4.0K Apr  7 18:53 rc0.d

drwxr-xr-x. 2 root root 4.0K Apr  7 18:53 rc1.d

drwxr-xr-x. 2 root root 4.0K Apr  7 18:53 rc2.d

drwxr-xr-x. 2 root root 4.0K Apr  7 18:53 rc3.d

drwxr-xr-x. 2 root root 4.0K Apr  7 18:53 rc4.d

drwxr-xr-x. 2 root root 4.0K Apr  7 18:53 rc5.d

drwxr-xr-x. 2 root root 4.0K Apr  7 18:53 rc6.d

-rwxr-xr-x. 1 root root  340 Dec 29 23:22 rc.local

-rwxr-xr-x. 1 root root  20K Oct 16  2014 rc.sysinit

 

这里,rc0.drc6.d几个目录,对应的正是我们之前设置的7个运行级别。聪明的小伙伴看到这里一定猜到了什么了。我们再选rc3.d看看:

 

[root@www /]# ls -lh /etc/rc.d/rc3.d/

total 0

lrwxrwxrwx. 1 root root 16 Dec 25 06:15 K01smartd -> ../init.d/smartd

lrwxrwxrwx. 1 root root 17 Dec 25 06:10 K02oddjobd -> ../init.d/oddjobd

.

.

.

lrwxrwxrwx. 1 root root 18 Dec 29 22:33 K92iptables -> ../init.d/iptables

lrwxrwxrwx. 1 root root 19 Dec 25 06:31 K95firstboot -> ../init.d/firstboot

lrwxrwxrwx. 1 root root 14 Dec 25 06:15 K99rngd -> ../init.d/rngd

lrwxrwxrwx. 1 root root 17 Dec 25 06:13 S01sysstat -> ../init.d/sysstat

lrwxrwxrwx. 1 root root 22 Dec 25 06:14 S02lvm2-monitor -> ../init.d/lvm2-monitor

lrwxrwxrwx. 1 root root 22 Dec 25 06:36 S03vmware-tools -> ../init.d/vmware-tools

lrwxrwxrwx. 1 root root 17 Dec 25 06:07 S10network -> ../init.d/network

.

.

.

lrwxrwxrwx. 1 root root 15 Apr  7 18:53 S85httpd -> ../init.d/httpd

lrwxrwxrwx. 1 root root 15 Dec 25 06:10 S90crond -> ../init.d/crond

lrwxrwxrwx. 1 root root 13 Dec 25 06:00 S95atd -> ../init.d/atd

lrwxrwxrwx. 1 root root 20 Dec 25 06:10 S99certmonger -> ../init.d/certmonger

lrwxrwxrwx. 1 root root 11 Dec 25 06:07 S99local -> ../rc.local

 

鉴于编幅,中间省略了一大段,免得被人说我刷稿费呀。

虽然省略了不少内容,但各位有没有从中发现什么规律呢?

对,里面都是由K01某服务脚本…K99某服务脚本,S01某服务脚本…S99某服务脚本组成。什么意思呢?K##开始的,对应的是关闭某某服务软件的脚本,而S##对应的,则是开启某某服务软件的脚本。比如: K92iptables 的功能,就是关闭iptables服务,而S85httpd,则是开启httpd服务了。

我们再来看看httpd服务

lrwxrwxrwx. 1 root root 15 Apr  7 18:53 S85httpd -> ../init.d/httpd

S85httpd链接到了上级目录 ../init.d/httpd,因而,实际执行代码的脚本是在/etc/rc.d/init.d中的httpd脚本。这就是系统存放服务脚本的地方。

每个服务,我们都会按优先级编定不同的次序(S##,K##),然后,在选择了相应的运行等级里,按次序运行该级别K##的脚本,以实现关闭该级别下的服务,然后,按次序运行该级别S##的脚本,以实现启动该级别下的服务。

 

系统脚务脚本与一般脚本的功能一样,只是在脚本开始的注释上有所要求,系统服务脚本的格式为:

 

#!/bin/bash

#

#chkconfig: LLL nn nn

 

其中,LLL是服务默认启动的级别,比如LLL345,则表示此服务默认在3级别、4级别、5级别下都是运行的。第一个nn则是用于启动的序号,比如上面的httpd服务,nn85,则脚本名称就影射为S85httpd;第二个nn是关闭的序号,又比如上面的iptabled服务,nn92,则脚本名称影射为K92iptables

 

通过以上的规划,我们为系统的各种服务设置了各种场景。比如在多用户模式3级别下,我们可定制系统某些服务在内核启动后则自动加载运行,某些服务则不加载。在关机模式0级别下,我们可定制系统关闭某服务,然后才安全关机。

 

 

最后,系统在执行完上述的脚本命令后,还会默认启动6个虚拟终端,以等待用户登录,提供界面以执行交互式操作。

tty1:2345:respawn:/usr/sbin/mingetty tty1

tty2:2345:respawn:/usr/sbin/mingetty tty2

Tty3:2345:respawn:/usr/sbin/mingetty tty3

tty4:2345:respawn:/usr/sbin/mingetty tty4

Tty5:2345:respawn:/usr/sbin/mingetty tty5

tty6:2345:respawn:/usr/sbin/mingetty tty6

 

以上,就是CentOS5的系统启动全过程,是不是觉得眼花瞭乱呢,没关系,让我们总结一下整个过程:


CentOS5的系统启动全过程:

加电自检(POST)–>Boot Sequence(BIOS) –>BootLoader(MBR)选择引导的内核–>内核启动,建立内核空间–>加载根文件系统–>建立用户空间,并启动用户空间的第一个程序 /sbin/init –> (/etc/inittab) –>设置默认运行级别 –> 运行系统初始脚本、完成系统初始化 –> 关闭对应级别下需要关闭的服务,启动需要启动的服务 –>设置登录终端,等待用户登录

 

这样一整理,是不是觉得整个启动过程清晰明瞭了 :-)

 

至于CentOS6,其启动过程与5其实是大同小异的,只是CentOS6init配置文件为/etc/init/*.conf下的一堆配置文件,而/etc/inittab 也为兼容5而依然存在。具体到二者的不同,表现在CentOS5init执行脚本为顺序执行,因而在系统启动时会串行地执行一大堆的脚本命令,效率显得不高。而CentOS6在其之上稍作改变,init的脚本执行机制类似于并行,因而Upstart的方式比init的方式来得高效。

 

CentOS6的系统启动全过程:

加电自检(POST)–>Boot Sequence(BIOS) –>BootLoader(MBR)选择引导的内核–>内核启动,建立内核空间–>加载根文件系统–>建立用户空间,并启动用户空间的第一个程序 /sbin/init –> (/etc/inittab,/etc/init/*.conf) –>设置默认运行级别 –> 运行系统初始脚本、完成系统初始化 –> 关闭对应级别下需要关闭的服务,启动需要启动的服务 –>设置登录终端,等待用户登录

 

上述为CentOS5CentOS6的系统启动过程,由于CentOS7采用的是systemd的机制,与上述的两种机制相比,发生了很大的变化,因而,我会在下篇中详述。

 

以上是我对CentOS系统启动过程的理解!作为初学者,我对linux的认识还是很肤浅,上述可能有不正确的地方,如有错漏,希望各位能及时指正,共同进步。

 

  我的QQ153975050 

  在此感谢马哥及马哥团队,在linux的道路上引领我一直向前!

                                                  

                                                                                                                               小斌斌

                                                    2016-06-06

 

 

 

 

 

原创文章,作者:马哥Net19_小斌斌,如若转载,请注明出处:http://www.178linux.com/17856

(0)
上一篇 2016-06-09 22:14
下一篇 2016-06-10 13:21

相关推荐

  • 文本三剑客之grep

    文本编辑三剑客之grep 目录 一、正则表达式 二、grep:文本过滤器 一、正则表达式 REGEXP:由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面上的意义,而表示控制或者通配的功能。分类: 基本正则表达式:BRE 扩展正则表达式:ERE 元字符的分类: 字符匹配 匹配次数 位置锚定 分组 (1)基本正则表达式元字符 1>…

    2017-03-26
  • N25_第二周作业

      1、Linux上的文件管理命令都有哪些,其常用的使用方法及其相关示例演示。  cp命令:                                  &nbsp…

    Linux干货 2016-12-13
  • 第二章 操作系统发展史

    Linux主流版本:   Debian(英语发音:/ˈdɛbiən/)是由GPL和其他自由软件许可协议授权的自由软件组成的操作系统,由Debian项目(Debian Project)组织维护。   历史: Debian于1993年8月16日由一名美国普渡大学学生伊恩·默多克(Ian Murdock)首次发表。伊恩·默多克最初把他的系统称为…

    Linux干货 2016-06-03
  • MySQL常用命令

    本文大纲 MySQL命令             (0%) 交互式CLI工具     服务端命令 mysqld服务器程序 数据类型 DDL语句                 &n…

    Linux干货 2017-02-16
  • bash脚本之数组及字符串切片,登陆配置文件

    一,概述 数组(就是一堆变量的集合) 变量:存储单个元素的内存空间 数组:存储多个元素的连续的内存空间,相当于多个变量的集合/ 数组名和索引     索引:编号从0开始,属于数值索引     注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本之后…

    Linux干货 2016-09-01
  • 重定向、管道——Linux基本命令(9)

    1.     输出重定向 Linux默认输入是键盘,输出是显示器。可以用重定向来改变这些设置。比如用wc命令的时候本来是要手动输入一篇文字来计算字符数的,可以直接把一个已经写好的文件用‘<’指向这条命令,就直接可以统计这个文件的字符数等了。   STDOUT(标准输出)和STDERR(标准错误)可以被重…

    2017-07-20