linux系统开机启动流程
在系统刚启动时,系统会主动的读取BIOS加载硬件信息以及进行硬件自我检测,并根据其中设定的取得第一个开机装置的MBR(主要启动记录区)中的boot loader(开机管理程序,例如grub),然后开机管理程序就可以加载内核到内存当中解压缩并执行,此时内核就可以在内存中运行起来了。然后内核会去侦测所有硬件,如果不能识别某些硬件就需要加载硬件驱动程序来挂载根文件系统。此时内核就可以运行第一种程序init呢,等到init这只程序运行完毕后,整个linux运行环境已经准备完毕,只等待用户登入了。
可以将linux启动的流程分为如下几部:
1、读取BIOS加载硬件信息并进行自我检测
2、读取第一个可开机装置中MBR中的boot loader。
3、boot loader加载内核到内存当中解压缩并运行
4、内核侦测所有硬件信息,并加载相关硬件驱动程序来挂载根文件系统
5、运行/sbin/init这个程序,来管理用户空间的所有进程或服务
6、init这个程序运行完毕后,等待用户登入。
内核的设计风格
单内核:这种设计的内核是将许多模块直接编译到内核,因此该设计的内核容量比较大
微内核:这种设计的内核将许多的子功能设计成模块,所以当系统需要哪种功能是只需要加载相关的模块就可以了,因此这种设计的内核容量比较小。
而在kernel中的模块叫做kernel object(ko)
在由RedHat、SuSE设计的内核中是由核心和模块组成的,该核心可以加载内核模块完成相应功能。
我们知道内核要访问根文件系统才能访问磁盘上的/sbin/init这个程序,而要想访问根文件系统,那么根文件系统必须要挂载后才可以访问,而根文件系统的挂载就需要kernel来加载硬件驱动程序来识别磁盘,从而完成根文件系统的挂载。
一般说来,我们的硬件驱动程序或者其他功能模块是放在/lib/modules/`uname -r`/kernel/目录下的,所以这个驱动程序也是存放在磁盘上的,而kernel有无法识别硬盘,那么又如何加载相应的驱动程序呢?
这时候我们就需要借助initrd这个程序了。boot loader可以将这个文件加载到内存当中解压缩仿真成一个根目录,形成一个虚拟文件系统(ramdisk)。这个虚拟文件系统中包含了开机所需要的相关模块。通常这些模块是USB、RAID、LVM、SCSI等文件系统与磁盘接口的驱动程序。因此内核就可以加载这些相关模块,释放虚拟文件系统,从而能够识别磁盘。来实际完成根文件系统的挂载。根文件系统挂载后,那么kernel就可以重新运行/sbin/init这个程序了,完成用户空间的进程初始化。
在RHEL 5中虚拟文件系统使用initrd这个程序形成的
在RHEL 6中虚拟文件系统是由initramfs形成的
grub程序
从上面启动的过程中我们发现,linux的内核是通过开机管理程序(boot loader)来加载到内存中执行的。如果没有boot loader内核是无法被加载到内存当中,那么系统也就无法运行起来。所以boot loader就是整个系统启动过程中最重要的程序。目前最主流的boot loader就是grub这个程序了。
那么grub是如何完成内核加载的呢?
grub完成内核加载可分为2个阶段:
第一阶段:主要执行boot loader的主程序,这个程序放在MBR中
第二阶段:boot loader加载主要配置文件,这个配置文件为/boot/grub/grub.conf
其中主要包括的信息如下:
default=0:设定默认启动的title编号,从0开始
timeout=5:等待用户的超时时长(如果没有按键盘的话),单位为秒
splashp_w_picpath=(hd0,0)/grub/splash.xmp.gz
hiddenmenu:隐藏选单菜单
title Red Hat Enterprise Linux Server (2.6.18-308.el5):内核标题或者操作系统名称,可以自由修改。
root(hd0,0) #表示内核所在的设备,对于grub而言,所有类型的硬盘一律为hd,所以设备格式为hd(#,N),其中#表示第几个硬盘,最后的N表示这个磁盘上的第几个分区。默认数字都是从0开始的。
kernel /vmlinuz-2.6.18-308.el5 ro root=LABEL=/ rhgb quiet #内核文件所在的路径,以及传递给内核的参数;如果/boot没有独立分区,那么此时的路径为/boot/vmlinuz*
initrd /initrd-2.6.28-308-el5.img #ramdisk文件路径,其中2.6.18-308.el5为内核版本,可以使用uname -r来查看
在/proc目录下,有一个文件叫做cmdline这个文件是用来保存kernel的参数的。
而在/pooc/目录下的每一个进程目录下,也有一个cmdline文件,这个文件是该进程启动时执行的命令。
如何修复grub
当某个磁盘上的grub遗失或者grub损坏了,系统无法正常启动,所以这时需要修复grub文件了。
使用如下命令来修复:
当grup损坏时,系统重新启动后会进入grub shell中,再在环境下输入如下命令即可正常启动系统。
grub> find (hd#,N) / (然后按tab键,如果显示出了内核文件,则表示内核就在该磁盘上)。
grub> root (hd#,N) #这里是kernel所在磁盘。
grub> kernel /path/to/kernel_file #指定内核的文件路径。
grub> initrd /path/to/initrd_file #指定initrd文件所在路径。
grub> boot #启动系统
例如:
等系统正常启动后,在手动生成一个文件/boot/grub/grub.conf,那么下次启动后就可以正常开机了。
如何安装grub
有2种安装grub方式
第一种:直接输入grub命令进入grub shell中去
例如:grub
grub> root (hd0,0) #这里指定内核所在的磁盘
grub> setup (hd0) #这里grub程序指定安装在哪个磁盘上
grub> quit #退出grub
第二种安装方式,在当前主机上安装grub程序到其他硬盘上
使用grub-install --root-directory=/path/to/boot's_parent_dir /path/to/device
其中--root-directory=/path/to/boot's_parent_dir为boot的父目录
/path/to/device:为指定的磁盘上面安装grub
linux的系统级别
系统的运行级别:从0-6共7个级别,不同的级别启动的服务不一样
0:用于halt关闭系统
1:single user mode单用户模式,在该级别下,用户可以直接以管理员身份切换,而且不需要密码,
其中s,S,single都表示为单用户模式,该模式是用来维护系统的
2:multi user mode ,no NFS表示多用户级别,但是该级别下无NFS功能
3:multi user mode ,text mode该模式就是我们常说的文本模式
4:reserved保留
5:multi user mode,grapic mode我们常说的图形化模式
6:reboot用于重启系统
为grub程序设置密码
我们知道在系统刚启动时,会显示一个grub页面,在该页面下,可以使用一些命令如e就可以编辑内核参数和命令,而如果我们没有给他们设定密码的话,那么所有的人都可以修改内核的参数和命令,或者更严重的可以修改管理员密码,这对于系统来说是不安全的。
使用grub-md5-crypt可以为grub程序设定密码,然后在将此命令下生产的密码字符串放在grub.conf中
例如:
其中password这一行,就是我们设定的密码,如果想要修改某些参数,必须先得输入密码才可以。
如果password这一行放在title下面,那么表示的意思就是grub在加载内核时,必须先输入密码,才可以加载内核。
如何进入单用户模式?
在系统运行到上图这个页面时,首先输入p在输入设定的密码,就可以使用e来编辑内核的参数了,在内核的参数后面加上s或S或single等字符串,在输入Enter键,最后输入b就可以进入单用户模式了。单用户模式一般用于维护系统。
此处就是单用户模式了。
init的配置文件为/etc/inittab
其中每一部分的信息表示的意思为:
id:3:initdefault: #表示该系统默认运行的等级为3
si::sysinit:/etc/rc.d/rc.sysinit #表示系统初始化
/etc/rc.d/rc.sysinit主要完成的任务包括如下几部分:
1、激活udev和selinux
2、根据/etc/sysctl.conf来设置内核参数
3、设置时钟
4、装载键盘映射
5、启动交换分区
6、设定主机名
7、进行根文件系统检测,并以读写方式创新挂载
8、激活RAID和LVM设备
9、启动磁盘配额
10、根据/etc/fstab来挂载其他文件系统
11、清理过期的锁和PID文件
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1l2:2:wait:/etc/rc.d/rc 2l3:3:wait:/etc/rc.d/rc 3l4:4:wait:/etc/rc.d/rc 4l5:5:wait:/etc/rc.d/rc 5l6:6:wait:/etc/rc.d/rc 6#这里的每一行可以使用id:runlevels:action:process来表示
#这里的每一行都是用冒号来分成四段的,每一段表示的意思为:
第一段表示运行等级的id
第二段表示系统运行的等级
第三段表示系统在什么情况下要执行此行
第四段表示系统运作的程序,通常都是一些脚本
其中/etc/rc.d/rc文件中的脚本信息大概为:
#!/bin/bash
#关闭某个运行级别所对应目录下的K*文件 for STOP in /etc/rc$1.d/K*;do $STOP stop done #开启某个运行级别所对应目录下的S*文件 for START in /etc/rc$1.d/S*;do $START start done
其中action(第三段信息)可以有这些:
initdefault:设定默认运行级别
sysinit:执行系统初始化
wait:等待级别切换到此级别时执行
respawn:一旦程序终止会立即重新启动
其中/etc/rc.d/rc 3表示在某个级别下要执行的脚本的信息,后面的数字[0-6],表示运行这个脚本时的参数,也就是$1.
以/etc/rc.d/rc 3为例来说明:通过$1也就是3来取得要执行的脚本目录,即/etc/rc$1.d/
(这里是/etc/rc3.d/)这个目录,这个目录下存放着许多的K*和S*文件。
在切换到指定的级别下时,K*文件先关闭,然后在启动S*文件,这些文件都是系统服务,且也是链接文件,真正的服务文件存在/etc/init.d/或者/etc/rc.d/init.d/这个目录下。
每个文件由两位数字##组成,这个数字表示的是服务启动或关闭的优先顺序,数字越小,越优先选定。
我们知道这些以S*命名的文件和以K*命名的文件,在切换到指定的级别下时,会启动以S*命名的服务和会终止以K*命名的服务。而这些文件都是连接文件,他们都是指向/etc/init.d/或者/etc/rc.d/init.d/目录下的文件,这些文件都是脚本文件。
在这些脚本文件中,都包含特定的2行,这两行的内容为:
# chkconfig:runlevel SS KK
# discription:string...
虽然这两行是批注内容,但是使用chkconfig命令时,是会读取这两行内容的。
其中chkconfig这一行的意思为:当使用chkconfig命令为某个脚本创建链接时,会在指定级别(runlevel)下创建以S开头的文件,且S开头的文件的启动优先级为SS,而在除此之外的级别下,创建以K开头的文件,且以K开头的文件的关闭优先级为KK。其中如果runlevel为"-"时,表示任何级别下默认没有S开头的链接文件
例如:irda这个程序在所有级别下都没有S开头的链接文件
第二行也就是description这一行为描述这个脚本的功能
如何使用chkconfig命令为某个脚本创建链接文件呢?
chkconfig语法格式:
chkconfig --list :查看所有的独立守护进程的启动设定
chkconfi --list service_name :查看某个特定的脚本或者服务的启动设定
chkconfig --add service_name:为某个特定的脚本或者服务创建链接
注意:(创建的链接是根据脚本中chkconfig这一行的设定来创建的,且这个脚本要位于
/etc/rc.d/init.d/或者/etc/init.d/目录下。这两个文件是软链接文件)
chkconfig --del service_name:为某个特定的脚本或者服务删除链接
chconfig [--level RUNLEVEl] service_name {on|off}
设定某个服务在某个运行级别下自动开机启动或者关闭
如果省略运行级别[--level RUNLEVEl],则默认为2345级别
说明:使用chkconfig启动的服务或者关闭的服务只在下次开机才会生效
例如:创建一个Myservice文件,让他在345级别下创建S开头的链接,在其他级别下创建K开头的链接
其中/etc/rc.local是一个脚本文件,是在系统最后才执行的一个脚本文件。
如果想让某些脚本或者命令每次开机自动执行,就可以在这个文件中增添相应的内容。
接着说/etc/inittab这个文件的内容
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now这一行表示的是使用ctrlaltdel可以重启系统
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"# If power was restored before the shutdown kicked in, cancel it.pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"这两行表示的意思是当系统断电后,多少分钟后自动关机后面一行的意思是当系统来电了,在还没有关机之前(前一行指定的时间内),取消自动关机
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty12:2345:respawn:/sbin/mingetty tty23:2345:respawn:/sbin/mingetty tty34:2345:respawn:/sbin/mingetty tty45:2345:respawn:/sbin/mingetty tty56:2345:respawn:/sbin/mingetty tty6这几行表示的意思是当tty1-tty6这几个终端使用logout终止时,会立刻重新启动该终端,等待用户输入。
我们常说的6个终端就是在这里指定的,如果不想要这么多终端,可以批注掉几行。
/sbin/mingetty:用来登入终端的,且会执行login这个程序,提醒用户输入用户名才可以登入进去
/sbin/agetty -n -l login_programe 38400 tty:在登入终端时,执行某些程序
-n:表示不用输入用户名就可以直3接登入到系统中去
-l login_programe:登入时执行的程序
# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon这一行就是启动图形终端
总结/etc/inittab文件中的主要内容:
1、设定默认运行级别
2、运行系统初始化脚本
3、运行指定级别下对应目录下的脚本,所有的K*文件停止,所有的S*文件启动
4、设定Ctrl+Alt+Del组合键来重启系统
5、定义UPS在电源故障/恢复故障下的操作
6、启动虚拟终端
7、启动图形终端
总结系统开机流程:
BIOS(POST)-->MBR(boot loader)-->kernel-->initrd(加载开机所需的模块)-->加载/sbin/init这个程序
进程的类型
进程分为独立守护进程和瞬时守护进程
独立守护进程:这种类型的进程一直存在内存中,所以当客户端有请求时,该进程响应速度快,但是占用内存资源,一直处于监听状态。
瞬时守护进程:瞬时守护进程是由一个超级守护进程来管理的,这个超级守护进程叫做xinetd。超级守护进程一直处于监听状态。当客户端有请求时,超级守护进程负责呼叫它所管理的瞬时守护进程,当请求结束时,该进程在内存中将会释放,因此不会占用内存资源。但是由于只有发生请求时才生成进程并响应,因此该类进程响应速度慢。
瞬时守护进程是不需要关联运行级别的。而超级守护进程需要关联运行级别的,且一直存在内存当中。
例如: