任何系统启动的第一步必然是加电,也就是按下电源开关,然后计算机硬件会主动读取BIOS来加载硬件设备,以及进行硬件设备的自我检测,之后系统会主动的读取第一个有引导程序的设备,该引导程序可以指定使用哪个内核来启动,并将其加载至内存当中运行,等所有硬件设备完全加载完成后,系统就真正启动起来了。稍后系统会操作一些外部程序开始准备软件的运行环境,之后加载一些系统运行所需要的软件程序,最后一步就是等待用户的登录操作。
整体上来说系统启动分为以下几个过程:
1)加电自检:power on system test (POST)
2)选择启动顺序,加载MBR
在硬件设备初始化之后,BIOS会列出一些可以启动的装置顺序,接下来就开始读取第一个可以启动的设备中操作系统的核心文件,但是由于不同的操作系统其文件系统格式不同,因此为了避免这些格式信息的“不兼容”问题,我们必须要以一个启动管理程序来处理这些核心文件加载问题,这个启动管理程序为:Boot Loader。
#Boot Loader 的主要功能就是去识别、加载操作系统中的核心文件,并提交到内存中运行,进而来启动相应的操作系统。
#Boot Loader 的另一个主要功能是提供菜单信息(可以向使用者提供不同的启动项目,来加载不同的操作系统),并将启动管理功能转交给其他的加载程序。
3)加载系统内核Kernel,并执行系统初始化信息
在Boot Loader 开始读取操作系统内核文件后,接下来就会将内核文件解压缩后装载到内存当中,然后根据内核提供的功能开始测试与加载各个设备(CPU、硬盘、网卡等)。在这里我们采用了一种叫虚拟文件系统,它放置在/boot目录下,并且是一个以initrd开头的文件,这个initrd文件的特点是,能够通过Boot Loader 程序将其加载到内存中,然后这个文件会被解压缩并且在内存中模拟一个根文件系统,这个根文件系统能够提供一个可以运行的程序。
4)启动用户空间第一个执行的程序/etc/init
在内核、硬件及驱动信息加载完毕后,内核会呼叫用户控件的第一个执行程序/etc/init,init程序主要功能是准备软件运行环境,包括系统的主机名称、网络配置、文件系统格式等其他服务的启动管理,而这些所有的操作都是通过init文件来定义的。在init文件的配置当中有一个非常重要的配置项目,那就是默认的的系统启动级别,启动级别就是为系统维护的目的而设定的,途径是设定启动或关闭服务实现的。级别分类如下图所示
通常使用较多的默认级别为3或者5,服务基本上默认使用3级别,当然不同级别之间是可以进行切换的,切换方式为runlevel或who -r命令来查当前运行的级别。而init又是根据/etc/rc.d/rc.sysinit中定义的内容进行系统的初始化,/etc/rc.d/rc.sysinit所做的事情主要有以下几点:
#根据配置文件中的设定来设定主机名
#激活SELinux和udev
#挂载所有定义在/etc/fstab文件中的文件系统
#激活swap设备
#检测根文件系统,并实现以实现读写重新挂载
#设置系统时钟
#根据/etc/sysctl.conf文件设定内核参数的值
#激活LVM和RAID设备
#加载额外的设备驱动程序
#清理操作
在/etc/rc.d/rc.sysinit初始化完成系统之后,此时的系统就已经顺利的开始工作了,只不过此时我们还要启动一同所需要的各项服务,这样主机才能提供一些我们需要的服务功能,如网络服务、dhcp服务等等。这里就的通过inittab里面提到的/etc/rc.d/rcS.d配置了,实际上就是通过目录下所有连接文件来决定如何启动或关闭服务,即所有以“s”开头的,都被传递start参数以启动,所有以“k”开头的,都被传递stop参数以停止。过程脚本如下图
在完成系统所有相关服务启动之后,接下来Linux就会启动终端或者是来向用户提供登录界面。例如,启动虚拟终端,一般启动6个虚拟终端,每个终端启动之后,会立刻通过此终端附加一个应用程序--login,如果默认级别为5,还会启动一个图形虚拟终端,会附加X应用程序。综上所述,系统的启动流程可以理解为,在BIOS读取相关信息之后,接下来就是去第一个可以启动的设备当中的MBR中读取Boot Loader信息,Boot Loader提供具有菜单功能、直接加载内核信息,以及相关的控制权转交功能,也就是说系统必须有Boot Loader,然后才能去加载内核。而Boot Loader存储于MBR当中,MBR只有512bytes,其中446bytes存储Boot Loader,而很显然的的446bytes根本不够用的,那么为了解决这个问题,Linux将Boot Loader的程序运行与配置项加载分成三个阶段来运行:
#stage1、运行Boot Loader主程序,这个程序必须要被安装在启动区,即MBR中。因为MBR空间有限,因此在MBR当中仅安装Boot Loader的最小主程序,并没有安装Boot Loader的相关配置文件。
#stage1_5、在MBR随后的扇区中存放,主要用于与stage2所在分区的文件系统进行交互。
#stage2、通过Boot Loader加载所有配置文件及相关的环境参数信息,这些配置文件及相关的环境参数都存放于磁盘分区上的/boot目录下。如下图所示
由此可以得知在/boot/grub目录下最重要的是grub的配置文件及各种文件系统的定义,当Boot Loader读取了这些文件系统所定义的数据后,就能够识别文件系统并读取在该文件系统上的内核文件了。grub.conf的配置文件是什么样的,应该怎么设置呢,那我们先了解一下它的文件格式,如下图所示
由图我们分解一下grub.conf文件的内容:
#default=0 表示默认的启动条目,假如同事装有多个操作系统,0就表示的第一个title系统,1表示定义的第二个title系统,以此类推。
#timeout=5 表示可供选择的等待的时间,如果超过5秒,则使用默认的启动条目dafault定义的内容。
#splashimage=(hd0,0)/grub/splash.xpm.gz 定义启动时的背景图片信息
#hiddenmenu 启动时是否要显示菜单,默认情况下是不显示不显示菜单信息,如果想要显示菜单信息,可以将该配置注释即可。
#title 定义各个操作系统的名称
#root 表示内核文件的存放位置,这里指定的是分区位置,而非根目录。
#kernel 内核名称及一些启动时的核心参数,由于启动过程中需要挂载根目录,因此就需要指定根目录所在分区的位置,rhgb表示色彩显示,quiet表示静默模式加载内核。
#initrd 就是前面提到的initrd,即虚拟文件系统。
到这里,系统启动的整个过程也就介绍完了,那如果grub文件出现了问题,系统肯定就无法正常启动了,那我们就要分析Linux在Boot Loader的程序运行与配置项加载三个阶段来进行排错解决,下面举例说说在系统无法正常启动时如何去排错、修复:
一)破坏stage1后,修复并完成系统正常启动
1、系统无法正常启动,直接进入了光盘引导界面。
2、进入rescue救援模式
3、chroot /mnt/sysimage/ 改变到磁盘的根目录
grub-install /dev/sda 安装grub引导程序到磁盘/dev/sda的MBR扇区。
4、退出并重启
5、修复成功
二)破坏stage1_5后,修复并完成系统正常启动
1、无法读取stage1_5,无法完成正常启动
2、进入救援模式
3、chroot /mnt/sysimage/ 改变到磁盘的根目录
grub-install /dev/sda 安装grub引导程序到磁盘/dev/sda的MBR扇区。
4、root(hd0,0) 指定内核存放位置为第一个磁盘上的第一个分区
setup (hd0,0) 启动安装tage1,Stage1_5,Stage2
5、重启,修复成功
三)stage2破坏,缺失了/boot/grub下的所有文件,修复并完成系统正常启动
1、报错,系统无法完成正常启动
2、root(hd0,0) 指定内核存放位置为第一个磁盘上的第一个分区
kernel /vmlinuz-2.6.32-696.e16.x84_64 ro root=/dev/sda2 设置内核文件路径,根文件系统所在设备
initrd /initramfs-2.6.32-696.e16.x84_64 指明辅助内核完成启动的ramdisk文件路径在内存缓存
3、boot重新启动程序
4、修复成功
四)3个阶段全部损坏,/boot下所有文件全部缺失,修复并完成系统正常启动
1、报错,系统无法正常启动
2、进入救援模式操作
2、chroot /mnt/sysimage/ 改变到磁盘的根目录
grub-install /dev/sda 安装grub引导程序到磁盘/dev/sda的MBR扇区。
3、mount /dev/cdrom /media 挂载光盘
cp /media/isolinux/vmlinux /boot mkinitrd /boot/initramfs-$(uname -r).img $(uname -r) 生成initrd
4、vim /boot/grub/grub.conf 新建/grub.conf文件
5、exit退出救援模式,并重启
5、修复成功
五)/etc/fstab 及/boot下的所有文件全部损坏,修复并完成系统正常启动
1、文件缺失,系统无法正常启动
2、切换进入救援模式
3、mount /dev/sda2 /mnt/sysimage 挂载根目录
blkid >> /mnt/sysimage/etc/fstab 将UUID信息导入根目录下的/etc/fstab中
chroot /mnt/sysimage 切换进入根目录下
vim /etc/fstab 进入/etc/fstab文件
4、重新编辑/etc/fstab文件信息
5、重启,再次进入救援模式
6、chroot /mnt/sysimage/ 改变到磁盘的根目录
grub-install /dev/sda 安装grub引导程序到磁盘/dev/sda的MBR扇区。
7、mount /dev/cdrom /media 挂载光盘
cp /media/isolinux/vmlinux /boot mkinitrd /boot/initramfs-$(uname -r).img $(uname -r) 生成initrd
8、vim /boot/grub/grub.conf 新建/grub.conf文件
9、exit退出救援模式,并重启
10、修复成功
六)etc/fstab 文件、/etc/init/rcS.conf文件、 /etc/rc.d/rc.sysinit文件及/boot文件全部损坏,修复并启动系统
1、文件缺失,系统无法正常启动
2、切换进入救援模式
3、mount /dev/sda2 /mnt/sysimage 挂载根目录
blkid >> /mnt/sysimage/etc/fstab 将UUID信息导入根目录下的/etc/fstab中
chroot /mnt/sysimage 切换进入根目录下
vim /etc/fstab 进入/etc/fstab文件
4、重新编辑/etc/fstab文件信息
5、重启,再次进入救援模式
6、chroot /mnt/sysimage/ 改变到磁盘的根目录
grub-install /dev/sda 安装grub引导程序到磁盘/dev/sda的MBR扇区。
7、mount /dev/cdrom /media 挂载光盘
cp /media/isolinux/vmlinux /boot mkinitrd /boot/initramfs-$(uname -r).img $(uname -r) 生成initrd
8、vim /boot/grub/grub.conf 新建/grub.conf文件
8、rpm -qf /etc/init/rcS.conf rpm -qf /etc/rc.d/rc.sysinit 查询这两个文件来至哪个包
9、将这个压缩包复制到/app目录下,并解压
10、复制这两个文件到相应父目录下
11、退出救援模式,重启系统
12、完成修复,系统正常启动
综上所述,我们可以了解到救援模式是维护Linux的有力武器,以上述几个例子讲解了它的应用方法,希望能够给大家一点启示,可以运用救援模式解决Linux系统启动的故障,但前提是我们必须充分理解Linux的引导过程,才能够对故障进行有效的判断和处理。