加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Linux系统启动过程详解

(2016-05-01 13:44:19)
标签:

it

分类: Linux

                   Linux系统启动过程全解

 

1、Linux 的启动流程分析

在介绍Linux系统启动过程之前,先对Linux系统启动的过程大致的给大家归纳一下,好让大家在看本文之前有个大致的了解,然后带着问题往下看,效果会更好些。

主机系统开始运行后,此时Linux才会调用外部程序开始准备软件执行的环境,并且实际夹在所有系统所需要的软件。最后系统就会开始等待你的登录操作。简单来说,Linux系统启动的过程如下:

·  加载BIOS的硬件信息与进行自我检测,并依据设置取得第一个可启动的设备;

·  读取并执行第一个启动设备内MBR的boot loader(即是grup,spfdisk等程序);

·  依据boot loader的设置加载Kernel,Kernel会开始检测硬件与加载驱动程序;

·  在硬件驱动成功后,Kernel会主动调用init进程,而init会取得run-level信息

·  init执行/etc/rc.d/rc.sysinit文件来准备软件执行的操作环境(如网络、时区等);

·  init执行run-level的各个服务的启动(script方式);

·  init执行/etc/rc.d/rc.local文件; 

·  init执行终端机模拟程序mingetty来启动login进程,最后就是等待用户登录。 

 

1.1、BIOS, boot loader 与 kernel 加载

 

1.1.1 BIOS, 启动自我测试与 MBR

要启动整系统首先就得要让系统去加载 BIOS (Basic Input Output System),并通过BIOS 程序去加载 CMOS 的信息,并且通过 CMOS 内设置的值取得主机的各项硬件配置,例如 CPU 与接口设备通信频率、启动设备查找顺序、硬盘的大小与类型、系统时间、各周边总线是否启动 Plug and Play (PnP,即插即用设备) 、 各接口设备的 I/O 位址以及与 CPU 通信的 IRQ 中断等等的信息

读取这些信息后,BIOS 还会进行开机自检 (Power-on Self Test, POST)。 然后开始执行硬件检测的初始化,并配置 PnP 设备,之后再定义出可启动的设备顺序,接下来就会开始进行启动设备的数据读取了 (MBR 相关的任务开始)。

由于系统软件大多放置到硬盘中所以 BIOS 会指定启动的设备好让我们可以读取硬盘中的操作系统的内核文件。但由于不同的操作系统文件系统格式不相同,因此我们必须要以一个引导装载程序来处理内核文件加载 (load) 的问题, 因此这个启动引导装载程序就被称为 Boot Loader 了。那这个 Boot Loader 程序安装在哪里呢?就在启动设备的第一个区 (sector) 内,也就是我们上面谈到的 MBR (Master Boot Record, 主引导分区)。

那你会不会觉得很奇怪啊?既然内核文件需要 loader 来读取,那每个操作系统的 loader 都不相同, 这样的话 BIOS 又是如何读取 MBR 内的 loader 呢?很有趣的问题吧!其实 BIOS 是透过硬件的 INT 13 中断功能来读取 MBR 的,也就是说,只要 BIOS 能够测的到你的硬盘 (不论该硬盘是 SATA 还是 IDE 介面),那他就有办法通过 INT 13 这条道来读取该硬盘的第一个扇区内的 MBR 啦! 这样 boot loader 也就能够被执行了

注意:硬盘的第一个扇区区内含有 446 B的 MBR 区域,那么如果主机上面有两硬盘的话,系统会去哪硬盘的 MBR 读取 boot loader 呢?这个就得要看 BIOS 的配置了。基本上,我们常常讲的系统的 MBR其实指的是 第一个启动设备的 MBR 才对!所以,如果你要将引导装载程序安装到某块硬盘的 MBR 时, 要特别注意当时系统的第一个启动设备是是哪个,否则会安装到错误的硬盘上面的 MBR,这点非常重要!

1.1.2 Boot Loader 的功能

