Linux 系统启动流程
Centos5和6的启动流程
Linux:kernel+rootfs
系统运行起来之后,在某一时刻要么是运行内核代码,要么是执行rootfs上某个路径上的某个程序的用户代码;
kernel:进程管理、内存管理、网络管理、驱动程序、文件系统等、安全功能;
rootfs:用户空间
glibc:编写程序时需要发起系统调用,显然不是直接调用系统调用来实现的,而是通过调用库来实现的;
Linux系统运行只需内核、应用程序以及库就可运行;
库:函数集合(function)
其实调用函数其实就是调用其某一块功能代码来实现某种功能,一般是通过函数的调用接口来调用它,所以为了方便我们会给它起个名称(函数名),这样更利于人类调用使用;为了函数拥有更灵活的功能,所以会给它设置一些参数来丰富其功能,不同的函数能接受的参数和类型不尽相同,所以每一个库有多少个函数,每个函数具有什么样的功能等特性,都会有一个文件来描述这些特性,这个文件就是所谓的头文件,所以在编写程序的时候为了让代码可以识别理解这些库,就会在程序代码首部声明头文件;
库也是二进制程序,但是它和/bin下的二进制程序的是有区别的,那就是库函数没有可执行入口,无法独立执行但是可以被调用执行;
库函数还可以分为是否有返回值:
过程调用(procedure)→无返回值就是调用函数执行来实现某些功能,实现完毕后就结束;
函数调用(function)→有返回值也是调用函数执行来实现某些功能,不过执行完毕后会反馈信息给主程序,供主程序有需要时使用;
程序:大多数程序会依赖配置文件来执行功能;
内核加载完成之后会运行根文件系统,然后运行文件系统上的第一个用户进程init,init程序负责调用某些系统调用或自己有权限的能力来实现对整个用户空间的程序的启动运行、回收等管理操作;
内核设计流派:大多数是使用c语言来实现的,只有一少部分是使用汇编语言来实现的;
单内核设计:Linux(Linux是支持模块化的)
把所有功能集成于同一个程序中,各个功能相依性比较强,有牵一发而动全身的隐患,不过效率会比较好;
微内核设计:windows,Solaris
每种功能使用一个单独的子系统来实现,各个子系统在核心框架下工作;某个子系统出问题之后不会直接导致整个内核崩溃,不过效率会慢一点;
Linux内核特点:
支持模块化:.ko(内核模块);
支持模块的动态装载与卸载;比如各种协议模块,文件系统模块等;
因为支持模块化所以Linux可以只保持最基本的核心功能,使Linux内核可以做的非常小而美;
组成部分:
核心文件:/boot/vmlinuz-VERSION-release
ramdisk
centos5:initrd
生成工具:mkinitrd
/boot/initramfs-VERSION-release.img
centos6/7:initramfs
生成工具:mkinitrd、dracut
/boot/initramfs-VERSION-release.img
模块文件:/lib/modules/&(uname -r)/
在硬盘上存储着内核与根文件系统,系统启动时会加载内核到内存中,然后加载根文件系统,但是能识别文件系统的模块在硬盘的/lib/modules目录中,此时还没有挂在文件系统无法加载模块呀;这就陷入了一个死循环;所以需要一个中间的过渡程序来帮助内核挂载根文件系统→initramfs;
initramfs:包含了内核驱动硬盘和文件系统的最基本的驱动程序的虚拟根文件系统(模拟成文件系统);开机时与内核一起被装载到内存中,当内核要加载根文件系统时先加载这个虚拟的根文件系统为了接下来驱动硬盘和挂载真根文件系统(挂载真文件系统之前会做根切换initramfs→rootfs);
可以知道,initramfs不可能是事先规定好的,否则它就会集成很多模块,变得很大,与直接集成到内核没什么区别了,所以它是在安装完系统之后,根据系统所处的环境自动或者是使用工具生成的;但是initramfs并不是必须的,如果内核可以驱动硬盘和识别文件系统的话就不需要initramfs了;
启动流程:
POST:加电自检;
包括检测CPU、内存、风扇、显示设备等是否存在与能否工作;
ROM:CMOS 芯片
BIOS:Basic Input and Output System 基本输入输出系统;
管理系统上的基本输入输出,设定硬件彼此之间的协作方式
开机时主机激活CPU,接着会传递第一条指令(ROM地址空间的某一特定地址)给CPU,CPU就会去执行此指令来完成自检等操作;
内存:ROM+RAM
内存的编制空间并不是从一开始的编制地址就是RAM空间,而是ROM;接下来的才是RAM空间;
BOOT Sequence:
根据BIOS设置的启动顺序寻找第一个可引导设备的boot loader(位于MBR中),然后开始加载系统;只要是找到了含有boot loader(引导加载器)的设备,哪怕之后不可以成功加载都不会再去寻找下一个;
boot loader:引导加载器,程序
功能:提供一个菜单,允许用户选择要启动的系统或不同的内核版本,然后把用户选定的内核装载到特定的内存空间,解压、展开内核,并把控制权移交给内核;
Windows:ntloader
Linux:
LILO:LInux LOader
GRUB:Grand Uniform Bootloader
GRUB 0.X:GRUB Legacy
GRUB 1.X:GRUB2
MBR:主引导记录
446:boot loader
64:磁盘分区表
2:55AA;魔数,标识boot loader是否可用
GRUB:
bootloader:1st stage 第一阶段 →只是为了寻找第二阶段(中间还有1_5阶段)
MBR之后的一块扇区地址:1_5 stage :帮助GRUB识别(2nd stage所在)分区上的文件系统
在系统安装之后根据磁盘文件系统类型等环境生成的,达成量身定制的目的;
disk:2nd stage
kernel:
自身初始化:
探测可识别到的硬件设备;
加载硬件驱动程序;(有可能会借助于ramdisk加载驱动程序)
以只读方式挂载根文件系统(initrd阶段);(之后会重新以读写方式挂载根文件系统)
运行用户空间的第一个应用程序:/sbin/init(centos 5)
init类型:根据配置文件来完成初始化;
SysV:init→centos 5
配置文件:/etc/inittab
所有的初始化和启动过程都是通过脚本实现的,使用脚本启动会产生很多的创建和销毁进程的过程,消耗CPU,导致启动过程很慢;
Upstart:init → 兼容了SysV ,centos 6
配置文件:/etc/inittab、/etc/init/*.conf
Systemd:systemd→也兼容之前版本的使用方式,centos7
配置文件:/usr/lib/systemd/system/、/etc/systemd/system
可以靠自己本身加载程序,然后提交给内核启动,不需要bash参与,所以不会启动很多进程,也可以说systemd本身就是一个解释器;
ramdisk:
centos 5→initrd:把initrd当做磁盘加载到内存中,因为内核认为磁盘的速度很慢,所以会把initrd中的文件加载到内核的缓冲区中(内核的特性之一就是使用缓冲和缓存来加速对磁盘的访问速度),因为initrd本来就是在内存中,这样就多了一个处理过程从而降低速度;
centos6/7→initramfs:把initramfs当做文件系统加载到内存中,文件系统自身是可以完成缓冲和缓存管理的,所以改善了initrd加载两次的弊端;
系统初始化:
POST→BootSequence(BOIS)→Bootloader(MBR)→kernel(initrd)→rootfs(ro)→init/systemd
/sbin/init:
根据/etc/inittab配置文件完成用户空间的很多功能的初始化过程
Centos 5:
运行级别:为了系统的运行或维护等应用目的而设定的;
想必大家用Windows时都有过某次开机时不是直接进入系统而是跳出来一个黑白界面,上面有各种模式等你选择,如果不选它会在特定秒数之后自动选择默认选项执行;centos的运行级别就类似windows的哪个界面的选项,比如centos的1级别跟Windows的安全模式就很类似(用来当系统出现问题来修复系统的);
0-6:7个运行级别
0:关机
1:单用户模式(维护模式),或称single
使用root权限登录,无需登录→忘记管理员密码时可以用来更改root密码;
2:多用户模式
会启动网络功能,但不会启动网络文件系统,很多功能都不会启动;
3:多用户模式,文本界面
4:多用户模式,预留级别,类似3级别
5:多用户模式,图形界面
6:重启
常用(默认)3/5级别;
Note:不要把默认级别设置为6,可以想象:只要一开机就会重启;
切换级别:
init #
查看级别:
runlevel或who -r
显示内容中最后面的为当前运行级别,往前则为上一次所在级别;
例如 4 3表示当前级别为3,当一次运行级别为4;
N 表示空级别
配置文件:/etc /inittab
每一行定义一种action以及与之对应的process
例如:label:runlevel:action:process
label:标识
runlevel:运行级别
为空时为所有级别
action:按照什么样的模式启动
wait:切换至次级别就运行一次process
respawn:如果此process终止,则自动重新启动
initdefault:设定默认运行级别,可以省略process
id:3:initdefault:
……
sysinit:设定系统初始化方式(设定系统的许多参数,比如:加载驱动程序,设定系统时钟,加载LVM,挂载proc等文件系统等),一般为运行/etc/rc.d/rc.sysinit这个脚本;
si::sysinit:/etc/rc.d/rc.sysinit
process:此运行级别按照特定模式所要执行的操作
当初始化完毕之后就要开始去执行特定级别下所要作的操作了
比如开启某些功能,关闭某些功能;
l3:3:wait:/etc/rc.d/rc 3
表示切换到级别3时执行/etc/rc.d.rc脚本,后面的3为传递给脚本的参数,运行级别到底为哪个实际上就是通过这个参数来指定的;
Note:/etc/rc.d/rc 3→意味着读取/etc/rc.d/rc3.d/目录下的
以K##*开头的脚本文件
被传递stop参数
for srv in /etc/rc.d/rc3.d/K##*
do
$srv stop
done
以S##*开头的脚本文件
被传递start参数
for srv in /etc/rc.d/rc3.d/S##*
do
$srv start
done
S表示要开启的功能,K表示要关闭的功能
后面的##为数字,用来设置启动或关闭的顺序,数字越小越优先,因为各个进程之间是有依赖关系的,某些进程启动是需要特定依赖的进程事先启动完毕才能启动的;如果细心你会发现如果S ##越小对应的K ##越大,因为先启动的一般都是被依赖的,所以要后关闭,反义亦然;
那么这些数字是怎么设置的呢?
vim /etc/rc.d/rc3.d/S08iptables
#!/bin/sh
#
# iptables Start iptables firewall
#
# chkconfig: 2345 08 92 =》就是通过这里设置的(虽然是#开头但仍会读取)
2345:表示指定级别
08:表示S08
92:表示K92
# description: Starts, stops and saves iptables firewall
# config: /etc/sysconfig/iptables
# config: /etc/sysconfig/iptables-config
### BEGIN INIT INFO
# Provides: iptables
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
默认在哪些级别下开启此功能:S
# Default-Stop: 0 1 6
默认在哪些级别下关闭此功能:K
# Short-Description: start and stop iptables firewall
# Description: Start, stop and save iptables firewall
### END INIT INFO
这两类文件其实都是/etc/init/目录下的某个脚本的链接
只有一个文件特殊/etc/rc.d/ec3.d/S99local是链接到/etc/rc.d/rc.local
可以把那些不便放于/etc/init.d/下的欲执行的命令放在此目录下,开机时也会自动执行;
可以通过chkconfig命令管理这些链接文件;
显示:
chkconfig --list
设置:
chkconfig --level # NAME on/off
chkconfig --level 3 sshd on
添加:
先将服务脚本放置于/etc/init.d/(/etc/rc.d/init.d/)目录中
根据脚本中的chkconfig:#1-6 ## ##来指定级别、S##、K##
使用chkconfig --add NAME创建链接
朋友,到这里你会发现,当你想开机就启动某些服务功能时就可以通过这一步来进行设置添加你要的服务;
删除:
chkconfig --del NAME
只是删除链接,脚本还在;
一篇比较详细的解释文章:https://blog.csdn.net/newnewman80/article/details/8133797
tty1:2345:respawn:/usr/sbin/mingetty tty1
……
tty6:2345:respawn:/usr/sbin/mingetty tty6
与上面初始化时的格式类似
这里使用respawn想必大家都有体会,就是当我们无论登出多少次或者登陆错误时,都会在界面上重新显示让我们登陆的提示符;
mingetty可以显示登陆提示符,然后验证账号和密码是否正确,最后打开一个属于你的shell进程;
/etc/rc.d/rc.sysinit:系统初始化脚本
设置主机名
设置欢迎信息
激活udev和selinux
挂载/etc/fstab文件中定义的文件系统
检测根文件系统,并以读写方式重新挂载根文件系统
设置系统时钟
激活swap设备
根据/etc/sysctl.conf文件设置内核参数
激活LVM及software raid设备
加载额外设备的驱动程序
清理操作
总结:/sbin/init→(/etc/inittab)→设置默认运行级别→运行系统初始脚本、完成系统初始化→关闭对应级别下需要关闭的服务,启动需要启动的服务→设置登陆终端
Centos 6:
init程序为upstart,由Ubuntu研发
配置文件:/etc/inittab(centos 6为了便于更改默认级别所保留的)、/etc/init/*.conf(centos 6 真正使用的配置文件)
centos5把所有命令都放在了inittab一个文件中,centos6把命令拆分到了*.conf等多个文件中;
Note:/etc/init/*.conf文件语法 遵循 upstart配置文件语法格式;
讲解一下级别1(维护模式):
开启主机当界面上出现Vmware下面出现进度条时,按任意键可呼出隐藏的菜单
选择kernel
键入"1"然后按Enter键→进入维护模式
然后键入passwd就可以更改管理员的密码了
接着可以重启系统或者键入init 3直接切换到多用户模式
总结Centos 6启动流程:
POST→Boot sequence(BIOS)→Kernel(initramfs)→rootfs→switchroot→/sbin/init→(/etc/inittab、/etc/in it/*.conf)→设定默认运行级别→系统初始化脚本→关闭会启动对应级别下的服务→启动终端
注:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删