Linux之服务器基本启动步骤

Linux 启动的基本步骤

要完整讲述Linux 的启动过程,需要追溯到按下电源开关的那一刻。

1、PC 引导的第一步是执行存储在ROM(只读存储器)中代码,这种引导代码通常被称为BIOS(基本输入输出系统,Basic Input/Ouput System)。

2、BIOS 知道和引导有关的硬件设备的信息,包括磁盘、键盘、串行口、并行口等,并根据设置选择从哪一个设备引导。

3、确定引导设备后(通常是第一块硬盘),计算机就尝试加载该设备开头512 个字节的信息,包含这512 个字节的段被称作MBR(Master Boot Record,主引导记录)。MBR 的主要任务是告诉计算机从什么地方加载下一个引导程序,“下一个”引导程序被称为“引导加载器(Boot Loader)”。

4、引导加载器负责加载操作系统的内核,Grub 和LILO 就是Linux上最著名的两个引导加载器。


接下来发生的事情就随操作系统的不同而不同了。对于Linux 而言,基本的引导步骤
包括以下几个阶段。
(1)加载并初始化Linux 内核。
(2)配置硬件设备。
(3)内核创建自发进程。
(4)由用户决定是否进入手工引导模式。
(5)(由init 进程)执行系统启动脚本。

(6)进入多用户模式。


    可见,Linux 内核总是第一个被加载的东西。内核执行包括硬件检测在内的一切基础操作,然后创建几个进程。这些内核级别的进程被称做“自发”进程。最重要的init 进程就是在这个阶段创建的。

    事情到这里还没有完。内核创建的进程只能执行最基本的硬件操作和调度,而那些执行用户级操作的进程(诸如接受登录)还没有创建。这些任务最后都被内核“下放”给init进程来完成,因此,init 进程是系统上除了几个内核自发进程之外所有进程的祖先。


 init 和运行级

    init 定义了一些被称做“运行级”的东西,这里的“级”是级别的意思,用一些整数表示。进入某一个运行级意味着使用某种特定的系统资源组合。“系统资源”是一个很宽泛的概念,由于几乎所有的进程都是由init 创建的,因此理论上可以完全控制在某个运行级下应该运行哪些进程。从某种意义上,init 的运行级有点快餐店里“套餐”的味道,顾客可以说“来一份1 号套餐”,于是服务员就端上汉堡、薯条和可乐。


Linux 的init 进程总共支持10 个运行级,但实际定义的运行级只有7 个。表22.1 显示了这些运行级及其对应的系统状态。表 22.1 运行级及其对应的系统状态运 行 级 系 统 状 态

0 系统关闭
1 或S 单用户模式
2 功能受限的多用户模式
3 完整的多用户模式
4 一般不用,留作用户自己定义
5 多用户模式,运行X 窗口系统

6 重新启动


    目前绝大部分的Linux 发行版本默认都启动计算机至运行级5,也就是带有X 窗口系统的多用户模式。服务器通常不需要运行X,因此常常被设置进入运行级3。运行级4 被保留,方便管理员根据实际情况定义特殊的系统状态。

    单用户模式是关于系统救援的。在这个运行级下,所有的多用户进程都被关闭,系统保留最小软件组合。引导系统进入单用户模式后,系统会要求用户以root 身份登录到系统中。在2.4 节提到的“救援模式”就是典型的单用户模式。

    0 和6 是两个比较特殊的运行级,系统实际上并不能停留在这两个运行级中。进入这两个运行级别意味着关机和重启。使用telinit 命令可以强制系统进入某个运行级。运行下面这条命令后,系统就进入运行级6,也就是关闭计算机,然后再启动。


sudo telinit 6


尽管表22.1 明确地列出了所有7 个运行级代表的系统状态,但事实上这只代表了大部分系统的习惯做法。在某一台特定的计算机上,管理员可能会根据实际情况调整配置:例如让运行级3 也能启动X 窗口系统。init 的配置文件是/etc/inittab,这个文件中定义了每个运行级上需要做的事情。下面是opensuse Linux 中inittab 文件的一部分。

# runlevel 0 is System halt (Do not use this for initdefault!)

# runlevel 1 is Single user mode

# runlevel 2 is Local multiuser without remote network (e.g. NFS)
# runlevel 3 is Full multiuser with network
# runlevel 4 is Not used
# runlevel 5 is Full multiuser with network and xdm
# runlevel 6 is System reboot (Do not use this for initdefault!)
#
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
#l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5

