还记得Windows的启动流程吗?相信大家能说出来个大概,为什么说出个大概呢,因为Windows是图形界面启动的,但是开机过程都做了什么,你知道吗,相反,Linux启动的时候,会把这些加载到屏幕上面显示,那接下来我们来看看Linux启动都发生了些什么把!!!


Linux启动流程图

wKiom1fVBELjXsvaAAUkuL83t2Q304.jpg


简解开机启动流程

    当用户打开电源后,BIOS开机自检,确定启动设备,安装启动设备启动设备上面安装的GRUB开始引导Linux,Linux首先先进行内核引导,通过跟切换,执行init程序,init程序确定启动级别,根据启动级别进行系统初始化和运行的服务,然后返回init启动终端,用户通过验证成功登陆Shell,这就是一个从开机到登陆的启动过程


第一步:硬件引导启动


wKioL1fVBKryShbGAADrFHTlj-4910.png


这一部分简单的说就是,BIOS程序引导并加载MBRBootloader程序,也即grub bootloader程序。


当用户打开电源后POST开始自检,检测硬件设备是否确实或者存在故障(是否影响正常开机),如果不影响正常开机,就把任务交给BIOS


BIOS通过搜索,安装启动确定启动设备


启动项为硬盘,BIOS去读取硬盘的前512字节到内存,找到BootLoader,确定GRUB


第二步:GRUB引导启动内核

wKiom1fVCCiS_otBAACaCaDmT6Y903.png

这一步分概况起来即使:GRUB程序加载执行并开始引导kernel程序

Boot Loader就是在操作系统内核运行之前运行的一小段程序。通过GRUB引导可以确定内核程序,因为引导扇区只有446字节,GRUB只是一个小的程序安装在里面,真正使用的在MBR后面的扇区存放,我们想使用Bootloader GRUB功能必须读取后面的文件,Bootloader GRUB功能程序的运行和加载配置选项分为三个阶段


A.Stage1阶段:

Stage1阶段其实就是执行系统安装时预先写入到MBR的Bootloader中的程序。

Stage1阶段的任务仅是将硬盘0柱面0磁道2扇区的内容读入内存并执行,它是Stage1.5阶段或Stage2阶段的入口,引导进入Stage1.5阶段或Stage2阶段。 

在此Stage1阶段,还没有识别文件系统的能力。


B.Stage1.5阶段

stage1.5阶段是stage1阶段和stage2阶段的中间桥梁。stage1.5阶段具有识别启动分区文件系统的能力,此后GRUB程序便有能力去访问/boot分区下/grub目录下的 stage2文件,并将stage2载入内存执行。


C.Stage2阶段

Stage2阶段执行时,首先会解析GRUB程序的配置文件grub.conf,并依配置文件决定是否显示系统启动菜单。然后加载内核镜像到内存中,通过initrd程序建立RAMDisk内存虚拟根文件系统。此时控制权将转交给内核程序。


第三部:内核引导启动

wKiom1fVClews7eUAAA00sCzm-c795.png


这一部分主要是通过在内存中建立虚拟根文件系统实现相关设备的驱动并建立和切换到真正的根文件系统。


解压内核镜像加载到内存,以及initrd程序建立RAMDisk内存虚拟根文件系统后,内核开始驱动基本硬件,并调用虚拟根文件系统中的init程序加载驱动模块初始化系统中各种设备的相关配置工作,其中包括CPU、I/O、存储设备等。当所需的驱动程序加载完后,会根据grub.conf配置文件中“root=XXX”部分所指定的内容创建一个根设备,然后将根文件系统以只读的方式挂载,并切换到真正的根文件系统上,同时调用系统进程的老祖宗进程/sbin/init程序,进入系统初始化阶段。


第四步:系统初始化

wKiom1fVC3mg-U07AADipmcMw3g129.png

这一步是通过/sbin/init,init程序准备软件运行坏境,启动系统服务


通过/etc/inittab文件确定运行级别,然后去执行系统初始化脚本/etc/rc.sysinit,为用户初始化用户空间环境,在完成初始化后,根据运行级别,系统开始对应级别的目录启动服务,关闭那些不要的服务(里面S99local -> ../rc.local)用户自动服务启动脚本


