对于计算机来说,不同的操作系统的开机流程大体相似。linux系统中,centos是使用比较广泛的一种,今天我们就主要以centos6为例进行开机流程的简单说明。
先简要介绍完整的开机流程,下面会详细解说:
1.加载BIOS的硬件信息与进行自我检测,并依据设置取得第一个可启动的设备
2.读取并执行第一个启动设备内MBR的boot loader(即是grub,spfdisk等程序)
3.依据boot loader的设置加载kernel(内核),kernel会开始检测硬件与加载驱动程序(可能依赖ramdisk虚拟文件系统)
4.在硬件驱动成功之后,kernel会主动调用init进程,而init会取得run-level信息
5.init执行/etc/rc.d/rc.sysinit文件来准备软件执行的操作环境(如网络,时区等)
6.init执行run-level的各个服务的启动(script方式)
7.init执行/etc/rc.d/rc.local文件
8.init执行终端机模拟程序mingetty来启动login进程,最后就等待用户登录
1.POST加电自检
POST:Power On and SelfTesting,加电后自我检测
通电以后,主机会自动加载BIOS,并通过BIOS去加载CMOS的信息,取得主机硬件的各个参数,然后BIOS进行开机自检,定义出可启动的设备顺序,就开始进行启动设备的读取了(MBR的任务)
CMOS:记录各项硬件参数并嵌入在主板上的存储器,只能读取
BIOS:写入到主板上的一个软件程序,开机时,主机主动执行的第一个程序
CMOS与BIOS都是写入到主板上的特殊的存储器里面,并不在主机内存中。
2.Boot loader:引导加载器
Boot loader安装在启动设备的第一个扇区(sector)中,也就是我们一直提到的MBR(Master Boot Record,主引导分区)。对于不同的操作系统,BIOS通过硬件的INT 13中断功能来读取MBR,而INT13是一种硬件中断,是硬件厂商直接设定好的,所以能够做到对于不同的操作系统,BIOS都能正常读取。
MBR大小为512bytes,其中只有446bytes是bootloader,非常小,对于早期的系统来说,还可以,但对于现在系统来说就有些吃力了。所以对于不同的操作系统来说,设置了多重引导,来增强bootloader的功能。 以centos6为例,它的引导的第一个阶段是在MBR上面,第二阶段就是在磁盘空间上,使得空间大大增加
对于不同的操作系统,使用了不同的bootloader:
Windows:ntloader
Linux:
LILO:LIinux LOader(早期使用)
GRUB:Grand Uniform Bootloader(现在使用)
GRUB 0.X:Grub Legacy
GRUB 1.X:Grub
这样的多重引导使得bootloader的功能也非常强大。
bootloader的功能:
1.提供一个菜单,允许用户选择要启动的系统或不同的内核版本,在这里可以对内核、开机项进行设置
2.把用户选定的内核装载到RAM中的特定空间中,解压、展开,
3.把系统控制权移交给内核;
在一台主机上同时安装Windows与linux操作系统的说明:
每个操作系统默认会安装一套bootloader到自己的文件系统中,在linux系统中,你可以选择将bootloader安装到MBR去,也可以选择不安装。如果选择安装到MBR,那理论上你在MBR与bootsector都会保留一份bootloader程序。至于Windows安装时,会默认主动将MBR与bootloader都安装上一份bootloader。所以,在安装多重操作系统时,你的MBR经常会被不同的操作系统的bootloader覆盖。所以,在安装Windows与linux双系统时,一般要先安装Windows,在安装linux。
3.加载Kernel(内核)
引导完成之后,就要加载指定的内核了,Kernel开始自身的初始化:
1.探测可识别到的所有硬件设备:此时的检测是linux内核以自己的功能重新检测一次硬件,而不一定会使用BIOS检测到的硬件信息。也就是说,内核此时才开始接管BIOS后的工作。硬件检测进行了两次。
2.加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)
3.以只读方式挂载根文件系统;(以防影响到磁盘内的文件系统,只读模式运行)
4.切换根文件系统,虚拟根文件系统(ramdisk)与磁盘上的根文件系统“/”切换
5.运行用户空间的第一个应用程序:/sbin/init
对于不同版本的操作系统,init程序的类型也不太相同:
CentOS 5:SysV init
配置文件:/etc/inittab
CentOS 6:Upstart
配置文件:/etc/inittab
/etc/init/*.conf
CentOS 7:Systemd
配置文件:/usr/lib/systemd/system/, /etc/systemd/system/
ramdisk:虚拟文件系统
由于内核根本不认识SATA盘,所以需要加载SATA盘的驱动程序,否则根本无法挂载根目录。但是SATA的驱动又在/lib/modules/内,无法加载根目录,就读取不到/lib/modules/内的驱动程序。所以要使用虚拟文件系统-initialRAM DISK,一般在/lib/initrd中。通过bootloader加载到内存中,然后会被解压到内存中,仿真成一个根文件系统,通过它来加载启动过程中所需要的内核模块。等载入完成后,会帮助内核重新调用/sbin/init来开始后续的正常启动流程。编译好的ramdisk一般会与内核放置在一起,在/boot目录下,加载kernel的同时也会加载ramdisk。
在/boot目录下的以initramfs开头的文件即是编译好的ramdisk,我们解压一下看看有什么东西
解压后的initramfs-2.6.32-573.el6.x86_64.img,可以看出,其中的文件与一个根文件系统基本类似
4.执行第一个初始化程序:/sbin/init
init的作用:准备软件执行的环境,包括系统的主机名、网络配置、语系处理、文件系统的格式及其他服务的启动等,以上所有的操作都会通过init的配置文件来进行规划,而且,其中还设置了默认的run level(启动执行等级)。
init的简单处理流程:
1.先在配置文件/etc/inittab中取得runlevel即默认执行等级的相关等级(以runlevel=5为例)
2.使用/etc/rc.d/rc.sysinit进行系统初始化
3.由于系统是5级,所以只执行相关的服务,在/etc/rc.d/rc5.d/sysinit中
4.启动mingetty的6个终端机(tty1-tty6)
5.启动开机界面
第一步:执行配置文件,/etc/inittab
在Centos6系统中,在安装的时候就选定了开机方式,所以只显示一行,在Centos5与之前的版本中显示的是多行,不过也只会执行一行。下面介绍配置文件的内容:
每行定义一种action以及与之对应的process
格式:id:runlevels:action:process
id:一个任务的标识符;
runlevels:在哪些级别启动此任务;#,###,也可以为空,表示所有级别;
action:在什么条件下启动此任务;
process:任务;
action:
wait:等待切换至此任务所在的级别时执行一次;
respawn:一旦此任务终止,就自动重新启动之;
initdefault:设定默认运行级别;此时,process省略;
sysinit:设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit脚本;
例如:
id:3:initdefault:
id:5:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
…………
l6:6:wait:/etc/rc.d/rc 6
系统的运行级别:为了系统的运行或维护等目的而设定的机制,共有0-6,7个级别;
0:关机, shutdown
1:单用户模式(single user),root用户,无须认证;维护模式;
2、多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式;
3、多用户模式(mutli user),完全功能模式;文本界面;
4、预留级别:目前无特别使用目的,但习惯以同3级别功能使用;
5、多用户模式(multi user), 完全功能模式,图形界面;
6、重启,reboot
默认级别:3, 5
级别切换:init #
级别查看:
who -r
runlevel
第二步:选定要执行的运行级别,就开始使用/etc/rc.d/rc.sysinit进行系统初始化
1.取得网络环境与主机类型
2.测试与挂载内存设备/proc以及USB设备/sys
3.决定是否启动SElinux
4.启动系统的随机数生成器,进行一些密码加密演算的功能
5.设置终端字体
6.设置显示于启动过程中的欢迎界面
7.设置系统时间(clock)与时区设置:需读入/etc/sysconfig/clock设置
8.接口设备的检测与PnP参数的测试
9.用户自定义模块的加载,在/etc/sysconfig/modules/*.modules中加入的自定义模块,在此刻被加载到系统中
10.加载内核的相关设置,读取/etc/sysctl.conf这个文件的设置,使内核成为我们想要的样子
11.设置主机名与初始化电源管理模块(ACPI)
12.初始化磁盘阵列
13.初始化LVM的文件系统功能
14.以fsck检测磁盘文件系统:会进行filesystem check
15.重新以可读写模式挂载系统磁盘
16.启动系统伪随机数生成器
17.清除启动过程中的临时文件
18.将启动信息加载到/var/log/dmesg文件中
对整个开机流程比较感兴趣的可以查找/var/log/dmesg文件,查找更详细的过程
第三步:启动或关闭/etc/rc.d/rc5.d/目录下的服务脚本所控制服务
我们打开/etc/rc.d/rc5.d目录,可以看到:
K*:要停止的服务;K##*,优先级,数字越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的;
S*:要启动的服务;S##*,优先级,数字越小,越是优先启动;被依赖的服务先启动,而依赖的服务后启动;
/etc/rc.d/rc#(0-6).d/之下的文件基本上就是链接文件,指向在/etc/init.d/*目录下具体的执行程序
我们还可以通过chkconfig命令,管控/etc/init.d/每个服务脚本在各级别下的启动或关闭状态;
用法:
查看:chkconfig --list [name]
添加:chkconfig --add
删除:chkconfig --del name
修改指定的链接类型:
chkconfig [--level LEVELS] name <on|off|reset>
--level LEVELS:指定要控制的级别;默认为2345;
注意:正常级别下,最后启动的一个服务S99local没有链接至/etc/init.d下的某脚本,而是链接至了/etc/rc.d/rc.local(/etc/rc.local)脚本;因此,不便或不需写为服务脚本的程序期望能开机自动运行时,直接放置于此脚本文件中即可。
第四步:mingetty会调用login程序,打开虚拟终端
注意:打开虚拟终端的程序除了mingetty之外,还有诸如getty等;
第五步.打开设定的开机界面(3,为命令行界面。5,为图形化界面)
总结(用户空间的启动流程): /sbin/init (/etc/inittab)
设置默认运行级别 --> 运行系统初始化脚本,完成系统初始化 --> 关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务--> 设置登录终端 [--> 启动终端]
CentOS系统的启动流程就介绍到这里,对于其中的一些内容比如开机引导grub,kernel等没有进行详细介绍,留待下一次进行介绍了。
对于计算机而言,整个开机流程,从硬件到软件,对于Linux、Windows这些操作系统,基本流程都是大体相似的。通过对于开机配置文件的修改,就可以设置我们自己的操作系统了。