l6:6:wait:/etc/init.d/rc 6


    以“#”开头的行是注释行,紧跟在后面的这些行定义了在每个运行级下应该做的事情。inittab 文件通常并不会一一列出所有应该执行的脚本,而是调用rc 脚本(通常是/etc/init.d/rc)改变运行级。rc 脚本随后根据传给它的参数查找与运行级有关的目录,并执行其中的脚本。
    这些“与运行级有关”的目录总是以rclevel.d 的形式出现,其中level 就是运行级编号。例如所有要在运行级1 下执行的脚本都保存在rc1.d 目录下,而为了进入运行级3,那么就执行位于rc3.d 目录下的脚本。通常,这些目录不是在/etc 目录下,就是在/etc/init.d 目录下。


$ ls -d /etc/rc* ##列出/etc 目录下所有以rc 开头的目录
/etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rc3.d /etc/rc4.d /etc/rc5.d
/etc/rc6.d /etc/rcS.d


    很显然,为了改变某个运行级所使用的系统资源组合,可以在这些目录下添加/删除相应的脚本。rclevel.d 目录下的脚本文件有自己一套独特的命名和实现方法,将在22.1.3 节讨论。很容易改变 Linux 的默认运行级。在/etc/inittab 文件中找到下面这一行:

id:5:initdefault:

    这一行设置将Linux 默认启动到运行级5。如果要让Linux 默认启动到运行级3,可以把它改成下面这样:
id:3:initdefault:

服务器启动脚本

    用于启动服务器应用程序(更确切地说是服务器守护进程)的脚本全部位于/etc/init.d目录下,每个脚本控制一个特定的守护进程(这个概念将在22.2.1 节具体介绍)。所有的脚本都应该认识start 和stop 参数,分别表示启动和停止服务器守护进程。下面这条命令启动了SSH 服务器的守护进程。

$ sudo /etc/init.d/sshd start
Starting SSH daemon done

    与此相对的,下面这条命令停止 SSH 服务器的守护进程。

$ sudo /etc/init.d/sshd stop
Shutting down SSH daemon done

    大部分启动脚本还认识restart 参数。顾名思义,接收到这个参数的脚本首先关闭服务器守护进程,然后再启动它。

$ sudo /etc/init.d/sshd restart
Shutting down SSH daemon done
Starting SSH daemon done

   在改变运行级(包括系统启动和关闭)的时候,系统执行的是rclevel.d 目录下的脚本文件。仍然以SSH 为例,使用ls -l 命令可以清楚地看到init.d 和rclevel.d 这两个目录下脚本文件之间的关系。

$ ls -l /etc/init.d/rc5.d/ | grep sshd
lrwxrwxrwx 1 root root 7 11-09 17:55 K12sshd -> ../sshd
lrwxrwxrwx 1 root root 7 11-09 17:55 S10sshd -> ../sshd

   /etc/init.d/rc5.d 目录下的两个脚本文件K12sshd 和S10sshd , 实际上都是指向/etc/init.d/sshd 的符号链接。init 在执行脚本的时候,会给以字母S 开头的脚本文件传递start参数,而给以字母K 开头的脚本文件传递stop 参数。例如init 运行K12sshd 时,实际执行的是下面这条命令。

/etc/init.d/rc5.d/K12sshd stop

   由于 K12sshd 脚本是/etc/init.d/sshd 的符号链接,因此又等价于下面这条命令。

/etc/init.d/sshd stop

   脚本文件名中的数字描述了脚本运行的先后顺序,数字较小的脚本首先被执行。下面的例子反映了这一点。当进入运行级5的时候,S05network 在S10sshd 之前执行(因为5<10);类似地,当退出运行级5 的时候,K12sshd 在K17network 之前执行(因为12<17)。

$ ls -l /etc/init.d/rc5.d/ | egrep 'ssh|network'
lrwxrwxrwx 1 root root 7 11-09 17:55 K12sshd -> ../sshd
lrwxrwxrwx 1 root root 10 11-09 17:50 K17network -> ../network
lrwxrwxrwx 1 root root 10 11-09 17:50 S05network -> ../network
lrwxrwxrwx 1 root root 7 11-09 17:55 S10sshd -> ../sshd

   这样安排的用意很明显,供远程登录使用的SSH 服务器不应该在网络接口启动之前运行。在向rclevel.d 目录下手动添加脚本的时候应该格外注意这些依赖关系。下面列出了在笔者的openSUSE 系统上启动服务器脚本的顺序。

$ ls -l /etc/init.d/rc5.d/
...
lrwxrwxrwx 1 root root 8 11-09 17:50 S01acpid -> ../acpid
lrwxrwxrwx 1 root root 7 11-09 17:50 S01dbus -> ../dbus
lrwxrwxrwx 1 root root 14 11-09 17:50 S01earlysyslog -> ../earlysyslog
lrwxrwxrwx 1 root root 8 11-09 17:50 S01fbset -> ../fbset
lrwxrwxrwx 1 root root 16 11-09 17:50 S01microcode.ctl -> ../microcode.
ctl
lrwxrwxrwx 1 root root 9 11-09 17:50 S01random -> ../random
lrwxrwxrwx 1 root root 9 11-09 17:50 S01resmgr -> ../resmgr
lrwxrwxrwx 1 root root 21 11-09 18:10 S01SuSEfirewall2_init -> ../SuSEfirewall2_
init
lrwxrwxrwx 1 root root 13 11-09 17:50 S02consolekit -> ../consolekit
lrwxrwxrwx 1 root root 12 11-09 17:50 S03haldaemon -> ../haldaemon
lrwxrwxrwx 1 root root 11 11-09 17:50 S04earlyxdm -> ../earlyxdm
lrwxrwxrwx 1 root root 10 11-09 17:50 S05network -> ../network

