centos(linux)启动流程
CentOS系统启动流程——基础知识
Linux系统的组成部分:
除去硬件部分linux系统由,内核+根文件系统组成。内核启动后不是在执行内核代码,就是在执行根文件系统下某个路径中的应用程序的代码(用户代码)。
内核主要功能:
简述
进程管理、内存管理、网络管理、文件系统、驱动程序、安全功能,这些功能就是通过系统调用输出的。
进程管理:
如一个父进程可以fork一个子进程,在必要时还可以将自己的数据复制给子进程一份。在子进程完成任务后还可以将其收回。
内存管理:
如c语言编程是可以使用命令malloc函数申请一段内存,使用完成后通过free来释放内存
文件系统:
如打开,读取,编辑一个文件都是通过系统调用实现的。
Glibc:
现在程序员在写程序的时候虽然需要发起系统调用,但是有些时候在编程时不是通过发起系统调用完成的,而是,调用把系统调用二次封装的离用户更近的库文件实现的。在linux叫做glibc。Glibc是用户空间的内容了,如/usr/lib下的文件。
整个操作系统最核心的是内核、用户空间的应用程序以及必要库文件,其他的都是非必要。如man命令提供的帮助文档。
Lib(库):
库是函数的集合,一个功能模块,lib有其调用接口。通过函数名调用lib文件。库文件也是一个二进制文件,但是他不能独立运行,只能被调用。
过程调用:
procedure,没有返回值的函数
函数调用:
function,有返回值的函数
头文件:不同函数可接受的参数数量和类型不同,所以说每一个库中有多少个函数,每个函数可接受多少参数,以及每个参数类型都应该有一个文件对其加以描述,这个文件就是头文件。
内核设计流派:
单内核设计:如,Linux
把所有功能集成于同一个程序;每个功能都是在此程序中通过线程实现。这就是linux内核线程。一般来讲效率高,但是可能任何一个程序出现问题会影响整个系统
微内核设计:如,Windows, Solaris
每种功能使用一个单独子系统实现;一般来讲效率比单内核设计低,但是一个子系统出现问题不会影响整个系统。
Linux内核特点:
微内核设计思想比单内核更前卫,但是linux也借鉴了微内核有点,在内核内部支持模块化。
支持模块化:
linux内核支持将每个功能设计为一个独立的功能模块。格式为*.ko。
支持模块的动态装载和卸载。
动态装卸载的优点:(小、维护)
由于动态装卸载的存在,我们可以仅保留内核最基本和核心的功能,当需要某模块提供的功能时,只需要临时将其装载进内核。这样内核体系就变得非常小了。
我们知道硬件的驱动程序一般都是由内核提供的,如果内核模块不支持模块化的,得来的结果是:任何一个硬件驱动程序想要被使用,必须提前将其编写整合进内核。如果作为一个内核维护者,在没有充分检验情况下将别人开发的驱动整合进内核,万一有,此驱动带有恶意代码可能造成很大危害(例如对方植入病毒等)。造成内核崩溃,操作系统关闭等。而有了模块化后,任何一个厂商都可自行开发模块,作为用户,我们可以自行选择使用那些模块。维护工作也由厂商自己负责,以保证自己模块的安全性。这也是的linux能随时使用更多的硬件设备了
内核组成部分:
核心文件:
/boot/vmlinuz-VERSION-release 。可以看到内核文件很小,是因为它将很多功能做成了模块
模块文件:
/lib/modules/VERSION-release 。模块文件需要和内核版本严格匹配的。模块文件名就是核心文件的后缀名。*.ko文件就是内核模块
Ramdisk:
Init文件在centos5和6上不同:
Centos5使用的是initrd,即init ram disk
CentOS 5: /boot/initrd-VERSION-release.img ,基于内存的磁盘。
Centos6使用的是init ram file-system
CentOS 6: /boot/initramfs-VERSION-release.img ,基于内存的文件系统。
Ramdisk生成工具
Ramdisk是在安装系统时由工具自动生成的
Centos5使用的是initrd,由mkinitrd
Centos6使用的是initramfs,由dracut
问题二:为什么centos5到6从ramdisk 变成ramfs
这要从,“内核中的特性之一:使用缓冲(写)和缓存(读)来加速对磁盘上的文件访问;”说起centos5中使用的是ramdisk是将内存当做磁盘使用,在linux中cpu 认为磁盘的访问速度太慢,为了加速磁盘访问,会将磁盘内容加载至内存,这样会造成这个“磁盘”会再次被加载到内存一次当做缓冲和缓存。两次缓存,使得资源访问变慢。而ramfs是将内存当做了文件系统。文件系统自己就可以管理自己的缓存和缓冲,避免了两次加载。
问题三:内核如何挂载根
除去核心文件和模块文件还有第三个文件它是非必要的,但是在很多场景中被用到了他就是ramdisk。例如linux开机后加载内核,由内核去加载根文件系统,但是内核中没有根文件系统驱动(都放在/lib/modules下)。/lib在根文件系统上。这就没法去加载硬件驱动。解决此问题有两种方法:
1、直接将驱动编译进内核,但是驱动有千万种,都将他们编译进内核,会使内核变得太大。这样显然不合适
2、借助于外在的辅助机制。 将所有驱动硬盘的必要工具全部做成一个文件系统,这个文件系统称为虚拟文件系统。这个根文件系统仅仅包含了驱动硬盘的驱动和文件系统。在开机时此文件系统跟随内核一起加载至内存。内核先去加载虚拟文件系统,从虚拟文件系统加载到驱动磁盘的驱动
问题四:这个虚拟根文件系统中存放的是哪一种驱动呢?是全部的驱动?还是只针对于本机硬盘设备的驱动?
存放的是只适用于本机磁盘类型的驱动。所以虚拟根文件系统不是提前制作好的,而是在安装操作系统时,在安装最后一步自动生成的适用于自己的电脑的磁盘的驱动。
这个虚拟文件系统是一个本地回环设备文件,并且该文件在系统启动时会自动加载到内存。在内存中把这个文件当做磁盘使用,从而使得内核能加载到临时根文件系统,并装载临时根文件系统中的驱动。随后进行根切换。将临时根切换为真正根。
CentOS 系统启动流程:
概述:加电自检,通过BIOS设定的启动顺序,将第一个含有bootloader的设备中的内核加载至内存。随后内核在内存中完成初始化(加载硬件驱动程序(有可能借助ramdisk),只读格式挂载跟文件系统,并运行第一个用户空间程序/sbin/init)。
POST:powered self-test 加电自检;
在按下开机电源后,给CMOS通电,先去通过BIOS读取CMOS中存储的当前系统的硬件配置和用户的参数设定,根据BIOS的设定去检测硬件设备(cpu、memory、disk)是否存在,状态是否正常,之后进行硬件设备的初始化。
补充:在上述操作后,会有一个提示:例如Windows中按下enter进入bios设定界面。Linux如下图按“F2”进入bios。随后看到bios界面
BOOT Sequence:系统的引导加载次序
在bios中有个BOOT Sequence(见上图的boot菜单),根据BIOS设定的次序去逐一查找含有boot loader(引导加载器,是一个程序)的设备,直到找到第一个可启动设备。第一个有引导程序的设备即为本次启动用到设备;如果我们不按“F2”进入bios更改启动选项的话,会使用boot中之前已经设置好的。
MBR: master boot record
位于硬盘上的0磁道的0分区共512字节,由以下三部分组成
前446字节: bootloader,一般是在安装OS时,默认安装。也可以手动安装
64: fat(磁盘分区表)
最后2字节: 55AA,用来标记boot loader是否有效
bootloader:
每一种操作系统都应该有自己的加载器,bootloader主要功能是:找到操作系统所在的磁盘分区,将内核加载至内存中,并且将控制权转交给内核。
功能:提供一个菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核;
Windows中的bootloader是 ntloader
Linux中的bootloader有两种
LILO:LInux LOader,古老,常见于手机中
GRUB: GRand Uniform Bootloader
GRUB 0.X: GRUB Legacy 在centos6中使用的是0.9版本的grub。
GRUB 1.x: GRUB2,grub 二代和一代完全不同是完全重写的centos7使用的是grub2
GRUB: grup有三个阶段
Stage1:运行boot loader主程序,这个程序只能被安装在MBR中。因为MBR空间太小,因此仅安装boot loader的最小主程序,并没有安装配置文件。只是查找位于磁盘上的第1.5阶段
Stage1_5:在MBR随后的扇区存放,重要用于与stage2所在分区的文件进行交互。系统所使用的文件系统类型,在安装完操作系统后就已经确认为某一种了。Grup的1.5阶段就是将上图的某一个1_5与当前文件系统匹配,安装在了MBR随后的扇区上。通过1.5阶段去访问第2阶段分区的驱动,加载并访问第2阶段
Stage2:通过boot loader加载所有的配置文件和相关环境参数,这些文件和参数放在磁盘的/boot目录下。
Kernel:
通过bootloader 加载内核后,内核在内存中解压,加载。探测可识别到的所有硬件设备,加载硬件驱动程序(有驱动的适用驱动去访问硬件,没有的适用基本驱动去访问,如果基本驱动无法访问,则该设备无法被加载),只读方式挂载根文件系统,并启动init。
自身初始化:
1. 探测可识别到的所有硬件设备;
2. 加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)
3. 以只读方式挂载根文件系统;
任何一个程序中都有不确定因素,内核第一次加载根文件系统后,并不确定自己的行为是否妥当的,只读方式,是为了防止内核有BUG的情况下删除根文件系统等破坏性操作
4. 运行用户空间的第一个应用程序:/sbin/init
init程序的类型:
SysV: init, CentOS 5
配置文件:/etc/inittab
Upstart: centos6
在centos6上又被重命名为init,所有 CentOS 6还可以使用service启动管理服务。
配置文件:/etc/inittab(该文件在centos6上几乎被废弃),主要使用 /etc/init/*.conf
Centos6使用UPstart的原因
Sysv的init在完成系统初始化时,都是借助于脚本实现,是串行运行的。脚本是一组命令的集合,整个初始化过程由上往下执行,一直在创建进程和销毁进程,而各个服务之间有的还有以来关系(如A依赖于B只有在B完全启动后A才能启动),处理速度慢。这就是为什么centos5启动慢的原因。Upstart 是由ubantu研发的,他是接近于并行运行的。当出现依赖关系是A无需等待B完全启动(提供一种基于总线的进程间互相通信,B一初始化就可以通知A,A可以启动了)centos6启动速度比centos大大加快。
Systemd:systemd, CentOS 7
仿照mac的初始化启动流程,不通过脚本的方式启动服务,而是由systemd自己本身启动服务,只有在服务第一次被使用的时候,该服务才被启动。这使得开机可以在秒级别启动
配置文件:
/usr/lib/systemd/system/和/etc/systemd/system/目录下
系统初始化流程总结(前半段):
POST --> BootSequence (BIOS) --> Bootloader(位于MBR,三阶段) --> kernel-->[ramdisk](内核借助ramdisk挂载临时根,通过临时根去加载硬件驱动,然后切换临时根为真正根) --> rootfs(只读方式挂载真正根) --> init
/sbin/init
CentOS 5:
运行级别:
为了系统的运行或维护等应用目的而设定;
0-6:7个级别
0:关机
1:单用户模式(默认root用户, 无须输入密码,即可登录), single, 维护模式;
2: 多用户模式,会启动网络功能,但不会启动NFS(网络文件系统);维护模式;
3:多用户模式,正常模式;文本界面;
4:预留级别;可同3级别;
5:多用户模式,正常模式;图形界面;
6:重启
默认运行级别:
Linux默认运行级别应该为3或5。
切换级别:
init #
查看级别:
runlevel :查看系统当前和上一次运行级别
输出两个字段:第一个代表上一次运行的级别,第二个为本次运行级别。下图情况N是null的意思代表系统启动后没有切换过级别,所以就和本次运行的级别一样其实也是3。3代表系统运行级别为3级别。who -r :last=3代表上次运行级别为3
配置文件:/etc/inittab
配置文件/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:系统软件运行环境的配置比脚本。在设置好默认运行级别后,装载此脚本完成系统配置。
例如:
根据配置文件中的设定来设定主机
激活selinux和udev
激活swap设备
设置时钟
激活LVM、raid设备
检测根文件系统,实现以读写方式重新挂载等
例如:
id:3:initdefault: 设定默认运行级别为3
系统环境初始化
si::sysinit:/etc/rc.d/rc.sysinit:设定系统初始化方式,此处一般为指/etc/rc.d/rc.sysinit(系统初始化脚本);
运行指定级别下的脚本
10:0:wait:/etc/rc.d/rc 0
11:1:wait:/etc/rc.d/rc 1
…………
16:6:wait:/etc/rc.d/rc 6
每一行后都有一个参数0~6,由于一开始设定“id:3:initdefault:”意味着去启动或关闭/etc/rc.d/rc3.d/目录下的服务脚本所控制服务;etc/rc.d/rc3.d/目录下的服务脚本,都是以S或者K开头的。K代表关闭服务。S代表开启服务
K##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为依赖到别的服务;
S##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为被依赖到的服务;
这些/etc/rc.d/rc#.d/下的S或者K开头的文件其实是/etc/rc.d/init.d/下文件的链接文件,链接文件保持/etc/rc.d/init.d下文件名不变只是在其前边添加K##或者S##
chkconfig命令
/etc/rc.d/rc#.d/下文件被启动还是关闭由其开头的S或者K决定。配置其实在哪个级别上开启或者关闭的是由chkconfig命令决定的
查看服务在所有级别的启动或关闭设定情形:
chkconfig [--list] [name]
更改指定服务在某级别下的启停状态
例如更改NetworManager在3级别下由on改为off状态
Chkconfig --level 3 NetworManager off
可以看到/etc/rc.d/rc3.d下NetworkManager被改成了以K开头的了
补充:K84NetworkManager中优先级84是怎么来的呢?
这个信息是在每个服务的脚本中定义的。查看/etc/rc.d/rc3.d/NetworkManager脚本。
Centos5 sysv格式:
第一个地段:代表刚添加完服务脚本在此目录,并受到chkconfig控制时默认在那些级别下将此服务设置为S,“-”代表所有级别都不为S,即刚刚把服务脚本添加到目录,使用chkconfig处理时,默认在0~6级别都添加一个K开头的链接文件;
第二个字段:23代表启动时的优先级。
第三个地段:84位关闭时的优先级。
Centos5一刀切的设置启动方式,centos6有更高级方式如下图
如何让手动安装的软件要像系统服务那样自启动
添加:手动安装的软件要想像系统服务那样自启动需要手动编写Sysv脚本放在/etc/rc.d/init.d下 SysV的服务脚本放置于/etc/rc.d/init.d (/etc/init.d)
使用chkconfig创建rc脚本
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文件中;
启动六个虚拟终端
tty1:2345:respawn: /sbin/mingetty tty1
tty2:2345:respawn: /sbin/mingetty tty2
...
tty6:2345:respawn: /sbin/mingetty tty6
只在2345级别启动原因:因为1级别不需要用户登录是单用户模式,6级别为重启
respawn:当用户登出后,立即重启/usr/sbin/mingetty中的某一虚拟终端
注意:mingetty会调用login程序,login程序给用户提供一个登录界面,并验证账号密码信息
补充:
/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) 清理操作; 总结:/sbin/init --> (/etc/inittab) --> 设置默认运行级别 --> 运行系统初始脚本、完成系统初始化 --> 关闭对应下需要关闭的服务,启动需要启动服务 --> 设置登录终端
全部总结--CentOS 6启动流程:
POST --> Boot Sequence(BIOS) --> Boot Loader (MBR) --> Kernel(ramdisk) --> rootfs --> switchroot --> /sbin/init -->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别 --> 系统初始化脚本 --> 关闭或启动对应级别下的服务 --> 启动终端
posted on 2020-08-25 08:11 HowOldAreYou 阅读(1221) 评论(0) 编辑 收藏 举报