文件详解:

/etc/inittab文件

wKioL1fVHw_iyP9TAADW9PL__FM892.png

这个文件是设置系统启动的默认级别


设置默认运行级别

  (1)运行级别:为了系统的运行或维护等目的而设定的机制;

    0-6:共7个级别;

     0:关机,shutdown

     1:单用户模式(single user),root用户,无须认证,维护模式;

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

     3:多用户模式(multi user),完全功能模式,文本界面;

     4:预留级别:目前无特别使用目的,但习惯以同3级别功能使用;

     5:多用户模式(multi user),完全功能模式,图形界面;

     6:重启,reboot

centos5和6已经不一样了,CentOS5这里还可以设置【ctrl】+【alt】+【del】和【UPS】【tty】【和系统初始化脚本】,现在这些已经默认了,在这个文件由详解


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

(1)设置主机名;

(2)设置欢迎信息;

(3)激活udev和selinux;

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

(5)检测根文件系统,并以读写方式重新挂载根文件系统;(重新挂载是指根文件检测完之后)

(6)设置系统时钟;

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

(8)激活lvm即软raid设备;

(9)激活swap设备;

(10)加载额外设备的驱动程序;(内核加载驱动只加载根文件系统的)

(11)清理操作;


脚本文件/etc/rc.d/

关闭/启动对应级别下的服务

[root@localhost ~]# ls /etc/rc.d/
init.d  rc  rc0.d  rc1.d  rc2.d  rc3.d  rc4.d  rc5.d  rc6.d  rc.local  rc.sysinit

  脚本文件/etc/rc.d/rc作用为当级别切换时启动或停止服务;此脚本接受传递的参数给脚本中$runlevel变量,然后,读取/etc/rc$runlevel.d/K*和/etc/rc$runlevel.d/S*所有文件,这些文件就是为什么开机启动后,有些服务会自动启动,有些服务没有启动的原因。

[root@localhost ~]# ls /etc/rc.d/rc3.d/
K01smartd          K69rpcsvcgssd      K95rdma          S13cpuspeed          S25netfs      S82abrtd
K05wdaemon         K73winbind         K99rngd          S13irqbalance        S26acpid      S90crond
K10psacct          K74ntpd            S01sysstat       S13rpcbind           S26haldaemon  S95atd
K10saslauthd       K75ntpdate         S02lvm2-monitor  S15mdmonitor         S26udev-post  S99firstboot
K15htcacheclean    K75quota_nld       S08ip6tables     S22messagebus        S28autofs     S99local
K15httpd           K84wpa_supplicant  S08iptables      S23NetworkManager    S50bluetooth
K30spice-vdagentd  K87restorecond     S10network       S24nfslock           S50kdump
K50dnsmasq         K89netconsole      S11auditd        S24rpcgssd           S55sshd
K60nfs             K89rdisc           S11portreserve   S25blk-availability  S80postfix
K61nfs-rdma        K92pppoe-server    S12rsyslog       S25cups              S82abrt-ccpp

K*:要停止的服务,K##*,优先级,数字越小,越优先关闭,依赖的服务先关闭,然后再关闭被依赖的。

S*:要启动的服务,S##*,优先级,数字越小,越是优先启动,被依赖的服务先启动,而依赖的服务后启动。

