随着Linux的应用日益广泛。特别是在网络应用方面,有大量的网络server使用Linux操作系统。因为Linux的桌面应用和Windows相比另一 定的差距。所以在企业应用中往往是Linux和Windows操作系统共存形成异构网络。在server端大多使用Linux和Unix的,眼下Linux的擅 长应用领域是单一应用的基础server应用,譬如DNS和DHCPserver、Webserver、文件夹server、防火墙、文件和打印server、Intranet代理server 。启动 Linux 系统的过程包含非常多阶段。无论您是引导一个标准的 x86 处理器。还是PowerPC 机器,非常多流程都惊人地相似。本文将描写叙述了从开机到登录的 Linux 启动全过程。
(1) 从BIOS到内核
BIOS自检
计算机在接通电源之后首先由BIOS进行自检,即进行所谓的POST(Power On Self
Test),然后根据BIOS内设置的引导顺序从硬盘、软盘或CDROM中读入“引导块”。 在 PC 中。引导 Linux 是从 BIOS 中的地址 0xFFFF0 处開始的。BIOS 的第一个步骤是加电自检(POST)。POST 的工作是对硬件进行检測。
BIOS 的第二个步骤是进行本地设备的枚举和初始化。给定 BIOS 功能的不同使用方法之后。BIOS 由两部分组成:POST 代码和执行时服务。当 POST 完毕之后。它被从内存中清理了出来,可是 BIOS 执行时服务依旧保留在内存中,目标操作系统能够使用这些服务。
要引导一个操作系统,BIOS 执行时会依照 CMOS 的设置定义的顺序来搜索处于活动状态而且能够引导的设备。
引导设备能够是软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备,甚至是 USB 闪存。通常,Linux 都是从硬盘上引导的,当中主引导记录(MBR)中包括主引导载入程序。
MBR 是一个 512 字节大小的扇区,位于磁盘上的第一个扇区中(0 道 0 柱面 1 扇区)。
当 MBR 被载入到 RAM 中之后,BIOS 就会将控制权交给 MBR。
提取 MBR 的信息
要查看 MBR 的内容,请使用以下的命令:
# dd if=/dev/hda of=mbr.bin bs=512 count=1 # od -xa mbr.bin
这个 dd 命令须要以 root 用户的身份执行,它从 /dev/hda(第一个 IDE 盘) 上读取前 512 个字节的内容,并将其写入 mbr.bin 文件里。od 命令会以十六进制和 ASCII 码格式打印这个二进制文件的内容。
(2)启动GRUB/LILO
GRUB和LILO都是引导载入程序。最简单地 讲。引导载入程序(boot loader) 会引导操作系统。当机器引导它的操作系统时,BIOS 会读取引导介质上最前面的 512 字节(即人们所知的 主引导记录(master boot record,MBR))。在单一的 MBR 中仅仅能存储一个操作系统的引导记录,所以当须要多个操作系统时就会出现故障。所以须要更灵活的引导载入程序。
GRUB 与 LILO 的比較
如本文開始处所述,全部引导载入程序都以类似的方式工作,满足共同的目的。只是,LILO 和 GRUB 之间有非常多不同之处:
-
LILO 没有交互式命令界面,而 GRUB 拥有。
-
LILO 不支持网络引导,而 GRUB 支持。
-
LILO 将关于能够引导的操作系统位置的信息物理上存储在 MBR 中。
假设改动了 LILO 配置文件,必须将 LILO 第一阶段引导载入程序重写到 MBR。
相对于 GRUB,这是一个更为危急的选择,由于错误配置的 MBR 可能会让系统无法引导。使用 GRUB,假设配置文件配置错误,则仅仅是默认转到 GRUB 命令行界面。
安全提示:
关于安全性,不论什么能够接触到引导磁盘/CD 的人。仅仅须要使用没有设置安全性的 grub.conf 或 lilo.conf。就能够绕过本文中提及的全部安全措施。特别是使用 GRUB 时,由于能够引导到单用户模式,所以是一个严重的安全漏洞。
解决此问题的一个简单方法是在机器的 BIOS 中禁止通过 CD 和软盘进行引导,并确保为 BIOS 设置了一个口令。使得其它人不能改动这些设置。
(3)载入内核
当内核映像被载入到内存之后,内核阶段就開始了。
内核映像并非一个可运行的内核,而是一个压缩过的内核映像。通常它是一个 zImage(压缩映像,小于 512KB)或一个 bzImage(较大的压缩映像,大于 512KB)。它是提前使用 zlib 进行压缩过的。在这个内核映像前面是一个例程。它实现少量硬件设置。并对内核映像中包括的内核进行解压。然后将其放入高端内存中,假设有初始 RAM 磁盘映像,就会将它移动到内存中。并标明以后使用。然后该例程会调用内核。并開始启动内核引导的过程。
GRUB 中的手工引导
在 GRUB 命令行中,我们能够使用 initrd 映像引导一个特定的内核。方法例如以下:
grub> kernel /bzImage-2.6.14.2
[Linux-bzImage, setup=0x1400, size=0x29672e]
grub> initrd /initrd-2.6.14.2.img
[Linux-initrd @ 0x5f13000, 0xcc199 bytes]
grub> boot
Uncompressing Linux... Ok, booting the kernel.
假设您不知道要引导的内核的名称,仅仅需使用斜线(/)然后按下 Tab 键就可以。GRUB 会显示内核和 initrd 映像列表。
(4)运行init进程
init进程是系统全部进程的起点。内核在完毕核内引导以后,即在本线程(进程)空间内载入init程序。它的进程号是1。init进程是全部进程的发起 者和控制者。
由于在不论什么基于Unix的系统(比方Linux)中。它都是第一个执行的进程,所以init进程的编号(Process ID。PID)永远是1。
假设init出现了问题,系统的其余部分也就随之而垮掉了。
init进程有两个作用。
第一个作用是扮演终结父进程的角色。由于init进程永远不会被终止,所以系统总是能够确信它的存在。并在必要的时候以它为參 照。假设某个进程在它衍生出来的所有子进程结束之前被终止,就会出现必须以init为參照的情况。
此时那些失去了父进程的子进程就都会以init作为它们 的父进程。
高速运行一下ps -af 命令,能够列出很多父进程ID(Parent Process ID,PPID)为1的进程来。
init的第二个角色是在进入某个特定的执行级别(Runlevel)时执行对应的程序,以此对各种执行级别进行管理。它的这个作用是由/etc/inittab文件定义的。
(5)通过/etc/inittab文件进行初始化
init的工作是依据/etc/inittab来运行对应的脚本进行系统初始化,如设置键盘、字体, 装载模块,设置网络,等等。
对于RedhatLinux来说,运行的顺序为:
-
/etc/rc.d/rc.sysinit # 由init运行的第一个脚本
/etc/rc.d/rc.sysinit主要做在各个执行模式中同样的初始化工作,包含:
设置初始的$PATH变量。
配置网络。
为虚拟内存启动交换。
设置系统的主机名。
检查root文件系统,以进行必要的修复。
检查root文件系统的配额。
为root文件系统打开用户和组的配额。
以读/写的方式又一次装载root文件系统。
清除被装载的文件系统表/etc/mtab。
把root文件系统输入到mtab。
使系统为装入模块做准备。
查找模块的相关文件。
检查文件系统。以进行必要的修复。
载入全部其它文件系统。
清除几个/etc文件:/etc/mtab、/etc/fastboot和/etc/nologin。
删除UUCP的lock文件。
删除过时的子系统文件。
删除过时的pid文件。
设置系统时钟。
打开交换。
初始化串行port。
装入模块。 -
/etc/rc.d/rcX.d/[KS]
首先终止“K”开头的服务,然后启动“S”开头的服务。
对每个执行级别来说,在/etc/rc.d子文件夹中都有一个相应的下级文件夹。这些执行级别的下级子文件夹的命名方法是rcX.d,当中的X就是代表执行级 别的数字。
比方说。执行级别3的所有命令脚本程序都保存在/etc/rc.d/rc3.d子文件夹中。在各个执行级别的子文件夹中,都建立有到/etc /rc.d/init.d子文件夹中命令脚本程序的符号链接。可是,这些符号链接并不使用命令脚本程序在 /etc/rc.d/init.d子文件夹中原来的名字。
假设命令脚本程序是用来启动一个服务的。其符号链接的名字就以字母S打头;假设命令脚本程序是用来 关闭一个服务的,其符号链接的名字就以字母K打头。
很多情况下,这些命令脚本程序的运行顺序都非常重要。假设没有先配置网络接口,就没有办法使用DNS服务 解析主机名!
为了安排它们的运行顺序,在字母S或者 K的后面紧跟着一个两位数字,数值小的在数值大的前面运行。比方:/etc/rc.d/rc3.d/S50inet就会在 /etc/rc.d/rc3.d/S55named之前运行。存放在/etc/rc.d/init.d子文件夹中的、被符号链接上的命令脚本程序是真正的实 干家。是它们完毕了启动或者停止各种服务的操作过程。当 /etc/rc.d/rc执行通过每一个特定的执行级别子文件夹的时候,它会依据数字的顺序依次调用各个命令脚本程序执行。它先执行以字母K打头的命令脚本程 序,然后再执行以字母S打头的命令脚本程序。
对以字母K打头的命令脚本程序来说,会传递Stop參数;类似地对以字母S打头的命令脚本程序来说。会传递 Start參数。
-
运行/etc/ec.d/rc.local
Redhat Linux中的运行模式2、3、5都把/etc/rc.d/rc.local做为初始化脚本中的最后一个,所以用户能够自己在这个文件里加入一些须要在其 他初始化工作之后。登录之前运行的命令。在维护Linux系统运转的日子里,肯定会遇到须要系统管理员对开机或者关机命令脚本进行改动的情况。假设所做的 改动仅仅在引导开机的时候起作用,而且改动不大的话。能够考虑简单地编辑一下/etc/rc.d/rc.local脚本。这个命令脚本程序是在引导过程的最 后一步被运行的。
-
运行 /bin/login 程式
login 程序会提示使用者需输入账号及password, 接着编码并确认password的正确性, 若二者相合, 则为使用者进行初始化环境, 并将控制权交给 shell,即等待用户登录。
多次为止Linux启动过程所有结束。
最后笔者使用图1解释所有过程。
总结:与 Linux 本身很类似。Linux 的启动引导过程也很灵活。能够支持众多的处理器和硬件平台。
LILO 引导载入程序对引导能力进行了扩充,可是它却缺少文件系统的感知能力。最新一代的引导载入程序。比如 GRUB将更加灵活。