linux操作系统启动流程解析:
boot loader:引导加载器
在linux系统上有两种:
Lilo
Grub:GRand Uniform Bootloader
在centos6(包含)之前:Grub0.x,也称为GRUB legacy
在centos7上:Grub1.x,也称为GRUB2
功能:提供一个可视化的菜单,允许用户选择要启动的系统或者不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核;
kernel:
自身初始化:
探测可识别到的所有硬件设备;
加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)
以只读方式挂载根文件系统;
运行用户空间的第一个应用程序:/sbin/init
init程序的类型:
SysV: init, CentOS 5
配置文件:/etc/inittab
Upstart: init, CentOS 6
配置文件:/etc/inittab, /etc/init/*.conf
Systemd:systemd, CentOS 7
配置文件:/usr/lib/systemd/system, /etc/systemd/system
ramdisk:
内核中的特性之一:使用缓冲和缓存来回事对磁盘上的文件访问;
ramdisk是一个微小的根文件系统,内部存放了磁盘的驱动设备,在用户安装操作系统之后,会自动生成或者借助于工具生成磁盘类型的驱动。是存放在内存中的,在加载内核的时候,会自动搜索是否存在,若存在,则加载入内存。是一个辅助的程序,并不一定必须存在。在ramdisk上存在bin、sbin等个目录,也存在init初始化程序。
CentOS 5: /boot/initrd-VERSION-release.img,模拟为磁盘设备
CentOS 6: /boot/initramfs-VERSION-release.img,模拟为文件系统使用
根切换,从这个微小的根文件系统切换为真正要使用的根文件系统。
ramdisk --> ramfs
CentOS 5: initrd, 工具程序:mkinitrd
CentOS 6: initramfs, 工具程序:mkinitrd, dracut
运行级别:
/sbin/init是在系统初始化的时候完成的。设置运行级别是为了系统的维护或者运行等应用目的而进行的设定。
运行级别共有7个级别:
0-6:7个级别
0:关机
1:单用户模式(root, 无须登录), single, 维护模式;
2: 多用户模式,会启动网络功能,但不会启动NFS;维护模式;
3:多用户模式,正常模式;文本界面;
4:预留级别;可同3级别;
5:多用户模式,正常模式;图形界面;
6:重启
切换系统的运行级别:
init #
查看当前系统的运行级别:
runlevel
who -r
配置文件/etc/inittab:
每一行定义一种action以及与之对应的process
id:runlevel:action:process
action:
wait: 切换至此级别运行一次;
respawn:此process终止,就重新启动之;
initdefault:设定默认运行级别;process省略;
sysinit:设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit;
id:3: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
说明:rc 0 --> 意味着读取/etc/rc.d/rc0.d/
K*: K##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为依赖到别的服务;
S*: S##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为被依赖到的服务;
chkconfig命令:
查看服务在所有级别的启动或关闭设定情形:
chkconfig [--list] [name]
添加:
SysV的服务脚本放置于/etc/rc.d/init.d (/etc/init.d)目录下。
服务脚本的格式:
在服务脚本中必须指定chkconfig: LLLL nn mm;
其中LLLL:表示运行的级别,就是服务在哪些运行级别下进行启动;
其中nn:表示服务在该级别下启动的次序;
其中mm:表示服务在该级别下关闭的次序;
chkconfig --add name
删除:
chkconfig --del name
修改指定的链接类型:
chkconfig [--level levels] name <on|off|reset>
--level LLLL: 指定要设置的级别;省略时表示2345;
注意:正常级别下,最后启动一个服务S99local没有链接至/etc/rc.d/init.d一个服务脚本,而是指向了/etc/rc.d/rc.local脚本;因此,不便或不需写为服务脚本放置于/etc/rc.d/init.d/目录,且又想开机时自动运行的命令,可直接放置于/etc/rc.d/rc.local文件中;
/etc/rc.d/rc.sysinit: 系统初始化脚本
(1) 设置主机名;
(2) 设置欢迎信息;
(3) 激活udev和selinux;
(4) 挂载/etc/fstab文件中定义的文件系统;
(5) 检测根文件系统,并以读写方式重新挂载根文件系统;
(6) 设置系统时钟;
(7) 激活swap设备;
(8) 根据/etc/sysctl.conf文件设置内核参数;
(9) 激活lvm及software raid设备;
(10) 加载额外设备的驱动程序;
(11) 清理操作;
步骤详解:
第一步:post加电自检
POST(PowerOnSelfTest)首先对每一个外围设备进行检查。
第二步:boot sequence
也就是我们常说的BIOS,在加电自检完成之后,系统会按照一定的次序进行引导程序的查找,找到第一个引导程序即执行,不管该引导程序是否可以正常运行。若不能正常运行,也不会进行再次的查找。
第三步:boot loader
boot loader(引导加载器)存在于MBR(主引导记录)中。MBR由512个字节组成,前446个字节为boot loader,后64个字节为分区表相关信息,最后两字节为Magical Number。
通过读取MBR中的boot loader以及分区的相关信息,把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核。在引导完成之后,就会进入kernel的初始化。
第四步:kernel初始化
在kernel初始化的时候,进行的工作主要是识别各种硬件设备,加载硬件的驱动。在识别本地磁盘的时候,可能需要借助于ramdisk,通过ramdisk加载的磁盘驱动,kernel识别本地磁盘。
ramdisk并不是人为制作的,而是在系统启动的时候,会自动生成该文件系统。该文件系统不是必需的。
在识别完各种硬件之后,要进行根文件系统的切换,从ramfs切换到真正我们要使用的rootfs。
在挂载ramfs的时候,以只读方式挂载。在挂载rootfs的时候,以读写方式挂载。
在完成内核初始化之后,就要运行用户空间内的第一个初始化程序,即/sbin/init程序。
第五步:/sbin/init程序
通过运行系统初始化程序,启动一个init进程,读取/etc/inittab以及/etc/init/*.conf等配置文件,设置系统的默认启动级别,运行/etc/rc.d/rc.sysinit初始化脚本,加载/etc/rc.d/rc#.d所有脚本,启动相对应的系统运行级别下的服务。最后运行/etc/rc.d/rc.local脚本,启动终端,并进入认证界面。
注意:在centos5上只读取/etc/inittab文件;在centos6上,读取/etc/inittab以及/etc/init/*.conf文件;在centos7上systemd类型,读取/etc/lib/systemd及/etc/systemd/system。