这些文件都是链接文件,它们链接到了/etc/init.d/*目录下的各个程序的,例如ntpd这个脚本

[root@localhost ~]# ls /etc/rc.d/rc3.d/K74ntpd -ld
lrwxrwxrwx. 1 root root 14 Jul 25 08:38 /etc/rc.d/rc3.d/K74ntpd -> ../init.d/ntpd


那我们怎么设置某一服务下次重启系统后是该关闭或者开启呢?可以使用chkconfig命令实现:

checkconfig 

命令格式:

chkconfig [options] Service_Name [on|off] 
    Options: 
         --add              #→添加程序服务 
         --list             #→列出当前系统上所有的服务对应的级别是关闭还是启动 
         --del              #→删除某个服务(只是删除链接文件,不删除原文件) 
         --level [on|off]   #→指定某个服务对应哪些级别是on或off


用户自定义开机启动程序,可以根据自己的需求将一些执行命令或是写到脚本/etc/rc.d/rc.local.当开机时就可以自动加载啦!

[root@localhost ~]# ll /etc/rc.d/rc3.d/S99local 
lrwxrwxrwx. 1 root root 11 Jul 25 08:37 /etc/rc.d/rc3.d/S99local -> ../rc.local


第五步:启动终端,用户登录shell

wKioL1fVEcLxmKhIAACaOKZ5zJ8383.png

这一步是用户登录shell过程


如果没有改变级别,默认情况执行/sbin/mingetty打开6个纯文本终端,让用户输入用户名和密码。输入完成后,再调用login程序,核对密码。如果密码正确,就从文件 /etc/passwd 读取该用户指定的shell,然后启动这个shell。



GRUB详解

当计算机加电自检后,ROM BIOS加载MBR(主引导扇区,即硬盘第一扇区)中的代码到内存中,这个扇区一共512字节,前446字节内容存放grub(bootloader)的关键引导程序,接着64字节放置硬盘分区表DPT(Disk Partition Table),一共四可以有四个主分区,占64个字节,这也是为什么主分区最多只有四个的原因,最后2个字节是固定的标志0x55AA。当BIOS把引导程序加载到内存后就把控制权交给grub,而后grub的剩余代码将完成其它代码的加载和搬移以及文件系统初始化查找等工作,最终加载内核映像文件,从而把控制权交给真正的内核运行。

wKiom1fVFunRTkoWAAAWIeqKFKQ983.png


/boot/grub/grub.conf配置文件详解:

[root@centos6 grub]# ll /etc/grub.conf #/etc/grub.conf /boot/grub/grub.conf为连接文件
lrwxrwxrwx. 1 root root 22 8月  11 03:29 /etc/grub.conf -> ../boot/grub/grub.conf
[root@centos6 grub]# 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/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0 #设定默认启动菜单项,默认为0开始
timeout=5 #指定菜单等待选择的时长 
splashimage=(hd0,0)/grub/splash.xpm.gz #指定菜单的背景图片的路径,为xpm格式,采用gzip压缩
hiddenmenu #是否影藏菜单
password --md5 $1$1S9Xy$1MuGZSoPc2vAtkW.jvz0X/ #菜单编辑认证
title CentOS 6 (2.6.32-642.el6.x86_64) #定义菜单项
password 123456 #可以选择明文
root (hd0,0) #本次grub查找stage2及其kernel文件所在设备分区,指定grub的根
kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=UUID=240533cf-b37f-4460-974f-702bab867da5 nomodeset rd_NO_LUKS  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_MD crashkernel=auto LANG=zh_CN.UTF-8 rd_NO_LVM rd_NO_DM rhgb quiet #需要启动的内核 
initrd /initramfs-2.6.32-642.el6.x86_64.img #内核匹配的ramfs文件

我刚才在里面加入了两个密码,对GRUB的保护机制,输入密码才能编辑

生成加密的密文

[root@localhost ~]# grub-md5-crypt 
Password: 
Retype password: 
$1$1S9Xy$1MuGZSoPc2vAtkW.jvz0X/

wKiom1fVGgSjHTPYAAAWeIkdU0M871.png

问题来了

如果grub被破坏了导致系统无法启动该怎么办???


通过光盘进入紧急救援模式来进行修复

1,用关盘启动,在安装界面选择 Rescue installed system 进入救援模式

2,根据提示选择语言和键盘

3,选择是否配置网卡,选择no

4,根据硬盘上的系统提示已经找到并挂载在/mnt/sysimage下,continue用读写模式加载

5,输入 chroot /mnt/sysimage 改变磁盘根目录

6,fdisk -l /dev/sda 使用fdisk检查分区

7,grub-install /dev/sda 安装grub引导程序到磁盘/dev/sda的MBR扇区

8,exit

centos 7的安装修复方式

sh 3.1#grub

grub>root(hd0,0)

grub>setup(hd0)

grub>quit