首页 > 代码库 > 八、Linux系统启动流程

八、Linux系统启动流程

8.1、Centos6的启动流程

  Linux系统的启动分为5个阶段,每个阶段都会完成不同的启动任务。其主要流程可以概括为:

BIOS(BootSequence)-->MBR(bootloader,446)-->GRUB-->Kernel-->/sbin/init

技术分享

  1、计算机启动后,首先进行固件(BIOS)的自检,即所谓的POST(Power On Self Test),然后把保存在MBR中的引导程序加载到内存中。

  2、主引导加载程序通过分区表查找活动分区,然后将活动分区的次引导加载程序从设备读入内存中并运行。

  3、加载次引导程序(GRUB),其中次引导加载程序又可以分为三个阶段

1st stage:位于MBR中,为了引导 2nd stage
1.5 stage:位于boot基本磁盘分区中,为识别内核文件所在的文件系统提供文件系统识别扩展
2nd stage:位于boot基本磁盘分区中,GRUB 的引导程序(/boot/grub/)

  4、Linux内核镜像,在内核的引导过程中,会加载必要的系统模块,以挂载根文件系统(/),完成后内核会启动init进程,并把引导的控制器交给init进程。

  5、init进程会挂载/etc/fstab中设置的所有文件系统,并根据/etc/inittab文件来执行相应的脚本进行系统初始化。

  • BIOS加电自检

 x86计算机在启动后会进行BIOS的加电自检,检测计算机的硬件设备,然后按照CMOS设置的顺序搜索处于活动状态并可以引导的设备。引导设备可以是软盘、光驱、USB设备等。

技术分享

  一般Linux都是从硬盘上进行引导,硬盘上的主引导记录(MBR)中保存有加载程序。MBR是一个512字节大小的扇区,位于硬盘的第一个扇区中,可使用如下命令查看:

[root@localhost ~]# dd if=/dev/sda of=mbr.dmp bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000193145 s, 2.7 MB/s
[root@localhost ~]# file mbr.dmp 
mbr.dmp: x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, boot drive 0x80, 1st sector stage2 0x849fc, GRUB version 0.94; partition 1: ID=0x83, active, starthead 32, startsector 2048, 1024000 sectors; partition 2: ID=0x8e, starthead 221, startsector 1026048, 30431232 sectors, code offset 0x48
[root@localhost ~]# od -xa mbr.dmp   #以ASCII和十六进制格式显示MBR内容
0000000    48eb    1090    d08e    00bc    b8b0    0000    d88e    c08e
          k   H dle dle  so   P   < nul   0   8 nul nul  so   X  so   @
