第一步:POST(Power On Test) 

BIOS (Basic Imput & Output System) :基本输入输输出系统,是固化在ROM中的一个程序。在系统启动过程中,主要完成如下两个功能。

1.POST,系统通电后,CPU会将BIOS程序加载到内存中运行,BIOS此时会执行系统完整性检查,检查主要硬件,如CPU、DMA、 等是否正常,如过发现严重错误,启动过程就此终止,如果关键设备检查通过,则会执行更完整的硬件检查,包括Keyboard,Harddrive 等等。一切正常,则会进入下阶段。

2.根据BIOS中设置的启动顺序来查找用于启动系统的驱动器,可以是硬盘,光盘,U盘等。以硬盘为例,查找到可启动硬盘后,BIOS会读取硬盘的第一个启动扇区(BootSector)(0磁道,0扇区),该扇区大小只有512字节,该扇区中包含主引导记录MBR(Master Boot Record),至此BIOS已经完成了其自身使命,接下来交由MBR来引导系统。


第二步:BootLoader, Bootloader 位于MBR的前446字节,随后的64字节用于存储硬盘分区表,末尾2字节用于标示MBR的有效性。

Bootloader 功能:提供一个菜单,允许用户选择要启动的系统或不同的版本,把用户选择的内核加载到内存中的特定空间中,解压,展开后,将控制权交给内核

由于存储bootloader的空间有限,只有446字节,所以没有办法将bootload所有程序(会包含很多驱动文件)全部放在MBR头446字节中。因此,bootloader需要分阶段加载,于是就有了Grub Stage 1、Grub stage 1.5(衔接Grub Stage 1 和Grub Stage 2)、Grub Stage 2 (存放在硬盘分区上)。

查看/boot/grub 目录下的文件,可发现有stag1,stage1.5,stage 2 相关文件,其中*.stage1_5 多和文件系统相关的文件,如e2fs,jfs,等等

Linux学习笔记之 Linux系统启动流程_Linux 系统启动流程

Grub Stage 1 数据存储于硬盘第一个扇区的头446字节中。

Grub Stage 1.5 相关数据存放MBR最后的32K字节中,这段空间被称为MBR GAP,Stage 1.5 包含文件系统的驱动,一旦Stage 1.5加载了,grub 就可以读取/boot/grub/grub.conf 配置文件,其中包含kernel 和initrd(initial ramdisk) 文件路径。

Grub Stage 2: 位于磁盘分区/boot/grub下 (系统启动之初,是无法识别文件系统的,所以需要Stage 1.5 来衔接Stage 1 和 Stage 2)


启动时,在看到如下界面时候,按e可以进到Groub的选择菜单界面,可以选择你想要使用的内核(如果有安装多内核的话)

默认启动的内核是在/etc/grub/grub.conf 定义的

Linux学习笔记之 Linux系统启动流程_Linux 系统启动流程_02

此时,可移动光标,选择想要启动的内核,接下来就会进入内核的加载阶段

  Linux学习笔记之 Linux系统启动流程_Linux 系统启动流程_03

 Grub 配置文件介绍:(/etc/grub.conf)

#boot=/dev/sda
default=0    #默认启动的内核 ,从0开始编号
timeout=5    #菜单显示的超时时间
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz   #Grub启动的背景图
hiddenmenu    #隐藏菜单;注释掉此行后,Grub引导时,将直接进入菜单选项页面
title CentOS 6 (2.6.32-504.el6.x86_64)    #启动时,显示的系统的名称
        root (hd0,0)    #指明引导分区路径
        kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=/dev/mapper/vg_host1-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_host1/lv_root rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_NO_DM  KEYBOARDTYPE=pc KEYTABLE=us rd_LVM_LV=vg_host1/lv_swap rhgb quiet        #指定内核位置,已经相关配置和选项
        initrd /initramfs-2.6.32-504.el6.x86_64.img    #指明ramdisk的路径

                                            

第三步:内核(Kernel)加载

类似于Grub,内核加载也是分阶段进行的,Kernel 文件是以压缩的镜像文件格式存放的,它是一个可执行的bzImage 文件。


内核加载并初始化的过程:

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

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

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

运行用户空间的第一个应用程序:/sbin/init


initrd (initial ramdisk),

内核为了装载系统,需要众多模块和驱动,但是为了保证kernel体积不至于过大,所以内核需要ramdisk 来辅助加载一些驱动。

ramdisk 也是以压缩的镜像文件格式存放的,其路径在/boot 目录下。

 

接下来解压ramdisk文件看看其内容:

[root@S2 initrd]# gunzip initramfs-2.6.32-504.el6.x86_64.gz 

Linux学习笔记之 Linux系统启动流程_Linux 系统启动流程_04

可见其包含有 bin ,etc, init...等等,目录结构和真正的根 (/)目录类似;ramdisk 其实就是一个临时的小的虚拟的根文件系统,它用在Kernel装载真正的根之前,提供一些必要的驱动程序和模块


下图就是ramdisk 文件解压后的文件结构:

Linux学习笔记之 Linux系统启动流程_Linux 系统启动流程_05


第四步: init进程完成各种系统初始化工作

内核加载完成后,启动系统上第一个进程init ,它是系统上所有其它进程的父进程,它首先会调用/etc/rc.d/rc.sysinit 做系统初始化,接着它会读取/etc/inittab文件中的运行级别,来执行相应级别需要运行的服务脚本,启动该启动的服务。过程如下:

1.执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本配置,以读写方式重新挂载根文件系统,及其它文件系统

2.执行/etc/rc.d/rc 脚本,其定义了启动服务的顺序是先K(Kill),再S(Start),即先停止,再启动服务,具体每个运行级别的服务状态是保存在/etc/rc.d/rc*.c (*取值从0到6) 目录下,所有文件均是指向/etc/init.d 相应文件的符号链接; /etc/init.d,rc.sysinit通过读取/etc/inittab 文件来确定运行级别,然后去执行对应级别下(/etc/rc.d/rc*.d)的文件

/etc/init.d-> /etc/rc.d/init.d

/etc/rc ->/etc/rc.d/rc

/etc/rc*.d ->/etc/rc.d/rc*.d

/etc/rc.local-> /etc/rc.d/rc.local

/etc/rc.sysinit-> /etc/rc.d/rc.sysinit

3.  执行用户自定义的开机需要运行的命令(/etc/rc.d/rc.local),任何想要开机运行的命令都可以放在rc.local里面,开机会自动云心

4.  启动终端或X-Window ,打印登录提示符,等待用户登录


参考文档有:

http://blog.chinaunix.net/uid-23069658-id-3142047.html