linux系统启动流程详解

付费节点推荐


免费节点


节点使用教程


一、linux系统的总体启动流程如下:
POST –> BIOS(Boot Sequence) –> MBR(bootloader) –> kernel + initramfs(或initrd) –> mount rootfs (ro) –> /sbin/init设定默认运行级别 –> 使用/etc/rc.d/rc.sysinit初始化系统 –> 分别启动并关闭指定服务 –> Ctrl+Alt+Delete组合键 –> 启动字符终端 –> 启动图形终端

二、linux系统启动各阶段详述:
1、post:加电自检。通电后,CPU会加载位于CMOS中的BIOS程序,BIOS由一系列的汇编指令组成,它会识别并检测主板上的所有硬件,然后按照BIOS里设置的启动顺序依次寻找可引导设备,一旦找到便停止寻找

2、MBR:CPU读取可引导设备的第一个扇区即MBR(Master boot record),也称“主引导记录”,大小为512字节,其中存放着:
引导加载程序(boot loader):446bytes,常用的boot loader有LILO和GRUB,现以GRUB为主;
分区表:64bytes
有效性标记:2bytes
CPU把boot loader加载到内存中执行,boot loader帮我们从磁盘上找到内核并加载到内存中

3、kernel:内核被加载后,它要做的工作主要有:探测硬件、装载驱动程序、以只读方式装载根文件系统(rootfs)、启动第一个进程/sbin/init。
这里会有个“鸡生蛋”还是“蛋生鸡”的问题,根文件系统存在于磁盘上,内核要装载根文件系统就需要先能驱动磁盘,即需要先装载驱动程序,而驱动程序又在磁盘上。为解决此问题,boot loader在加载内核的同时也把initramfs(或initrd)加载到内存中(有关initramfs和initrd的详细说明见文末补充部分),它是一个临时的根文件系统,里面包含了启动所必须的驱动模块。内核挂载这个临时根,装载驱动程序,然后释放临时根,挂载实际的根文件系统,并启动第一个进程/sbin/init。
kernel和initramfs文件位于boot分区(或目录)下:
内核:/boot/vmlinux-VERSION-release
initramfs:/boot/initramfs-VERSION-release.img
[cc lang=”php”]
[root@node2 ~]# ls /boot
config-2.6.32-431.el6.x86_64 grub lost+found System.map-2.6.32-431.el6.x86_64
efi initramfs-2.6.32-431.el6.x86_64.img symvers-2.6.32-431.el6.x86_64.gz vmlinuz-2.6.32-431.el6.x86_64
[/cc]

