Linux开机流程分析与Grub引导程序
开机,对于我们每个人来说,是简单得不能再简单得事,可是,整个开机的过程会经历怎样一个流程呢?
一般来说,linux的开机大致上经历以下的流程:
1. 加载BIOS的硬件信息,进行自检,并依据设定获得第一个启动设备
2. 读取并执行启动设备内的MBR的boot Loader(grub)
3. Bootloader加载kernel,kernel会检测硬件和加载驱动程序。
4. 内核启动init程序
5. 系统初始化:(/etc/init/rcS.conf exec /etc/rc.d/rc.sysinit)
6. Init找到/etc/inittab文件,确定系统默认的运行级别(/etc/init/rcS.conf exec telinit $runlevel)
7. 触发响应的runlevel事件(/etc/init/rc.conf exec /etc/rc.d/rc $runlevel)
8. /etc/rcX.d中的脚本按预先设定的优先级次序启动(实质上就是服务)
9. 最后执行/etc/rc.d/rc.local(自定义的引导启动程序)
10. 加载终端或X-Window接口
MBR和bootLoader
当BIOS自检完成之后会执行MBR内的boot loader。我们知道,MBR一般都装在硬盘的主引导扇区中(0柱面,0磁头,1扇区),总共512个字节,下面给出一个MBR的组成图:
Boot Loader
由上图可知,boot loader在MBR内占了446个字节,它的主要作用就是从文件系统中加载系统的内核到主存储器中去执行。由此可知,boot loader可以引导系统的一个前提就是它能识别操作系统上的文件系统。由于MBR的boot loader只有一份,而硬盘上得操作系统可能有多个,那么,当MBR中的boot loader只能识别一个操作系统时,如果实现多重启动呢?
要实现多重启动,我们还需提前知道的一点是,引导程序并不仅仅只能安装在MBR中,它还能安装在文件系统分区上的super block中。并且,引导程序还可以做到以下两点:
1)直接加载核心到存储器中执行
2)转交控制权给另一个加载程序
这里,也许大家就明白了多重启动是如何实现的。假如我们的系统中有windows和linux这两个操作系统,windows安装在/dev/sda1中,linux安装在/dev/sda2中。它们的superblock中也安装了引导程序。MBR中的引导程序是可以同时识别这两个操作系统的文件系统的GRUB程序。
那么,MBR的grub可以做到以下几点:
1)直接加载/dev/sda2的/boot/vmlinux核心来启动
2)将控制权转交给/dev/sda2的super block中的boot loader来管理
3)将控制权转交给/dev/sda1(windows)的super block中的boot loader来管理
注意:linux可以选择将boot loader安装在MBR或super block中,而windows默认会强制在MBR和super block中都安装boot loader,并且,windows的boot loader预设是不具有控制权转交功能的,这也是为什么我们在装多重系统时,先安装windows,再安装Linux的原因了,因为如果后安装windows,那么它的boot loader会覆盖掉MBR中的boot loader。
重点:boot loader的目的就是要加载kernel。
GRUB引导流程
引导程序的功能非常强大,也涉及到了很多的配置文件。可是,我们看到MBR最多只有512个字节,那么它的设置文件都放置在哪里呢?
其实,引导加载程序常常分为两个阶段来执行:
Stage1:它是引导加载程序的主程序,实质上就是MBR
Stege2:它是引导加载程序的相关设置文件,一般来说,设置文件都放置在/boot下面。
了解/boot下面的文件
在/boot下面放置的就是与启动相关的文件。
vimlinuz:这就是最为重要的内核文件了;
config-2.6.32-71.el6.i686:系统knerl的配置文件,内核编译完成后保存的就是这个文件;
grub:引导程序相关的目录
initramfs-2.6.32-71.el6.i686.img:虚拟文件系统你相关文件,取代了以前的Initrd文件,用于加载一些核心模块。
System.map-2.6.32-71.el6.i686:系统kernel中的变量对应表
Symvers-2.6.32-71.el6.i686.gz:模块符号信息
了解/boot/grub下的grub.conf文件
该文件就是引导程序在加载内核前需要查找的配置文件,该配置文件大致格式如下:
Default=0
Timeout=5
Splashimage=(hd0,0)/grub/splash.xpm.gz
Hiddenmenu
Title CenOS(vimlinuz-2.6.32-71.el6.i686)
Kernel/vimlinuz-2.6.32-71.el6.i686roroot=UUID=be033dfc-63e2-491e-ae9e-2c884c6fead5
Initrd initramfs-2.6.32-71.el6.i686.img
Default表示开机默认加载的kernel,0表示第一个title,1表示第二个,依次类推
Timeou=5表示如果设置了hiddenmenu,则等待5秒,如果没有按下任意键再加载默认的kernel
Splashimage是选项中选定的背景图片
TITLE下面就是主要的加载的核心已经镜像文件。
注意:当我们grub错误而导致无法正常开机时,如开机后进入的时grubshell界面,我们可以手动加载核心。步骤如下:
首先找到/boot/grub的位置:
find /boot/grub
假设是(hd0,0)
然后指定/boot区
Root (hd0,0)
接着加载驱动
Kernel/vimlinuz-2.6.32-71.el6.i686roroot=UUID=be033dfc-63e2-491e-ae9e-2c884c6fead5
Initrd initramfs-2.6.32-71.el6.i686.img
最后,启动
Boot
这样,系统就能正常启动了。
GRUB中的硬盘分区表示方法:
GRUB要求设备名都包含在()之中,硬盘有hd来表示,软盘用fd来表示。其次,设备是从0开始编号,分区也是一样,设备和分区中间用’,’隔开。如果没有制定分区,表示MBR
第一个
(hd0) (hd0,0) (hd0,1)……..
第二个
(hd1) (hd1,0) (hd1,1)……..
.
.
.
.