运行中的系统分为两层:
用户空间:运行应用程序(进程或线程)
内核空间:运行内核代码,通常为特权级操作(系统调用)
系统在启动是也会分成两个层次进行。
----------------------------------------------------------------------------------------
内核初始化流程:
POST加电自检-->bootsquence(BIOS)-->BootLoader(MBR) -->kernel(ramdisk)-->rootfs(readonly)-->/sbin/init(/etc/inittab)
POST加电自检:主要检测主机上的设备是否存在问题。
bootsquence(BIOS):按次序查找各引导设备,第一个有引导程序的设备即为本次启动要用的设备。
BootLoader(MBR):即NTloader,LILO,GRUB等引导加载器程序,它存放在硬盘的MBR区域,也就是磁盘的0扇区的前512bytes,它提供一个菜单,允许用户选择要启动的系统或用户选定的内核装载到RAM中的特定空间中,解压、展开,而后把系统控制权移交给内核。而在linux系统中bootloader不是加载内核的而是加载GRUB第二阶段,而第二阶段在磁盘上,所有这个GRUB第二阶段就不受MBR 512byte的限制,而能实现更多更强大的功能,然后再有GRUB第二阶段再来加载内核。其实在GRUB第一阶段和第二阶段之间还有一个1.5阶段,是负责连接第一阶段与第二阶段的。
kernel(ramdisk):提供的功能有进程管理、内存管理、网络协议栈、文件系统、驱动程序、安全功能,而内核本身是不具备这些能力的,这些功能都是由加载在内核上的各种模块文件提供的。系统启动前内核首先自身初始化,探测所有设备,驱动程序初始化可能会借组于randisk(由内存虚拟成的磁盘)加载驱动。内核启动之前是不能识别根目录的,所以也不能识别/boot,只有遵循FHS目录结构的才能被当做根分区,并且还要拥有init程序,这是最重要的,所以这里可能会借用到randisk来充当内核与设备之间沟通的桥梁。
内核组成部分:
核心文件:/boot/vmlinuz-VERSION-release
模块文件:/lib/modules/KERNELVERSION
内核运行起来就是需要去装载根文件系统,要想装载根就得先装载磁盘驱动程序,而磁盘驱动程序又在根文件系统的模块上,于是就产生了临时根(ramdisk)这个概念,这是内存中的一段空间当做磁盘使用,临时根能够根据用户的硬盘设备,自动加载相应的设备驱动,从而让内核找到真正的根文件系统,找到磁盘上的根文件系统之后虚拟临时根自动将根下的文件移到真正的根下。
rootfs(readonly) :为了防止内核有BUG或操作问题将根文件系统损坏,所以挂载根文件系统是以只读方式进行的。
/sbin/init(/etc/inittab):启动第一个用户进程init(PID=1)。
用户空间启动流程:
设置默认运行级别 --> 运行系统初始化脚本,完成系统初始化 --> 关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务--> 设置登录终端 --> 启动图形终端(需系统运行在5级别)
以下以CentOS 5:systemV 为例
运行级别:为了系统的运行或维护等目的而设定的机制,共0-6,7个级别:
0:关机, shutdown
1:单用户模式(single user),root用户,无须认证;维护模式;
2、多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式;
3、多用户模式(mutli user),完全功能模式;文本界面;
4、预留级别:目前无特别使用目的,但习惯以同3级别功能使用;
5、多用户模式(multi user), 完全功能模式,图形界面;
6、重启,reboot;
级别切换可使用init #
级别查看runlevel,默认运行级别是35。
init初始化程序配置文件:/etc/inittab
这里每一行定义一种action,以及对应的process。
id:runlevels:action:process
id:一个任务的标识符;
runlevels:在哪些级别启动此任务;可以是一个或多个数字也可以是空。
action:在什么条件下启动此任务;
process:具体任务;
即某个任务:在哪个级别:在什么样条件下 :执行什么样的操作。
action:
wait:等待切换至此任务所在的级别时执行一次;
respawn:一旦此任务终止时,就自动重新启动;
initdefault:设定默认运行级别;此时,process省略;
sysinit:设定系统初始化方式,一般指定为指定/etc/rc.d/rc.sysinit脚本;
系统初始化脚本:/etc/rc.d/rc.sysinit主要有以下功能:
(1)设置主机名;
(2)设置欢迎信息;
(3)激活udev和selinux;
(4)挂载/etc/fstab文件中定义的所有文件系统;
(5)检测根文件系统,并以读写方式重新挂载根文件系统;
(6)设置系统时钟;
(7)根据/etc/sysctl.conf文件来设置内核参数;
(8)激活lvm及软raid设备;
(9)激活swap设备;
(10)加载额外设备的驱动程序;
(11)清理操作;
继续来说说/etc/rc.d这个目录,linux上服务是以脚本方式进行管理的,所有的服务脚本都存放在/etc/init.d目录下,并由/etc/rc.d/rc[0-6],7个文件下的进行统一调用管理在各个级别下的运行状态,这7个文件夹分别对应系统的7个运行级别,并以K*或S*表示对应级别下是否开启对应服务,并且以chkconfig命令来管理/etc/init.d下的脚本在各个级别下的运行状态,即将这些脚本对应级别运行状态存放到相应的/etc/rc.d/rc[0-6]中。
K*:要停止的服务;K##*,优先级,数字越小,越是优先关闭;依赖其他服务的服务先关闭,而后关闭被依赖的服务;
S*:要启动的服务;S##*,优先级,数字越小,越是优先启动;被依赖其他服务的服务先启动,而依赖其他服务的服务后启动;
chkconfig命令:管控/etc/init.d/每个脚本在各级别下的启动或关闭状态;
查服务在各个级别运行状态看:chkconfig--list [name]
添加服务脚本:chkconfig--add name
删除服务脚本:chkconfig--del name
修改指定链接类型:
chkconfig [--level LEVELS] name <on|off|reset>
--level LEVELS:指定要控制的级别;默认为2345;
例如:chkconfig--level 35 network on 就是说系统运行35级别是自动开启network脚本
一般服务脚本头部如下:
正常级别下,最后启动的一个服务S99local没有链接至/etc/init.d下的某脚本,而是链接至了/etc/rc.d/rc.local (/etc/rc.local)脚本;因此,不便或不需写为服务脚本的程序期望能开机自动运行时,直接放置于此脚本文件中即可。
在/etc/inittab文件中有
这表示的其实就是要启动的虚拟终端,而这个登陆提示符和登陆过程并不是由minggetty提供的,而是由minggetty调用login程序提供。这里x:5:respawn:/etc/X11/prefdm-nodaemon 是图形界面的活动,只在系统同运行在5级别下才启动。到这里整个系统初始化就已经完成了。
----------------------------------------------------------------------------------------
在CentOS 6上init程序为upstart,但依然命名为init(/etc/init),其配置文件为/etc/init/*.conf(多个文件)而不再像CentOS 5用一个上的/etc/inttab每行对应一个任务,而更像是每个任务对应一个文件。在CentOS6上的/etc/inittaba只是用来定义默认运行级别
----------------------------------------------------------------------------------------
在CentOS 7 上init则不复存在,并以新的systemd代替,在CentOS 7上面配置文件,已经变为了/usr/lib/systemd/system/*和/usr/systemd/system/*下的一堆文件,并且在CentOS 7上的服务从来没有被访问过,就不会启动而不会像CentOS 5,CentOS 6 开机只要在定义的级别就启动。并且CentOS 7上运行级别的概念也不复存在,但却能完全能够兼容upstart和systemV的脚本机制。