刚刚说到 Loader 的最主要功能是要认识操作系统的文件格式并据以加载内核存中去运行。由不同操作系统的文件格式不一致,因此每种操作系统都有自己的 boot loader用自己的 loader 才有办法载入内核文件。那问题就来大家应该有听说过多操作系统吧?也就是在一主机上面安装多种不同的操作系统。既然必须要使用自己的 loader 才能够加载属于自己的操作系统内核,而系统的 MBR 只有一个,那你怎么会有办法同时在一部主机上面安装 Windows 与 Linux 呢?

 其实每个文件系统 (filesystem, 或者是 partition) 都会保留一块引导扇区 (boot sector) 提供操作系统安装 boot loader , 而通常操作系统默认都会安装一份 boot loader 到根目录所在的文件系统的引导扇区(boot sector上。如果我们在一主机上面安装 Windows 与 Linux 后,该 引导扇区(boot sector, boot loader 与 主引导分区(MBR 关系会有点像下图1

http://s12/mw690/003E0ziMty71l8wCpflab&690

图1 Boot sector与操作系统的关系

 

如上图所示,每个操作系统默认是会安装一套 boot loader 到自己的文件系统中 (就是每个 filesystem 左下角的方框),而在 Linux 系统安装时,你可以选择将引导扇区(boot sector安装到主引导分区(MBR 去,也可以选择不安装。如果选择安装到 MBR 的话,那理论上你在主引导分区(MBR)和引导扇区(boot sector 都会保有一份 boot loader 程序的。 至于Windows 安装时,默认会主动的将主引导分区(MBR 引导扇区(boot sector 都装上一份 boot loader所以,你会发现安装多操作系统时,你的 MBR 常常会被不同的操作系统的 boot loader 所覆盖

到这里,我们刚刚提到的两个问题还是没有解决啊!虽然各个操作系统都可以安装一份 boot loader 到他们的引导扇区(boot sector中,这样操作系统可以通过自己的 boot loader 来加载内核文件了。问题是系统的主引导分区(MBR只有一个!你要怎么运行 引导扇区(boot sector里面的 boot loader 啊?这里就得说一下boot loader的功能了。boot loader 主要的功能如下:

·  提供菜单用户可以选择不同的启动选项(Windows OR Linux,这也是多重引导的重要功能

·  加载内核文件直接指向可启动的程序区段来开始操作系统;

·  转交其他 loader引导装载功能转交给其他 boot loader 负责。

由于具有菜单功能,因此我们可以选择不同的内核来启动。而由于具有控制权转交的功能,因此我们可以加载其他引导扇区(boot sector内的 boot loader 啦!不过 Windows 的 boot loader 默认不具有控制权转交的功能,因此不能使用 Windows 的 boot loader 来加载 Linux 的 loader!这也是在装多系统时,会特别强调先装 Windows 再装 Linux 的缘故。 我们将上述的三个功能下图2来解释你就看的懂了

http://s9/mw690/003E0ziMty71l8zowv638&690

2引导装载程序的菜单功能与控制权转交功能示意图

上图中,MBR 使用 Linux 的 grub 这个引导装载程序,并且里面假设已经有了三个菜单,第一个菜单可以直接指向 Linux 的内核文件并且直接加载内核来启动;第二个菜单可以将引导装载程序控制权交给 Windows 来管理,此时 Windows 的 boot loader 会接管启动流程,这个时候就能够启动 windows 了。第三个菜单则是使用 Linux 在 boot sector 内的引导装载程序,此时就会跳出另一个 grub 的菜单啦

·  而最终 boot loader 的功能就是加载 kernel(内核)文件

·  加载内核检测硬件与 initrd 的功能

当我们通过 boot loader 的管理而开始读取内核文件后,接下来, Linux 就会将内核解压缩到内存当中,并且利用核心的功能,开始测试与驱动各个周边设备,包括储存设备、CPU、网卡、声卡等等。此时 Linux 内核会以自己的功能重新检测一次硬件,而不一定会使用 BIOS 检测到的硬件信息喔!也就是说,内核此时才开始接管 BIOS 后的工作了。 那么内核文件在哪里啊?一般来说,会被放置到 /boot 里面,并且取名为 /boot/vmlinuz

[root@localhost ~]# ls --format=single-column -F /boot

config-2.6.32-431.el6.x86_64        <==此版本内核被编译时选择的功能与模块配置文件

grub/                                <==就是引导装载程序grub相关数据目录

initrd-2.6.32-431.el6.x86_64kdump.img<==虚拟文件系统文件

System.map-2.6.32-431.el6.x86_64     <==内核功能放置到内存地址的对应表

vmlinuz-2.6.32-431.el6.x86_64*       <==内核文件,尤其重要

从上我们也可以知道此版本的 Linux 内核2.6.32-431.el6.x86_64这个版本!为了硬件开发商与其他内核功能开发者的便利,因此 Linux 内核是可以通过动态加载内核模块的 (就请想成驱动程序即可),这些内核模块就放置在 /lib/modules/ 目录内。 由于模块放置到磁盘根目录内 (要记得 /lib 不可以与 / 分别放在不同的分区),因此在启动的过程中内核必须要挂载根目录,这样才能够读取内核模块提供加载驱动程序的功能。而且为了避免影响到磁盘内的文件系统,因此启动过程中根目录是以只读的方式来挂载。

一般来说,非必要的功能且可以编译成为模块的内核功能,目前的 Linux distributions 都会将编译成为模块。因此 U盘, SATA, SCSI... 等磁盘设备的驱动程序通常都是以模块的方式来存在的。现在来思考一种情况,假设你的 linux 是安装在 SATA 磁盘上面的,你可以通过 BIOS 的 INT 13 取得 boot loader 与 kernel 文件来启动,然后 kernel 会开始接管系统并且检测硬件及尝试挂载根目录来取得额外的驱动程序。

问题是,内核根本不认识 SATA 磁盘,所以需要加载 SATA 磁盘的驱动程序,否则根本就无法挂载根目录。但是 SATA 的驱动程序在 /lib/modules 内,你根本无法挂载根目录又怎么读取到 /lib/modules/ 内的驱动程序?是吧!是不是有点进退两难?在这个情况之下,你的 Linux 是无法顺利启动的! 那怎办?没关系,我们可以透过虚拟文件系统来处理这个问题。

虚拟文件系统 (Initial RAM Disk) 一般使用的文件名为 /boot/initrd ,这个文件的特色是,能够通过boot loader 来加载到内存中, 然后这个文件会被解压缩并且在内存当中仿真成一个根目录,且此仿真在内存当中的文件系统能够提供一执行的程序,过该程序来加载启动过程中所最需要的内核模块,通常这些模块就是 U盘, RAID, LVM, SCSI 等文件系统与磁盘接口的驱动程序载入完成后,会帮助内核重新调用 /sbin/init 来开始后续的正常启动流程,如图 3:

http://s10/mw690/003E0ziMty71l8BWmO5b9&690

3 BIOS与boot loader及内核加载流程示意图

如上图3所示,boot loader 可以加载 kernel 与 initrd ,然后在内存中让 initrd 解压缩成为根目录, kernel 就能够借此加载适当的驱动程序,最终释放虚拟文件系统,并挂载实际的根目录文件系统,就能够开始后续的正常启动流程。更详细的 initrd 说明,你可以自行使用 man initrd 去查阅看看。 下面来看一下 CentOS 6.x 的 initrd 文件内容有什么吧!

http://s8/mw690/003E0ziMty71l8EXI6ra7&690

[root@localhost initrd]# cpio -ivcdu < initrd-2.6.32-431.el6.x86_64kdump命令对其进行解压缩,解压完毕后看看 initrd-2.6.32-431.el6.x86_64kdump目录有什么东西:

http://s16/mw690/003E0ziMty71l8H70iraf&690看!是不是很像根目录?接下来用vim init来这个文件看看都有些什么内容:

mount -t proc /proc /proc         <==挂载内存的虚拟文件系统

.....(中间省略).....

echo Creating initial device nodes <==新建系统所需的各项设备

mknod /dev/null c 1 3

.....(中间省略).....

echo "Loading dm-mod.ko module"    <==加载各项内核模块,就是驱动程序

insmod /lib/modules/2.6.32-431.el6.x86_64/dm-mod.ko

.....(中间省略).....

通过上述执行文件的内容,我们可以知道 initrd 有加载模块并且尝试挂载了虚拟文件系统。 接下来就能够顺利的运行啦!那么是否一定需要 initrd 呢?

不一定的,需要 initrd 最重要的原因是,当启动时无法挂载根目录的情况下,此时就一定需要 initrd ,例如你的根目录在特殊的磁盘介面 (U盘, SATA, SCSI) ,或者是你的文件系统较为特殊 (LVM, RAID) 等等,才会需要 initrd。
如果你的 Linux 是安装在 IDE 接口磁盘上,并且使用默认的 ext2/ext3 文件系统,那么不需要 initrd 也能够顺利的启动进入 Linux 的!

内核完整的加载后,您的主机应该就开始正确的运行了,接下来,就是要开始运行系统的第一支程序:/sbin/init。 

1.2、第一个进程 init 及配置文件 /etc/inittab 与 runlevel

内核加载完毕、进行完硬件检测与驱动程序加载后,此时你的主机硬件应该已经准备就绪了 (ready) ,此时内核会主动的调用第一个进程,那就是 /sbin/init。这也是为啥使用 top、ps、pstree等命令时,你会发现 init 的 PID 号码是一号啦。/sbin/init最主要的功能就是准备软件执行的环境,包括系统的主机名称、网络配置、语系处理、文件系统格式及其他服务的启动等。而所有的操作会通过init 的配置文件,即是 /etc/inittab 来规划,而 inittab 内还有一个很重要的配置选项,那就是默认的 runlevel (启动运行等级)

 1.2.1 run revel:执行等级

那么什么是 run level 呢?有什么功用?其实很简单, Linux 就是通过设置 run level 来规定系统使用不同的服务来启动,让 Linux 的使用环境不同。基本上,依据有无网络与有无 X Window 而将 run level 分为 7 个等级,分别是:

   ·0 - halt (系统直接关机)

   ·1 - single user mode (单人维护模式,用在系统出问题时的维护,类似Windows的安全模式)

   ·2 - Multi-user, without NFS (类似下面的 runlevel 3,但无 NFS 服务)

   ·3 - Full multi-user mode (完整含有网络功能的纯文本模式)

   ·4 - unused (系统保留功能)

   ·5 - X11 (与 runlevel 3 类似,但加载使用 X Window)

   ·6 - reboot (重新启动)

由于 run level 0, 4, 6 不是关机、重新启动就是系统保留的,所以当然不能将默认的 run level 设置为这三个值,否则系统就会不断的自动关机或自动重新启动.... 好了,那么我们启动时,到底是如何取得系统的 run level 的?当然是 /etc/inittab 所设置。 那么 /etc/inittab 这个文件到底有什么呢内容下面先来看看这个文件的内容:

http://s9/mw690/003E0ziMty71l8Kh1lm48&690

现在会自行修改登陆时的默认 run level 设置值了吗?够简单的吧?一般来说,我们默认都是 3 或者是 5 来作为默认的 run level 的。但有时后可能需要进入 run level 1,也就是单用户维护模式的环境当中。这个 run level 1 有点像是 Windows 系统当中的安全模式,专门用来处理当系统有问题时的操作环境。此外,当系统发现有问题时,比如不正常关机造成 filesystem 的不一致现象时,系统会主动的进入单用户维护模式

好了, init 在取得 run level 之后,接下来要干嘛? 那就是通过/etc/rc.d/rc.sysinit这个文件来初始化整个系统了。

1、3 init处理系统初始化流程(/etc/rc.d/rc.sysinit)

系统根据/ect/inittab文件获取到运行级别后,就会执行/etc/rc.d/rc.sysinit这个shell脚本来设置好整个系统的环境,如果用vim /etc/rc.d/rc.sysinit来打开这个文件的话,可以发现这个文件的主要工作有以下这些:

1、取得网络环境与主机类型
读取网络配置文件 /etc/sysconfig/network ,取得主机名称与默认网关 (gateway) 等网络环境。

2、试与挂载内存设备 /proc U 设备 /sys
除挂载内存设备 /proc 之外,还会主动检测系统上是否具有 usb 设备,若有则会主动加载 usb 的驱动程序,并且尝试挂载 usb 的文件系统。

3、决定是否启动 SELinux
SELinux 在此时进行一些检测, 并且检测是否需要帮所有的文件重新编写标准的 SELinux 类型 (autorelabel)

4、启动系统的随机数产生器
随机数产生器可以帮助系统进行一些口令加密演算的功能,在此需要启动两次随机数产生器。

5、配置终端机 (console) 字体。 

6、配置显示启动过程中的欢迎界面 (text banner) 

7、配置系统时间 (clock) 与时区配置:需读入 /etc/sysconfig/clock 置值 

8、接口设备的检测Plug and Play (PnP) 参数的测试
根据内核在启动时检测的结果 (/proc/sys/kernel/modprobe ) 开始进行 ide / scsi / 网络 / 音效 等周边设备的检测,以及利用以加载的内核模块进行 PnP 设备的参数测试

9、用户自定义模块的加载
用户可以在 /etc/sysconfig/modules/*.modules 加入自定义的模块,则此时会被加载到系统当中 

10、加载内核的相关配置
系统会主动去读取 /etc/sysctl.conf 这个文件的设置值,使核心功能成为我们想要的样子

11、配置主机名称与初始化电源管理模块 (ACPI)

12、初始化软件磁盘阵列:主要是通过 /etc/mdadm.conf 来配置好的。

13、初始化 LVM 的文件系统功能 

14、fsck 检验磁盘文件系统:会进行 filesystem check 

15、进行磁盘配额 quota 的转换 (非必要) 

16、重新以可读写模式挂载系统磁盘。 

17、启动 quota 功能:所以我们不需要自定义 quotaon 操作。 

18、启动系统虚拟随机数产生器 (pseudo-random) 

19、清除启动过程当中的缓存文件

20、将启动相关信息加载 /var/log/dmesg 文件中

在 /etc/rc.d/rc.sysinit 将基本的系统配置数据都写好了,也将系统的数据配置完整!而如果你想要知道到底启动的过程中发生了什么事情呢?那么就运行dmesg ”命令来查看吧。另外,基本上,在这个文件当中所进行的很多工作的默认配置文件其实都在 /etc/sysconfig/ 当中 所以,请记得将 /etc/sysconfig/ 目录下的文件好好的瞧一瞧哈!

在这个过程当中,比较值得注意的是自定义模块的加载!在 CentOS 当中,如果我们想要加载内核模块的话,可以将整个模块写入/etc/sysconfig/modules/*.modules 当中,在该目录下,只要记得文件名最后是以 .modules 结尾即可。 这个过程是非必要的,因为我们目前的默认模块实在已经很够用了,除非是的主机硬件实在太新了,非要自己加载新的模块不可,否则,在经过 /etc/rc.d/rc.sysinit 的处理后,你的主机系统应该是已经跑得很顺畅了就等著你将系统相关的服务与网络服务启动了。

 

1、4启动系统服务与相关启动配置文件(/etc/rc.d/rc N & /etc/sysconfig)

加载内核让整个系统准备接受命令来工作,经过 /etc/rc.d/rc.sysinit 的系统模块与相关硬件信息的初始化后,你的 CentOS 系统应该已经顺利工作了。只是,我们还得要启动系统所需要的各项服务啊!这样主机才能提供我们相关的网络或者是主机功能这个时候,依据我们在 /etc/inittab 里面提到的 run level 置值,就可以来决定启动的服务选项了。举例来说,使用 run level 3 当然就不需要启动 X Window 的相关服务吧?

那么各个不同的 run level 服务启动的各个 shell script 放在哪?请看下图:

http://s6/mw690/003E0ziMty71l8MqHL705&690

run level 0-run level 6分别对应rc0.d-rc6.d目录。

由于我的系统的默认run level为3,所以就以rc3.d目录进行讲解好了。/etc/rc.d/rc 3 的意义是这样的 (建议您自行使用 vim 去观察一下 /etc/rc.d/rc 这个文件,你会更有概念!):

·  通过外部第一号参数 ($1) 来取得想要运行的脚本目录。亦即由 /etc/rc.d/rc 可以取得 /etc/rc3.d/ 这个目录来准备处理相关的脚本程序;

·  找到 /etc/rc3.d/K??* 开头的文件,并进行/etc/rc3.d/K??* stop”操作

·  找到 /etc/rc3.d/S??* 开头的文件,并进行/etc/rc3.d/S??* start操作

通过上面的说明我们可以知道所有的选项都与 /etc/rc3.d/ 有关,那么我们就来瞧瞧这个目录下有些什么玩意儿吧!

http://s16/mw690/003E0ziMty71l8Qdsab7f&690

这是/etc/rc3.d/目录下的文件,通过命令:ll /etc/rc3.d查看一下会更详细,如图:

http://s15/mw690/003E0ziMty71l8U7s067e&690

 

在这个目录下的文件很有趣,主要具有几个特点:

文件全部以 Sxx 或 Kxx ,其中 xx 为数字,且这些数字在文件之间是有相关性的!

全部是连接文件连接到服务启动目录 /etc/init.d/ 去

我们知道服务的启动主要是以/etc/init.d 服务名称 {start,stop} 来启动与关闭的,那么通过刚刚 /etc/rc.d/rc 程序的解说,我们可以清楚的了解到了 /etc/rc3.d/[SK]xx 其实就是跑到 /etc/init.d/ 去找到相对应的服务脚本, 然后分别进行 start (Sxx) 或 stop (Kxx) 的操作而已举例来说,以命令:ll rc3.d查看的文件中 K91capi 及 S10network 为例好了, 通过 /etc/rc.d/rc 的运行,这两个文件会这样进行:

·  /etc/rc3.d/K91capi stop --> /etc/init.d/capi stop

·  /etc/rc3.d/S10network start --> /etc/init.d/network start

由此可见你有想要启动该 runlevel 时就运行的服务,那么利用 Sxx 并指向 /etc/init.d/ 的特定服务启动脚本后,该服务就能够在启动时启动就这么简单!问题是,你需要自行处理这个 K, S 开头的连接文件吗?并不需要的,chkconfig(如:chkconfig httpd on #将httpd服务设置为开机启动)命令就是在负责处理这个连接文件啦!

那么为什么 K 与 S 后面要有数字呢?因为各不同的服务其实还是相互有关系的。举例来说,如果要启动 WWW 服务,总是得要有网络吧?所以 /etc/init.d/network 就会比较先被启动那么就会知道在 S 或者是 K 后面接的数字是啥意思了吧?嘿嘿,那就是服务的执行顺序啦!那么哪个文件被最后运行呢?看到最后一个被运行的选项是啥?没错,就是 S99local ,亦即是: /etc/rc.d/rc.local 这个文件啦!

1、5用户自定义开机启动程序(/etc/rc.d/rc.local)

在完成默认 runlevel 指定的各项服务的启动后,如果我还有其操作想要完成时,举例来说,我还想要一封 mail 给某个系统管理帐号,通知他,系统刚刚重新启动完毕,那么是否应该要制作一个 shell script 放置在 /etc/init.d/ 里面,然后再以连接方式连到 /etc/rc3.d/ 里面呢?呵呵!当然不需要!可以在 /etc/rc.d/rc.local文件中添加你想要开机启动的程序 

也就是说,我有任何想要在启动时就进行的工作时,直接将写入 /etc/rc.d/rc.local文件中 ,那么该工作就会在启动的时候自动被加载而不必等我们登陆系统去启动 不是很方便啊!

1、6 加载终端机或 X-Window 界面

在完成了系统所有服务的启动后,接下来 Linux 就会启动终端或者是 X-Window 来等待用户登陆Linux系统默认是打开6个终端的,分别可以用ALT+F1到ALT+F6进行访问,6终端默认都驻留在内存中,一般我们Linux 服务器都是通过远程登录,就算是本地登录,也只用到2个左右,其他可以关闭以节省内存。那么如何关闭这些默认开着的终端呢?CentOS 5之前的版本,可以修改/etc/inittab文件,加#注释掉你不想要的终端即可;但是在 CentOS 6以后的版本中,修改方法略有不同,终端TTY的配置由之前CentOS 5版本的/etc/inittab文件更改为/etc/init/start-ttys.conf,执行以下命令可以将默认的6个TTY终端更改为3个,找到“tty[1-6]”改为“tty[1-3]”,如图:

http://s14/mw690/003E0ziMty71l8WppRHfd&690

保存退出,重启系统即可生效。

关于X-Window的启动流程建议大家自行学习,在这里就不再详述。

1、7 Run level的切换

在我们完成上面的所有信息后,其实整个 Linux 主机就已经在等待我们用户的登陆了。 但是,相信大家应该还是会有一点疑问的地方,那就是:我该如何切换 run level 呢?会不会很难啊?其实很简单的,但是依据运行的时间而有不同的方式啊!

事实上,与 run level 有关的启动其实是在 /etc/rc.d/rc.sysinit 运行完毕之后。也就是说,其实 run level 的不同仅是 /etc/rc[0-6].d 里面启动的服务不同而已。不过,依据启动是否自动进入不同 run level 的设置,我们可以得出以下结论

1. 如果希望每次启动系统执行某个默认的 run level ,则需要修改 /etc/inittab 内的设置选项,即是id:3:initdefault:”里面的数字;

2. 如果希望只是暂时变更系统的 run level 时,则使用 init [0-6] 来进行 run level 的切换。但下次重新启动时,依旧会是以 /etc/inittab 的配置为准。

假设原本我们是以 run level 3 登陆系统的,但是因为某些因素,想要切换成为 run level 5 时,该怎么办呢?很简单啊,运行 init 5 即可切换。但是 init 5 这个操作到底做了什么呢?我们不是说了吗?事实上,不同的 run level 只是加载的服务不同罢了, 亦即是 /etc/rc3.d/ 还有 /etc/rc5.d 内的 Sxxname 与 Kxxname 有差异而已。 所以说,当运行 init 5 时,系统会:

· 先比对 /etc/rc5.d/ 及 /etc/rc3.d 内的 K 与 S 开头的文件;

· 在新的 runlevel 亦即是 /etc/rc5.d/ 内有多的 K 开头文件,则予以关闭;

· 在新的 runlevel 亦即是 /etc/rc5.d/ 内有多的 S 开头文件,则予以启动;

也就是说,两个 run level 都存在的服务就不会被关闭如此一来,就很容易切换 run level 了, 而且还不需要重新启动牛掰。那我怎么查看目前系统的runlevel及如何切换runlevel呢? 参考下图:

http://s1/mw690/003E0ziMty71l8YlcU8a0&690

查看及切换runlevel

到此为止,Linux的整个启动流程就结束啦,接下来就是用户的操作了,想干啥就干点啥吧!

说了这么多,总结一下:本文从主机的BIOS、boot loader、kernel的加载开始;到第一个init进程(Linux系统下所有进程的父进程)及配置文件/etc/inittab与runlevel,在这个小节介绍了系统调用init来准备软件执行的环境,并介绍各个runlevel的具体含义;接着介绍init处理系统初始化的相关流程(主要执行/etc/rc.d/rc.sysinit文件来实现);然后介绍了启动系统服务与相关启动配置文件(/etc/rc.d/rc N & /etc/sysconfig);再到用户如何实现自定义开机启动程序(主要通过修改/etc/rc.d/rc.local文件来实现)以及如何修改系统默认设置的tty终端数量(通过修改/etc/init/start-ttys.conf文件实现);最后介绍了在进行Run level切换时,相应的/etc/rc.d/rcN.d目录内文件的启动及关闭操作之间的关系。












0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有