4、init:内核初始化的最后一步就是启动pid为1的/sbin/init进程。这个进程是系统的第一个进程,它负责产生其他所有进程。init进程上来首先做的事是去读取/etc/inittab和/etc/init/*.conf(Centos 5上只有inittab文件)
在/etc/inittab和/etc/init/*.conf中,大致规定了以下动作:
取得runlevel即运行级别
使用/etc/rc.d/rc.sysinit进行系统初始化
根据runlevel启动相应的服务并关闭需要停止的服务
确定Ctrl+Alt+Delete组合键功能
启动字符终端
启动图形终端
系统运行级别:
0:关机
1:single user mode,即单用户模式
2:multi user mode,不支持NFS功能
3:完全多用户模式,文本接口
4:未使用,预留级别
5:完全多用户模式,图形接口
6:重启
可在命令行切换级别:init #
[cc lang=”php”]
[root@node2 ~]# cat /etc/inittab
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
# 0 – halt (Do NOT set initdefault to this)
# 1 – Single user mode
# 2 – Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 – Full multiuser mode
# 4 – unused
# 5 – X11
# 6 – reboot (Do NOT set initdefault to this)
#
id:3:initdefault: #这里设置的运行级别是3

[root@node2 ~]# ls /etc/init
control-alt-delete.conf plymouth-shutdown.conf rc.conf rcS-sulogin.conf readahead-disable-services.conf start-ttys.conf
init-system-dbus.conf prefdm.conf rcS.conf readahead-collector.conf serial.conf tty.conf
kexec-disable.conf quit-plymouth.conf rcS-emergency.conf readahead.conf splash-manager.conf
[/cc]

■补:CentOS 5中的/etc/inittab
与Centos 6不同,Centos 5上只有/etc/inittab,所有的初始化动作都是在此文件中定义的,此文件中定义的登记项都是以:隔开的四个段,格式如下:
id:runlevels:action:process 例如si::sysinit:/etc/rc.d/rc.sysinit
各字段的含义:
id:登记项的标识符,必须是唯一的
runlevels:系统的运行级别,表示process的action要在哪个级别下运行,可定义多个级别,各级别间不用分隔符;如果为空,表示在所有的运行级别下运行
具体的action有:
respawn:当process终止后马上启动一个新的
wait:当进入指定的runlevels后process才会启动一次,并且到离开runlevels为止
initfault:设定默认的运行级别
sysinit:系统初始化,只有系统开机或重启时process才会被执行一次

5、sysinit:在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它做的工作包括:
设定主机名:读取/etc/sysconfig/network文件中的HOSTNAME参数,并以之设定主机名
打印文本欢迎信息
激活selinux和udev
挂载/etc/fstab文件中定义的其它文件系统
激活swap
检测根文件系统,并以读写方式重新挂载
设置系统时钟
根据/etc/sysctl.conf设置内核参数
激活LVM和RAID设备
加载额外设备的驱动程序
清理操作

6、启动指定的默认级别的默认为启动的服务,停止指定的级别下默认为关闭的服务
/etc/rc.d/rc#.d (#表示运行级别),该目录下都是符号链接文件,其指向的实际服务脚本位于/etc/rc.d/init.d目录中(该目录有个软链接/etc/init.d)。这些链接文件均以S或K开头:
S##:启动的服务
K##:停止的服务
##:01-99,数字越小,越优先启动或关闭

[cc lang=”php”]
[root@node2 ~]# ls /etc/rc.d/
init.d rc rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d rc.local rc.sysinit
[root@node2 ~]# ll /etc/rc.d/rc3.d
total 0

lrwxrwxrwx. 1 root root 19 Aug 6 04:38 K75quota_nld -> ../init.d/quota_nld
lrwxrwxrwx. 1 root root 16 Aug 6 04:44 K76ypbind -> ../init.d/ypbind
lrwxrwxrwx. 1 root root 15 Aug 6 04:53 K80kdump -> ../init.d/kdump
lrwxrwxrwx 1 root root 24 Oct 31 07:28 K84wpa_supplicant -> ../init.d/wpa_supplicant
lrwxrwxrwx. 1 root root 21 Aug 6 04:34 K87restorecond -> ../init.d/restorecond
lrwxrwxrwx 1 root root 14 Oct 31 07:28 K88sssd -> ../init.d/sssd
lrwxrwxrwx. 1 root root 15 Aug 6 04:34 K89rdisc -> ../init.d/rdisc
lrwxrwxrwx. 1 root root 14 Aug 6 04:38 K99rngd -> ../init.d/rngd
lrwxrwxrwx. 1 root root 22 Aug 6 04:38 S02lvm2-monitor -> ../init.d/lvm2-monitor
lrwxrwxrwx. 1 root root 19 Aug 6 04:36 S08ip6tables -> ../init.d/ip6tables

lrwxrwxrwx. 1 root root 11 Aug 6 04:34 S99local -> ../rc.local #最后一个启动链接文件指向父目录rc.local
[root@node2 ~]# cat /etc/rc.d/rc.local
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don’t
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local
[/cc]

见上方,最后的一个启动链接文件为S99local,它指向/etc/rc.d/rc.local,如果我们不想把某些开机后的操作专门写成脚本,可写入此文件中。/etc/rc.d/rc.local还有一个软链接/etc/rc.local

若想控制某个脚本是否开机启动,可使用chkconfig命令
■chkconfig:查看或修改服务随系统启动的启动选项,它并不是直接激活或停止一个服务,而只是修改了其符号链接。用法如下:
①让指定的服务接受chkconfig命令管理:
第一步:在位于/etc/rc.d/init.d目录下的服务脚本中添加如下一行或多行注释:
# chkconfig: LEVEL SPRI KPRI ,例如# chkconfig: – 85 15
chkconfig后面有三个字段,它们的含义分别为:
LEVEL:当此服务由chkconfig控制时,默认在哪些运行级是启动的。若默认不在任何运行级启动,以“-”号表示
SPRI:启动优先级
KPRI:关闭优先级
第二步:chkconfig add SERVICE,该命令会自动在/etc/rc.d/rc#.d目录中创建链接文件
②chkconfig del SERVICE:让指定服务不再接受chkconfig管理,会删除链接文件
③chkconfig –list [SERVICE]:显示所有服务或指定服务的开机启动设置
④chkconfig [–level ###] SERVICE on/off/reset:若不指定–level选项,on和off操作默认只对运行级2、3、4、5有效,而reset默认对所有运行级有效,reset意为重置,即恢复成服务脚本中的初始设置

[cc lang=”php”]
[root@node2 ~]# cp testsrv /etc/rc.d/init.d/testsrv #接受chkconfig管理的服务其服务脚本必须位于init.d目录下
[root@node2 ~]# vim /etc/init.d/testsrv

#!/bin/bash
#
# chkconfig: 2345 90 10 #添加这一行,表示默认在运行级别为2、3、4、5开机启动
srv=`basename $0`

lockFile=”/var/lock/subsys/$srv”

[ $# -lt 1 ] && echo “Usage: $srv {start|stop|restart|status}” && exit 4

[ $UID -ne 0 ] && echo “Only root.” && exit 5

if [ “$1” == ‘start’ ]; then
if [ -f $lockFile ]; then
echo “$srv is running.”
exit 7

[root@node2 ~]# chkconfig –add testsrv #让testsrv接受chkconfig命令管理
[root@node2 ~]# ll /etc/rc.d/rc3.d | grep ‘testsrv’ #显示已创建了链接文件
lrwxrwxrwx 1 root root 17 Oct 31 08:29 S90testsrv -> ../init.d/testsrv
[root@node2 ~]# chkconfig –list testsrv #显示各级别开机启动设置
testsrv 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@node2 ~]# chkconfig testsrv off #默认关闭2-5级别开机启动
[root@node2 ~]# chkconfig –list testsrv
testsrv 0:off 1:off 2:off 3:off 4:off 5:off 6:off
[root@node2 ~]# chkconfig –level 23 testsrv on #指定在2、3级别随开机启动
[root@node2 ~]# chkconfig –list testsrv
testsrv 0:off 1:off 2:on 3:on 4:off 5:off 6:off
[root@node2 ~]# chkconfig testsrv reset #重置
[root@node2 ~]# chkconfig –list testsrv #显示已恢复成初始设置
testsrv 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@node2 ~]# chkconfig –del testsrv
[root@node2 ~]# ll /etc/rc.d/rc3.d | grep ‘testsvr’
[root@node2 ~]# rm -f /etc/init.d/testsrv
[/cc]

7、Ctrl+Alt+Delete组合键
启动系统服务后就是确定Ctrl+Alt+Delete组合键的功能了,配置文件为/etc/init/control-alt-delete.conf
[cc lang=”php”]
[root@node2 ~]# cat /etc/init/control-alt-delete.conf
# control-alt-delete – emergency keypress handling
#
# This task is run whenever the Control-Alt-Delete key combination is
# pressed. Usually used to shut down the machine.
#
# Do not edit this file directly. If you want to change the behaviour,
# please create a file control-alt-delete.override and put your changes there.

start on control-alt-delete

exec /sbin/shutdown -r now “Control-Alt-Delete pressed” #Control-Alt-Delete组合键的默认功能为重启系统
[/cc]

三、补充:initrd和initramfs
①initrd全称为initial ram disk,即linux初始RAM磁盘,它被加载到内存中后,会被内核当作block device。因为linux在设计上就会尽可能将读取/写入block device的文件予以cache,这样一来就会有重复的block device和cache资料,会浪费内存。
为解决此问题,linux 2.6之后引入了initramfs,它是一种ram filesystem,被加载至内存后,会被内核直接挂载并读取,不会再次cache
②initramfs或initrd实际是一个经过cpio和gzip工具处理后的归档压缩文件
展开initramfs过程如下:

[cc lang=”php”]
[root@node2 ~]# ls /boot
config-2.6.32-431.el6.x86_64 grub lost+found System.map-2.6.32-431.el6.x86_64
efi initramfs-2.6.32-431.el6.x86_64.img symvers-2.6.32-431.el6.x86_64.gz vmlinuz-2.6.32-431.el6.x86_64
[root@node2 ~]# file /boot/initramfs-2.6.32-431.el6.x86_64.img #显示initramfs是经过zip压缩的
/boot/initramfs-2.6.32-431.el6.x86_64.img: gzip compressed data, from Unix, last modified: Thu Aug 6 04:42:48 2015, max compression
[root@node2 ~]# cp /boot/initramfs-2.6.32-431.el6.x86_64.img ./initramfs-2.6.32-431.el6.x86_64.img.gz #要添加后缀后才能解压
[root@node2 ~]# gunzip initramfs-2.6.32-431.el6.x86_64.img.gz #解压
[root@node2 ~]# ls
anaconda-ks.cfg Downloads install.log Pictures samba-3.6.23-20.el6.x86_64.rpm vmware-tools-distrib
a.txt epel-release-latest-6.noarch.rpm install.log.syslog Public Templates zabbix-2.4
Desktop ftp-0.17-54.el6.x86_64.rpm Music ramfs testsrv
Documents initramfs-2.6.32-431.el6.x86_64.img mysql-5.1.73-5.el6_6.x86_64.rpm RPM-GPG-KEY-EPEL-6 Videos
[root@node2 ~]# cd ramfs
[root@node2 ~]# file initramfs-2.6.32-431.el6.x86_64.img #显示为cpio归档文件
initramfs-2.6.32-431.el6.x86_64.img: ASCII cpio archive (SVR4 with no CRC)
[root@node2 ~]# mkdir ramfs
[root@node2 ~]# cd ramfs
[root@node2 ramfs]# cpio -i < ../initramfs-2.6.32-431.el6.x86_64.img #展开 97331 blocks [root@node2 ramfs]# ls bin dev emergency init initqueue-finished initqueue-timeout lib64 pre-pivot pre-udev sbin sysroot usr cmdline dracut-004-335.el6 etc initqueue initqueue-settled lib mount pre-trigger proc sys tmp var [/cc] ③使用工具dracut或mkinitrd创建initramfs mkinitrd实际上也是调用dracut的功能,在Centos 6上已被dracut取代 用法: dracut [-f] [-k DIR] /path/to/initramfs-KERNEL_VERSION.img KRENEL_VERSION -f:覆盖现有的同名initramfs文件 -k DIR:指定加载内核模块的位置;默认为/lib/modules/KERNEL_VERSION 示例:针对当前运行内核创建 dracut /boot/initramfs-$(uname -r).img $(uname -r) 针对指定内核创建:(要确保能找到对应的内核模块) dracut /boot/initramfs-3.10.1.img 3.10.1 [cc lang="php"] [root@node2 boot]# mv initramfs-2.6.32-431.el6.x86_64.img initramfs-2.6.32-431.el6.x86_64.img.back #备份现有initramfs文件 [root@node2 boot]# dracut initramfs-$(uname -r).img $(uname -r) #针对当前系统内核创建initramfs [root@node2 boot]# ls config-2.6.32-431.el6.x86_64 initramfs-2.6.32-431.el6.x86_64.img symvers-2.6.32-431.el6.x86_64.gz efi initramfs-2.6.32-431.el6.x86_64.img.back System.map-2.6.32-431.el6.x86_64 grub lost+found vmlinuz-2.6.32-431.el6.x86_64 [/cc]

未经允许不得转载:Bcoder资源网 » linux系统启动流程详解

相关推荐

更多优质资源关注微信公众号: bcoder

bcoder
赞 (0)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册