centos(linux)启动流程

CentOS系统启动流程——基础知识

Linux系统的组成部分:

除去硬件部分linux系统由,内核+根文件系统组成。内核启动后不是在执行内核代码,就是在执行根文件系统下某个路径中的应用程序的代码(用户代码)。

内核主要功能:

简述

进程管理、内存管理、网络管理、文件系统、驱动程序、安全功能,这些功能就是通过系统调用输出的。

进程管理:

如一个父进程可以fork一个子进程,在必要时还可以将自己的数据复制给子进程一份。在子进程完成任务后还可以将其收回。

内存管理:

c语言编程是可以使用命令malloc函数申请一段内存,使用完成后通过free来释放内存

文件系统:

如打开,读取,编辑一个文件都是通过系统调用实现的。

Glibc

现在程序员在写程序的时候虽然需要发起系统调用,但是有些时候在编程时不是通过发起系统调用完成的,而是,调用把系统调用二次封装的离用户更近的库文件实现的。在linux叫做glibcGlibc是用户空间的内容了,如/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文件在centos56上不同:

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

问题二:为什么centos56ramdisk 变成ramfs

  这要从,“内核中的特性之一:使用缓冲(写)和缓存(读)来加速对磁盘上的文件访问;”说起centos5中使用的是ramdisk是将内存当做磁盘使用,在linuxcpu 认为磁盘的访问速度太慢,为了加速磁盘访问,会将磁盘内容加载至内存,这样会造成这个“磁盘”会再次被加载到内存一次当做缓冲和缓存。两次缓存,使得资源访问变慢。而ramfs是将内存当做了文件系统。文件系统自己就可以管理自己的缓存和缓冲,避免了两次加载。

问题三:内核如何挂载根

  除去核心文件和模块文件还有第三个文件它是非必要的,但是在很多场景中被用到了他就是ramdisk。例如linux开机后加载内核,由内核去加载根文件系统,但是内核中没有根文件系统驱动(都放在/lib/modules下)。/lib在根文件系统上。这就没法去加载硬件驱动。解决此问题有两种方法: 

1、直接将驱动编译进内核,但是驱动有千万种,都将他们编译进内核,会使内核变得太大。这样显然不合适

2、借助于外在的辅助机制。 将所有驱动硬盘的必要工具全部做成一个文件系统,这个文件系统称为虚拟文件系统。这个根文件系统仅仅包含了驱动硬盘的驱动和文件系统。在开机时此文件系统跟随内核一起加载至内存。内核先去加载虚拟文件系统,从虚拟文件系统加载到驱动磁盘的驱动 

问题四:这个虚拟根文件系统中存放的是哪一种驱动呢?是全部的驱动?还是只针对于本机硬盘设备的驱动?

  存放的是只适用于本机磁盘类型的驱动。所以虚拟根文件系统不是提前制作好的,而是在安装操作系统时,在安装最后一步自动生成的适用于自己的电脑的磁盘的驱动。

  这个虚拟文件系统是一个本地回环设备文件,并且该文件在系统启动时会自动加载到内存。在内存中把这个文件当做磁盘使用,从而使得内核能加载到临时根文件系统,并装载临时根文件系统中的驱动。随后进行根切换。将临时根切换为真正根。

CentOS 系统启动流程:

概述:加电自检,通过BIOS设定的启动顺序,将第一个含有bootloader的设备中的内核加载至内存。随后内核在内存中完成初始化(加载硬件驱动程序(有可能借助ramdisk),只读格式挂载跟文件系统,并运行第一个用户空间程序/sbin/init)。

POSTpowered self-test  加电自检;

在按下开机电源后,给CMOS通电,先去通过BIOS读取CMOS中存储的当前系统的硬件配置和用户的参数设定,根据BIOS的设定去检测硬件设备(cpumemorydisk)是否存在,状态是否正常,之后进行硬件设备的初始化。

补充:在上述操作后,会有一个提示:例如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中的bootloaderntloader

Linux中的bootloader有两种

LILOLInux LOader,古老,常见于手机中

GRUB: GRand Uniform Bootloader                                                                                                                                                                                                                   

  GRUB 0.X: GRUB Legacy  centos6中使用的是0.9版本的grub

   

  GRUB 1.x: GRUB2grub 二代和一代完全不同是完全重写的centos7使用的是grub2 

  

GRUB: grup有三个阶段

Stage1:运行boot loader主程序,这个程序只能被安装在MBR中。因为MBR空间太小,因此仅安装boot loader的最小主程序,并没有安装配置文件。只是查找位于磁盘上的第1.5阶段

Stage1_5:在MBR随后的扇区存放,重要用于与stage2所在分区的文件进行交互。系统所使用的文件系统类型,在安装完操作系统后就已经确认为某一种了。Grup1.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的原因

  Sysvinit在完成系统初始化时,都是借助于脚本实现,是串行运行的。脚本是一组命令的集合,整个初始化过程由上往下执行,一直在创建进程和销毁进程,而各个服务之间有的还有以来关系(如A依赖于B只有在B完全启动后A才能启动),处理速度慢。这就是为什么centos5启动慢的原因。Upstart 是由ubantu研发的,他是接近于并行运行的。当出现依赖关系是A无需等待B完全启动(提供一种基于总线的进程间互相通信,B一初始化就可以通知AA可以启动了)centos6启动速度比centos大大加快。

Systemdsystemd, 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-67个级别 

0:关机                                                     

1:单用户模式(默认root用户, 无须输入密码,即可登录), single, 维护模式;            

2: 多用户模式,会启动网络功能,但不会启动NFS(网络文件系统);维护模式;     

3:多用户模式,正常模式;文本界面;                          

4:预留级别;可同3级别;                                     

5:多用户模式,正常模式;图形界面; 

6:重启                                                                                                                 

默认运行级别:

Linux默认运行级别应该为35

切换级别:

init #                                                                                                                                                              

查看级别:

runlevel :查看系统当前和上一次运行级别  

输出两个字段:第一个代表上一次运行的级别,第二个为本次运行级别。下图情况Nnull的意思代表系统启动后没有切换过级别,所以就和本次运行的级别一样其实也33代表系统运行级别为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:系统软件运行环境的配置比脚本。在设置好默认运行级别后,装载此脚本完成系统配置。

例如:

  根据配置文件中的设定来设定主机

  激活selinuxudev

  激活swap设备

  设置时钟

  激活LVMraid设备

  检测根文件系统,实现以读写方式重新挂载等

例如:

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]    

更改指定服务在某级别下的启停状态

例如更改NetworManager3级别下由on改为off状态

Chkconfig --level 3 NetworManager off

可以看到/etc/rc.d/rc3.dNetworkManager被改成了以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) 激活udevselinux;                                                                                                                                                                                                                           

(4) 挂载/etc/fstab文件中定义的文件系统;这就是以为什么该文件中定义设备会被开机自动挂载                      

(5) 检测根文件系统,并以读写方式重新挂载根文件系统; 

(6) 设置系统时钟;                                                                                                           

(7) 激活swap设备;                                            

(8) 根据/etc/sysctl.conf文件设置内核参数; 

(9) 激活lvmsoftware 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) --> 设定默认运行级别 --> 系统初始化脚本 --> 关闭或启动对应级别下的服务 --> 启动终端 

 

 

                                                                                                                                                                  

原文地址:https://www.cnblogs.com/wxxjianchi/p/9879502.html