0000020    befb    7c00    00bf    b906    0200    a4f3    21ea    0006
          {   > nul   |   ? nul ack   9 nul stx   s   $   j   ! ack nul
0000040    be00    07be    0438    0b75    c683    8110    fefe    7507
        nul   >   > bel   8 eot   u  vt etx   F dle soh   ~   ~ bel   u
0000060    ebf3    b416    b002    bb01    7c00    80b2    748a    0203
          s   k syn   4 stx   0 soh   ; nul   |   2 nul  nl   t etx stx
0000100    0080    8000    49fc    0008    0800    90fa    f690    80c2
...
  • 引导加载程序GRUB

 GRUB是Centos6.x中默认的引导加载程序。引导过程又可以分为启动主引导加载程序和启动次引导加载程序两个阶段。第一阶段是保存在MBR中的主引导加载程序,主引导加载程序的任务就是查找并加载保存在硬盘分区上的次引导加载程序,它通过分区表查找活动分区,将活动分区的次引导加载程序从设备读入内存并运行,进入引导加载程序的第二个阶段。

  次引导加载程序也被称为内核加载程序,这个阶段的任务是加载Linux内核。一旦次引导加载程序被加载到内存中,便显示GRUB图形界面。

  

技术分享

  在此界面下提供的功能有:

(1) 提供菜单、并提供交互式接口

  e: 编辑模式,用于编辑菜单;c: 命令模式,交互式接口;

(2) 加载用户选择的内核或操作系统

  允许传递参数给内核可隐藏此菜单

(3) 为菜单提供了保护机制

  为编辑菜单进行认证为启用内核或操作系统进行认证

  单击c进入命令行交互模式后,可使用的命令

help: 获取帮助列表help KEYWORD: 详细帮助信息

find (hd#,#)/PATH/TO/SOMEFILE:root (hd#,#)

hd#:磁盘编号,用数字表示;从0开始编号

#: 分区编号,用数字表示;从0开始编号

kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;

initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk

boot: 引导启动选定的内核;

  手动在grub命令行接口启动系统的方法

grub> root (hd#,#)

grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE quiet

grub> initrd /initramfs-VERSION-RELEASE.img

grub> boot

  GRUB的配置文件:/boot/grub/grub.conf

配置语法:

default=0      #设定默认启动的title的编号,从0开始

timeout=5      #等待用户选择的超时时长,单位是秒

splashimage=(hd0,0)/grub/splash.xpm.gz  #grub的背景图片

hiddenmenu     #隐藏菜单

password                    #grub添加密码

title Red Hat Enterprise Linux Server (2.6.18-308.el5)  #内核标题

   root(hd#,#)          #内核磁盘所在分区

           hd#:磁盘编号,用数字表示;从0开始编号

 #: 分区编号,用数字表示;从0开始编号

       kernel         #内核文件路径,及传递给内核的参数

       Initrd         #ramdisk文件路径

[root@localhost ~]# cat /boot/grub/grub.conf    #启动配置示例
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-431.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-431.el6.x86_64.img

  当grub引导程序遭到破坏时,两种拯救方法:

#chroot /mnt/sysimage                           第一种
#grub-install --root-directory=ROOT /dev/DISK

#grub                                           第二种 
grub> root (hd#,#)
grub> setup (hd#)
grub> quit
  • init进程

  init是linux系统所有进程的起点,内核在完成内核引导后,便会加载init进程,其进程号是1。init进程启动后,会初始化操作系统,并启动特定的运行级别(Runlevel)下的自动运行程序。

  当init进程获得控制权后,首先会执行/etc/rc.d/rc.sysinit脚本,根据脚本中的代码完成如下一些操作:

1、激活udev和selinux;                   2、根据/etc/sysctl.conf文件,来设定内核参数;

3、设定时钟时钟;                        4、装载键盘映射;

5、启用交换分区;                        6、设置主机名;

7、根文件系统检测,并以读写方式重新挂载;8、激活RAID和LVM设备;

9、启用磁盘配额;                        10、根据/etc/fstab,检查并挂载其它文件系统;

11、清理过期的锁和PID文件

   接下来,init进程会执行inittab脚本中的代码。该脚本代码中定义了linux系统的运行级别,以及每个级别所对应的引导步骤。

0:halt关机

1: single user mode,直接以管理员身份切入,s,S,single

2:multi user mode, no NFS

3: multi user mode, text mode

4:reserved

5: multi user mode, graphic mode

6: reboot

查看运行级别:runlevel

[root@localhost ~]# 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:      #当前运行在3级别

inittab文件的配置语法:

每一行定义一种action以及与之对应的process   id:runlevel:action:process

  id: 操作的ID

  runlevels: 在哪些级别下执行此操作

  action: 动作

     initdefault: 设置默认运行级别,无需定义操作

     sysinit:指定系统初始化脚本(/etc/rc.d/rc.sysinit)

     wait: 等待系统切换至此级别时运行一次;

     ctrlaltdel: 定义组合键被按下时要运行的命令;

     respawn: 当指定操作进程被关闭时立即再启动一次;

  process: 操作

  在linux系统中每个级别所运行的服务都不一样,每个级别的运行服务脚本文件都分别存放在7个名为/etc/rc.drcN.d的目录下。

[root@localhost ~]# ls -l /etc/rc.d/
total 60
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 init.d
-rwxr-xr-x. 1 root root  2617 Nov 23  2013 rc
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 rc0.d
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 rc1.d
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 rc2.d
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 rc3.d
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 rc4.d
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 rc5.d
drwxr-xr-x. 2 root root  4096 Apr 21 21:30 rc6.d
-rwxr-xr-x. 1 root root   220 Nov 23  2013 rc.local
-rwxr-xr-x. 1 root root 19688 Nov 23  2013 rc.sysinit

  例如在运行级别为3,那么init进程会查找并执行/etc/rc.d/rc3.d/目录下的所有的脚本。目录下的脚本都是一些链接文件,指向了init.d目录下,命名规则为Snn服务名或者Knn服务名。其中,对于S开头的文件,系统会启动对应服务,对于K开头的,系统会终止对应的服务;nn位数字,表示脚本执行顺序,S开头的为文件会按数字从小到大执行,K带头的会从大到小关闭服务。

[root@localhost rc3.d]# ls -l
total 0
lrwxrwxrwx. 1 root root 19 Mar 13 05:20 K10saslauthd -> ../init.d/saslauthd
lrwxrwxrwx. 1 root root 22 Apr 21 21:30 K15htcacheclean -> ../init.d/htcacheclean
lrwxrwxrwx. 1 root root 15 Apr 21 21:30 K15httpd -> ../init.d/httpd
lrwxrwxrwx. 1 root root 20 Mar 13 05:20 K50netconsole -> ../init.d/netconsole
lrwxrwxrwx. 1 root root 21 Mar 13 05:19 K87restorecond -> ../init.d/restorecond
lrwxrwxrwx. 1 root root 15 Mar 13 05:19 K89rdisc -> ../init.d/rdisc
lrwxrwxrwx. 1 root root 18 Mar 13 05:22 K92iptables -> ../init.d/iptables
lrwxrwxrwx. 1 root root 22 Mar 13 05:20 S02lvm2-monitor -> ../init.d/lvm2-monitor
lrwxrwxrwx. 1 root root 19 Mar 13 05:20 S08ip6tables -> ../init.d/ip6tables
lrwxrwxrwx. 1 root root 17 Mar 13 05:20 S10network -> ../init.d/network
lrwxrwxrwx. 1 root root 16 Mar 13 05:20 S11auditd -> ../init.d/auditd
lrwxrwxrwx. 1 root root 17 Mar 13 05:20 S12rsyslog -> ../init.d/rsyslog
lrwxrwxrwx. 1 root root 26 Mar 13 05:20 S25blk-availability -> ../init.d/blk-availability
lrwxrwxrwx. 1 root root 15 Mar 13 05:20 S25netfs -> ../init.d/netfs
lrwxrwxrwx. 1 root root 19 Mar 13 05:20 S26udev-post -> ../init.d/udev-post
lrwxrwxrwx. 1 root root 14 Mar 13 05:20 S55sshd -> ../init.d/sshd
lrwxrwxrwx. 1 root root 17 Mar 13 05:20 S80postfix -> ../init.d/postfix
lrwxrwxrwx. 1 root root 15 Mar 13 05:20 S90crond -> ../init.d/crond
lrwxrwxrwx. 1 root root 11 Mar 13 05:20 S99local -> ../rc.local

  使用chkconfig命令可以配置自动运行的服务。

chkconfig [--list] [--type <type>] [name]
     chkconfig --add <name>
     chkconfig --del <name>
     chkconfig --override <name>
     chkconfig [--level <levels>] [--type <type>] <name> <on|off|reset|resetpriorities>

  在启动过程中/etc/rc.d/rc.local是系统最后启动的一个服务执行的一个脚本。当需要系统启动或关闭时自动执行某些任务可以写在此脚本中。

8.2、Centos7的启动流程

  相对于Centos6的启动方式,Centos7有所改变,其启动方式为:BIOS(BootSequence)-->MBR(bootloader,446)-->GRUB-->Kernel-->/sbin/init /sbin/systemd,其主要区别在于启动后systemd是由内核启动的第一个过程,它取代了sysvinit程序(即INIT),systemd负责协调引导过程中的其余部分并配置为用户的环境。

  systemd相比其他的init程序具有更搞得并行能力,其基于Socket通信的,首先建立个服务的Socket通信,然后各种程序可以同时启动。systemd可以处理程序之间的依赖关系,通常包含以下步骤:

设置主机名;初始化网络;初始化SELinux配置;打印欢迎横幅;初始化基于讷河启动参数的系统硬件;安装文件系统;清理/var目录;设置交换分区。

  systemd具有的特点:

  • 支持并行化任务

  • 同时采用socket式与D-Bus总线式激活服务;

  • 按需启动守护进程(daemon);

  • 利用 Linux 的 cgroups 监视进程;

  • 支持快照和系统恢复;

  • 维护挂载点和自动挂载点;

  • 各服务间基于依赖关系进行精密控制。

  systemd架构示意图:

技术分享

  • Linux运行级别到目标

 systemd使用目标代替了运行级别的概念。

Runlevel 0           |    runlevel0.target -> poweroff.target
Runlevel 1           |    runlevel1.target -> rescue.target
Runlevel 2           |    runlevel2.target -> multi-user.target
Runlevel 3           |    runlevel3.target -> multi-user.target
Runlevel 4           |    runlevel4.target -> multi-user.target
Runlevel 5           |    runlevel5.target -> graphical.target
Runlevel 6           |    runlevel6.target -> reboot.target
  • init与systemd的主要区别

(1)默认的 RunLevel(在/etc/inittab文件设置)现在被默认的 Target 取代,位置是 /etc/systemd/system/default.target,通常符号链接到graphical.target(图形界面)或者multi-user.target(多用户命令行)。

(2)启动脚本的位置,以前是/etc/init.d目录,符号链接到不同的 RunLevel 目录 (比如 /etc/rc3.d、/etc/rc5.d等),现在则存放在/lib/systemd/system和/etc/systemd/system目录。

(3)配置文件的位置,以前init进程的配置文件是/etc/inittab,各种服务的配置文件存放在 /etc/sysconfig目录。现在的配置文件主要存放在/lib/systemd目录,在/etc/systemd目录里面的修改可以覆盖原始设置。


本文出自 “随风而飘” 博客,请务必保留此出处http://yinsuifeng.blog.51cto.com/10173491/1920807

八、Linux系统启动流程