Linux 启动过程详解

   这是个很值得探讨的问题,51CTO上就有很详细的文章,自己就不写相关博客了。这只上传一张图片,以及贴一些连接....

 

   这张图片很详细的说明了Linux的启动过程。

   更详细的文字介绍链接如下:

   http://book.51cto.com/art/200906/127322.htm

   先贴部分:(其实整个章节都值得好好读读)

   第4章 Linux网络服务和xinetd

本章要点

Linux启动过程

Linux守护进程

xinetd

Linux服务管理工具

安全选择Linux服务

.从BIOS到内核

(1)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。

(2)提取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中只能存储一个操作系统的引导记录,所以当需要多个操作系统时就会出现问题,因此需要更灵活的引导加载程序。

所有引导加载程序都以类似的方式工作,满足共同的目的。不过,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命令行中,我们可以使用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映像列表。

安全提示  通过MD5进行GRUB密码加密,这样会更安全。

① 原来GRUB的密码是123456,所以先要用MD5对123456这个密码进行加密。

# /sbin/grub-md5-crypt
Password: 在这里输入123456
Retype password: 再输入一次123456
$1$7uDL20$eSB.XRPG2A2Fv8AeH34nZ0

$1$7uDL20$eSB.XRPG2A2Fv8AeH34nZ0就是通过grub-md5-crypt进行加密后产生的值。

② 修改配置文件/etc/grub.conf,加入"password --md5 $1$7uDL20$eSB.XRPG2A2Fv8AeH34nZ0"一行,注意在title之前。修改后的文件格式如下:

timeout=10
splashp_w_picpath=(hd0,7)/boot/grub/splash.xpm.gz
password --md5 $1$7uDL20$eSB.XRPG2A2Fv8AeH34nZ0
title Fedora Core (2.4.22-1.2061.nptl)
root (hd0,7)
kernel /boot/vmlinuz-2.4.22-1.2061.nptl ro root=LABEL=/
initrd /boot/initrd-2.4.22-1.2061.nptl.img
title WindowsXP
rootnoverify (hd0,0)
chainloader +1

4.执行init进程

init进程是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空间内加载init程序,它的进程号是1。init进程是所有进程的发起者和控制者。因为在任何基于UNIX的系统(比如Linux)中,它都是第一个运行的进程,所以init进程的编号(Process ID,PID)永远是1。如果init出现了问题,系统的其余部分也就随之不可用。

init进程有两个作用:

① 扮演终结父进程的角色。因为init进程永远不会被终止,所以系统总是可以确信它的存在,并在必要的时候以它为参照。如果某个进程在它衍生出来的全部子进程结束之前被终止,就会出现必须以init为参照的情况。此时那些失去了父进程的子进程都会以init作为它们的父进程。快速执行一下"ps-af"命令,可以列出许多父进程的编号(Parent Process ID,PPID)为1的进程来。

② 在进入某个特定的运行级别(Runlevel)时运行相应的程序,以此对各种运行级别进行管理。它的这个作用是由/etc/inittab文件定义的。

5.通过/etc/inittab文件进行初始化

init的工作是根据/etc/inittab来执行相应的脚本进行系统初始化,如设置键盘、字体,装载模块,设置网络等。对于Red Hat Linux来说,按以下顺序执行。

(1)执行/etc/rc.d/rc.sysinit(由init执行的第一个脚本)

Red Hat Linux的/etc/rc.d/rc.sysinit要做在各个运行模式中相同的初始化工作,包括:

设置初始的$PATH变量。

配置网络。

为虚拟内存启动交换。

设置系统的主机名。

检查root文件系统,以进行必要的修复。

检查root文件系统的配额。

为root文件系统打开用户和组的配额。

以读/写的方式重新装载root文件系统。

清除被装载的文件系统表/etc/mtab。

把root文件系统输入到mtab。

使系统为装入模块做准备。

查找模块的相关文件。

检查文件系统,以进行必要的修复。

加载所有其他文件系统。

清除几个/etc文件,如/etc/mtab、/etc/fastboot和/etc/nologin。

删除UUCP的lock文件。

删除过时的子系统文件。

删除过时的pid文件。

设置系统时钟。

打开交换。

初始化串行端口。

装入模块。

(2)执行/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参数。

(3)执行/etc/ec.d/rc.local

Red Hat Linux中的运行模式2、3、5都把/etc/rc.d/rc.local作为初始化脚本中的最后一个文件,所以用户可以自己在这个文件中添加一些需要在其他初始化工作之后,登录之前执行的命令。在维护Linux系统运转时,肯定会遇到需要系统管理员对开机或者关机命令脚本进行修改的情况。如果所做的修改只在引导开机的时候起作用,并且改动不大的话,可以考虑简单地编辑一下/etc/rc.d/rc.local脚本。这个命令脚本程序是在引导过程的最后一步执行的。

(4)执行/bin/login

login程序会提示使用者需输入账号及密码,接着编码并确认密码的正确性,若二者相合,则为使用者进行初始化环境,并将控制权交给shell,即等待用户登录。到此为止,Linux启动过程全部结束。如图4-1所示是Linux启动流程图。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章