lrwxrwxrwx 1 root root 9 11-09 17:50 S06syslog -> ../syslog
lrwxrwxrwx 1 root root 9 11-09 17:55 S07auditd -> ../auditd
lrwxrwxrwx 1 root root 10 11-09 17:55 S07portmap -> ../portmap
lrwxrwxrwx 1 root root 8 11-27 13:06 S07smbfs -> ../smbfs
lrwxrwxrwx 1 root root 15 11-09 17:55 S07splash_early -> ../splash_early
lrwxrwxrwx 1 root root 12 11-09 17:55 S10alsasound -> ../alsasound
lrwxrwxrwx 1 root root 15 11-09 17:55 S10avahi-daemon -> ../avahi-daemon
lrwxrwxrwx 1 root root 7 11-09 17:55 S10cups -> ../cups
lrwxrwxrwx 1 root root 19 11-09 17:55 S10java.binfmt_misc -> ../java.
binfmt_misc
lrwxrwxrwx 1 root root 6 11-09 17:55 S10kbd -> ../kbd
lrwxrwxrwx 1 root root 7 11-09 17:55 S10nscd -> ../nscd
lrwxrwxrwx 1 root root 13 11-09 17:56 S10powersaved -> ../powersaved
lrwxrwxrwx 1 root root 9 11-09 17:55 S10splash -> ../splash
lrwxrwxrwx 1 root root 7 11-09 17:55 S10sshd -> ../sshd
lrwxrwxrwx 1 root root 15 11-09 17:56 S10vmware-guest -> ../vmware-guest
lrwxrwxrwx 1 root root 17 11-09 17:55 S11avahi-dnsconfd -> ../avahidnsconfd
lrwxrwxrwx 1 root root 12 12-21 05:25 S11nfsserver -> ../nfsserver
lrwxrwxrwx 1 root root 10 11-09 17:55 S11postfix -> ../postfix
lrwxrwxrwx 1 root root 6 11-09 17:55 S11xdm -> ../xdm
lrwxrwxrwx 1 root root 7 11-09 17:55 S12cron -> ../cron
lrwxrwxrwx 1 root root 9 11-09 17:57 S12smartd -> ../smartd
lrwxrwxrwx 1 root root 9 11-09 14:15 S12xinetd -> ../xinetd
lrwxrwxrwx 1 root root 15 11-09 17:50 S21stopblktrace -> ../stopblktrace
lrwxrwxrwx 1 root root 22 11-09 18:10 S21SuSEfirewall2_setup -> ../SuSEfirewall2_
setup

Ubuntu 和Debian 的init 配置

   Ubuntu 和Debian 的启动配置有一点特殊,这两个发行版使用upstart 而不是init 来管理启动脚本。在默认情况下, Ubuntu 和Debian 没有inittab 文件, 而是使用/etc/event.d/rc-default 来确定启动的默认运行级。但奇怪的是,rc-default 脚本依然会试图寻找/etc/inittab。如果找到了,它就按照inittab 文件的配置来设置运行级;如果没有找到,它就把系统启动到运行级2。

   这又和人们的常识不太一样,为什么是运行级2 而不是5?Debian 的FAQ(常见问题)回答了这个问题,如表 所示。

运行级 系统状态
0 关闭系统
1 单用户模式
2~5 完整的多用户
6 重新启动

    也就是说,Ubuntu 和Debian 默认情况下并没有区分运行级2~5。这意味着用户必须手动定制每个运行级应该包含的启动脚本。举例来说,如果想要启动到不包含图形界面的多用户模式,应该依次执行下面这些步骤。
(1)选择一个运行级来完成这个任务,假设是运行级3。
(2)新建/etc/inittab,内容为“id:3:initdefault:”。

(3)把/etc/rc3.d/S30gdm(KDE 是S30kdm)移动到其他地方备份起来。
(4)重新启动系统。

    当然,如果愿意使用运行级4 或5 来表示“不包含图形界面的多用户模式”也没有问题,只是不太符合习惯。

注意:S30gdm(S30kdm)中字母S 后紧跟的数字随系统实际安装的软件不同而不同。









你可能感兴趣的:(Linux,Basic)