1
2
3
4
5
6
7
8
9
10
|
一、Linux系统组成 二、问题:先有鸡还是先有蛋 三、内核特点 四、Centos的启动流程 五、/sbin/init初始化: 六、配置文件:/etc/inittab 七、/etc/rc.d/init.d中脚本格式详解 八、si::sysinit:/etc/rc.d/rc.sysinit 九、CentOS6的启动流程 十、CentOS7启动过程 |
一、Liinux的组成部分:内核+根fs
内核:1.进程管理(进程调度,进程创建,交互等)
2.内存管理:抽像为线性地址,为每个地址一份
3.网络协议栈
4.文件系统
5.驱动程序
6.安全功能//selinux,安全访问的栈等
IPC:inter process communication //进程间通信机制
消息队列、semerphor,shared memory(shm) //本地进程间通信
socket //远程主机通信,一个主机监听在一个socket上,另外一个进程发送请求,建立通信
TCP/IP分为两段:通信子网+网络子网
运行中的os环境可分为两层:内核空间+用户空间
用户空间:应用程序(进程或者线程)
内核空间:内核代码(系统调用) //system call和用户空间交互
//进程运行,需要在用户和内核模式之间来回切换,应尽量避免和用户交互
Linux系统:
内核+根fs :动态视角
磁盘分区及相关files:静态视角
二、问题:先有鸡还是先有蛋
内核是在某个分区上放着的:启动分区:/boot;内核启动之前是没有 / 的。
那么既然没有根 如何加载内核呢?系统启动需要先加载内核,内核必须在根加载后才能访问和加载
rootfs:FHS有特定目录结构,{/bin,/sbin,/etc,/proc,/sys,/dev,init...}
在boot没有被加载以前,/ 在哪儿,内核又在哪儿呢
sda1==/boot //虽然标记为boot分区,但是内核没有启动,没有 / 也没有 /下的boot
系统先启动内核,但是内核文件在/ 下,必须先找到 /,但是 / 是在内核启动之后才有的 /
:先有鸡和先有蛋的问题
内核是对所有硬件负责的,所有程序必须经过内核去和硬件交互
内核设计流派:
1.单内核设计:所有功能集成与同一个程序 //一个程序bug,可能整盘结束
Linux //linus:只要能用就行
2.微内核设计:每个功能使用一个子系统实现 //更优秀点,故障一个发生,不会影响其他
Windows,solaris
三、内核特点
开机先加载内核:
内核加载 /,而 / 在分区上需要加载disk driver,而driver在 / 的某个分区上,需要加载disk driver :循环
因此开机的时候,加载ramdisk //虚根
Linux内核特点:
支持模块化:.ko(kernel object),.so(shared object)//个应用程序间的共享模块
支持模块动态装载和卸载
组成部分:核心文件+模块文件
内核文件:/boot/vmlinuz-3.10.0-327.el7.x86_64 //z:标识为压缩存放
vmlinuz-VERSION-release.arch //release是制作者添加的
ramdisk:实现系统初始化,基于内存的磁盘设备
Centos5:initrd-VERSION-release.img //rd:ramdisk
Centos6,7:initramfs-VERSION-release.img //ramfs ,基于ram 的fs
//基于ramdisk:在内存中已经被加载,但是在buffer/cache中仍被缓存
//ramfs:基于ram的fs减少了buffer和cache
//升级主要是为了避免双缓冲,双缓存的目的,从而达到提升性能的目的
模块文件
/lib/modules/3.10.0-327.el7.x86_64/
/lib/modules/3.10.0-327.el7.x86_64/kernel //内核模块的模块
www.kernel.org //内核源码
mainline:当前主要开发和维护的版本
stable:稳定
longterm:长期维护的版本
问题:为什么把ramdisk当做磁盘用
os启动的时候,需要把ramdisk装载到内存中,而后让 / 把他当做磁盘来使用,
从而把他识别为一个根 fs ,加载/lib/modules :ramdisk中生成的模块
借助于ramdisk加载真正的 / 所需的驱动,然后完成切换
//必要性:借助于ramdisk实现加载disk 驱动
//对于发行商来说,主要是为了应付多种硬件平台,需要借助于ramdisk
//非必要:个人使用,面对当前系统的
假如明确知道驱动类型,而且已经加载进内核,内核是自己编译的
问题:要装载根,必须先装载disk驱动程序,disk在哪里
disk驱动程序: /lib/modules 在根fs上
中间设备:一个完整的根fs系统,负责加载真正的 / 的驱动
内核启动后,负责加载这个假的临时的根fs //临时:作用,从真正的根fs中装载真 / 所需的驱动而已
注意:这个驱动是安装过程中生成的,根据当前主机的设备信息,动态创创建生成
initrd文件的作用:
initrd 的英文含义是 boot loader initialized RAM disk,即由引导程序初始化的RAM磁盘。
initrd是在实际根文件系统可用之前挂载到系统中的一个初始根文件系统。initrd与内核绑定在一起, 并作为内核引导过程的一部分进行加载。内核然后会将这个initrd文件作为其阶段引导过程的一部分来加载模块,
这样才能在以后的引导过程中使用真正的文 件系统,并挂载实际的根文件系统。
Initramfs
在linux2.5中出现了initramfs,它的作用和initrd类似,只是和内核编译成一个文件(该initramfs是经过gzip压缩后的cpio格式的数据文件),
该cpio格式的文件被链接进了内核中特殊的数据段.init.ramfs上,其中全局变量__initramfs_start和__initramfs_end分别指向这个数据段的起始地址和结束地址。
内核启动时会对.init.ramfs段中的数据进行解压,然后使用它作为临时的根文件系统。
四、Centos的启动流程
1.POST:自检程序,x86cpu设计上,通电后,自动检查硬件设备是否存在
power on and self test
ROM:CMOS 程序所在地,cpu加电后自动回寻找该程序
BIOS:CMOS中的一个基本输入输出系统
固化在ROM中:basic input and output system
CPU能够访问的地址空间:ROM+RAM
2.Boot Sequence:
按次序查找各引导设备,第一个有引导程序的设备即为本次启动,要用到的设备
bootloader:引导加载器 //硬盘,U盘,光盘上的一个程序
windows:ntloader
Linux:
LILO:Linux Loader //无法支持大硬盘,1024个柱面之后难以加载
//android手机通常使用该引导
GRUB:Grand Uniform Bootloader //统一引导加载器
Grub 0.x:CentOS 5,6 :Grub Legacy 传统经典版本
Grub 1.x:CentOS 7 :Grub2
作用:提供一个选择菜单,允许用户选择要启动的程序或不同的版本,把用户选择的内核版本装载到RAM中的内核空间中
解压、展开,而后移交控制权
安装位置中:
MBR+Grub:master boot record
512bytes:{446:bootloader 64:fat 2:55AA} //fat:filesystem allocation table 分区表
55AA:表示该MBR有效,bootloader有效,其他都表示无效
Grub:把其程序分为两段,1:bootloader中,2:Disk partition中/boot/grub中
1:bootloer中用来加载第二段
1.5:filesystem driver,加载fs驱动
2:第二段上提供bootloader的真正功能,选择菜单等
最后加载内核文件
UEFI+GPT:新版本的替代产品
3.Kernel
自身初始化:
探测可识别到的所有硬件设备
加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)
以只读方式挂载rootfs
运行用户空间的第一个应用程序:/sbin/init
init程序:
CentOS5:SysV init
配置文件:/etc/inittab
CentOS6:Upstart //基于dbus通信,支持并发启动服务
配置文件:/etc/inittab //没用的
/etc/init/*.conf //决定性配置文件
CentOS7:Systemd
配置文件:/usr/lib/systemd/system/
/etc/systemd/system
ramdisk:
Linux内核特性之一:使用缓冲和缓存来加速对磁盘上的file访问
ramdisk-->把内存当disk来使用,导致内存需要再次缓冲disk的内容:双缓冲
ramdisk-ramfs//变成了ramfs就不在需要缓冲了
CentOS5:initrd :mkinitrd
CentOS6,7:initramfs :dracut,mkinitrd
小结:系统初始化流程(内核级别)
POST-->BIOS(BootSequence)-->MBR(BootLoader)--->kernel-->initrd(initramfs)->挂载rootfs(ro)--->/sbin/init:用户空间的第一个程序
bootloader:一般是无法驱动那些软设备,软raid等,lv等复杂的
不能放在lv上,只能放在基本的逻辑分区上
kernel:只能放在基本分区上,因此/boot一般要单独分区
可能需要借助于ramdisk来完整真正 rootfs的加载
因为有的fs,可能kernel也不能直接驱动
五、/sbin/init初始化:
windows的安全模式:使用基本的驱动,然后可以进行修复
CentOS5:SysV init
运行级别:为了系统的运行或维护等目的而设定的机制
1
2
3
4
5
6
7
8
|
0-6:7个级别
0:shutdown
1:单用户single user,root用户,无需登录,维护模式
2:multi user启动网路功能,但不会启动NFS,维护模式
3. 多用户模式multi user,正常模式
4:预留模式,目前无特别使用目的,但习惯以同3级别对待
5:多用户模式,完全功能模式,图形界面
6:重启模式,reboot
|
0-6,3--5,1,2救援
级别切换:init #
级别查看:who -r / runlevel
N 3//N上一次没有级别,3:当前级别
配置文件:/etc/inittab
六、配置文件:/etc/inittab
Centos5:
每行定义一种action以及与之对应的processs
id:runlevel:action:process
id//任务的标识符,唯一
runlevel//在那些级别启动,#,###,可以为空表示所有级别
action:在什么条件下启动此任务
wait:等待切换至此任务所在的级别时执行一次
respawn:此任务终止时,就自动重新启动 //比如每次logout的时候登录界面都会显示出来
initdefault:设定默认运行级别,此时process省略
sysinit:系统初始化方式,此处一般指定/etc/rc.d/rc.sysinit
process:具体的任务是什么
例如:
id:3:initdefault //设定默认运行级别为3
si::sysinit:/etc/rc.d/rc.sysinit //使用这个脚本系统初始化
IO:0:wait:/etc/rc.d/rc 0 //0级别运行,向rc命令传递参数 0
rc脚本的功能:接受一个级别脚本为参数[0-6];
/etc/rc.d/rc0.d/ 是0级别运行的脚本
S#:启用顺序;
K#:关闭顺序 //数字越小越优先关闭{依赖别人的服务的服务先关闭},一个脚本都有开始和关闭的两个顺序
debian使用的是另外一套机制
脚本框架:
for srv in /etc/rc.d/rc#.d/K*;do
$src stop
done
for src in /etc/rc.d/rc#.d/S*;do
$src start
done
注意:/etc/init.d/* 脚本执行方式 {start|stop|restart|status}
/etc/rc.d/crond start
service crond start //作用一样
service 会自动到/etc/rc.d/init.d中查找该文件的启动脚本
七、/etc/rc.d/init.d中脚本格式详解
chkconfig: 2345 11 88 //启动级别,启动顺序,关闭顺序
//启动优先级:应该小于{先启动}其他依赖该服务的其他程序
//关闭优先级:应该大于{后关闭}:其他依赖该服务的其他程序,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
vim /etc/init.d/testsrv
#!/bin/bash
#
#
# chkconfig: 2345 51 61 //# chkconfig: - 51 61//-表示所有级别都要关闭
//runlevel 启动优先级 关闭优先级
# description: testing service
prog=$(basename $0)
if [ $# -lt 1 ] ;then
echo "Usage: ${basename} {start|stop|restart|status
}" exit 1
fi
if [ "$1" == "start" ];then
echo "start $prog finished."
elif [ "$1" == "stop" ] ;then
echo "stop $prog finished."
elif [ "$1" == "restart" ] ; then
echo "restart $prog finished."
elif [ "$1" == "status" ; then
if pidof $prog &> /dev/ null ;then
echo "$prog is running"
else
echo "$prog is stopped."
fi
else
echo "Usage: $prog {start|stop|status|restart}"
exit 2
fi
|
chmod +x filename
bash -n testsrc
chkconfig --add testsrc //--del 受chkconfig管理
//在2345分别创建一个S51testsrv的链接文件
//在06分别床架你一个K31testsrv的链接文件
service testsrc start //进行测试
chkconfig命令:管控/etc/init.d/两个服务脚本在各级别下的启动或关闭服务
--list testsrv //列出
chkconfig --level 235 testsrv on
chkconfig --list mysqld
chkconfig [--level LEVELS] name [on|off|reset]
//默认为2345
chkconfig testsrv on/off //默认2345
rc.local //可用于用户自定义命令,开机启动一次
注意:正常级别下,最后启动一个服务S99local没有链接到/etc/rc.d/rc.local下的某脚本,而是连接到了/etc/rc.d/rc.local;
因此用于开机启动的服务脚本,可以写在这里
tty1:2345:respawn:/usr/sbin/mingetty tty1
...
tty5:2345:respawn:/usr/sbin/mingetty tty6 //启动虚拟终端的
1.mingetty会调用login程序,真正实现用户登录和验证
2.打开虚拟终端的程序除了mingetty之外,还有getty等
tty7:5:respawn:/etc/X11/ 图形界面启动
总结:(用户空间的启动流程):/sbin/init/inittab
1.设置默认运行级别,initdefault
2.运行系统初始化脚本,rc.sysinit
3.关闭对应级别下需要停止的服务
4.启动对应级别下需要开启的服务
5.设置登录终端
6.启动图形终端
八、si::sysinit:/etc/rc.d/rc.sysinit 系统初始化脚本的作用
1
2
3
4
5
6
7
8
9
10
11
|
(1)设置主机名
(2)设置欢迎信息
(3)激活udev和selinux
(4)挂载/etc/fstab文件中定义的所有fs
(5)检测rootfs,以rw方式挂载
(6)设置系统时钟 //通过读取硬件时钟来实现
(7)根据/etc/sysctl.conf文件的设置,来设置内核参数
(8)激活lvm,及软raid设备
(9)激活swap设备 //挂载到fstab中的会被直接挂载,可以省略
(10)加载额外设备的驱动程序,内核没有识别到的
(11)清理操作
|
九、CentOS6的启动流程
init程序:upstart,但依然为/sbin/init,配置文件是
/etc/init/*.conf ,/etc/inittab(仅仅用于定义默认级别)
/etc/init/init-system-dbus.conf 这个是服务启动脚本
注意:*.conf为upstart风格的配置文件
rcS.conf
rc.conf 运行级别
start-tty.conf 启动终端
POST-->BIOS-->MBR(Bootloader)-->kernel(initrd)--rootfs-->switch_root-->/sbin/init
十、CentOS7启动过程
init程序:systemd,配置文件:
/usr/lib/systemd/system/* //
/etc/systemd/system/* //两个文件
CentOS5,6:开机的时候定义为开启的,直接就启动了
CentOS7:定义开机自启的也不启动,而是在第一次访问的时候才启动
只要不访问就一直不启动,所以开机快
systemctl set-default //设置默认运行级别
get-default //获取默认运行级别
Centos7默认没有运行级别的概念
但是依然可以使用service 命令
完全兼容SysV脚本机制;因此service 命令依然可用
systemctl {start|stop|restart|reload|status} name[.service]
systemctl list-unit-files //列出单元文件
systemctl enable|disable named //激活开机自启
OST--->BIOS(Boot Sequence)-->MBR(boot loader)--->kernel(ramdisk)-->rootfs--->switch root--->/sbin/init
-->{/etc/inittab,/etc/init/*.conf)
1.设定默认运行级别
2.系统初始化脚本
3.关闭或启动对应级
注意:VMware:右键该虚拟机,打开电源时进入固件 打开bios
本文转自MT_IT51CTO博客,原文链接:http://blog.51cto.com/hmtk520/1978207,如需转载请自行联系原作者