欢迎各位的光临,鄙人以好酒好菜招待~~!!^_^

Linux 引导过程内幕

上一篇 / 下一篇  2006-07-31 18:11:34 / 天气: 晴朗 / 心情: 高兴

查看( 1764 ) / 评论( 1 )

Linux 引导过程内幕

从主引导记录到第一个用户空间应用程序的指导Linux宝库kMx'ti!W

 
将此页作为电子邮件发送

P^&tvy&q]0 

1i+Ms lz(c s0

q7|3\ k}0未显示需要 JavaScript 的文档选项

2c$r&o C'R1^-hq0

hG^zZ'`M!L0

+U.@~2~)yQL6vj0 

(GS!{C1sW;T/v Pn0
Linux宝库]C{ph:Aj{:LBgw1d

n9@K4xc-C0}0级别: 初级

HHsQ_eh7VN E,B0

f$_8?M+R H'|x0M. Tim Jones(mtj@mtjones.com), 顾问工程师, Emulex
Y$_n[K@^#w0Linux宝库-^;m?x9b r

Linux宝库F+? R;[ER!m'L

 Linux宝库7a/u U5a/sR;C C

引导 Linux® 系统的过程包括很多阶段。不管您是引导一个标准的 x86 桌面系统,还是引导一台嵌入式的 PowerPC® 机器,很多流程都惊人地相似。本文将探索 Linux 的引导过程,从最初的引导到启动第一个用户空间应用程序。在本文介绍的过程中,您将学习到各种与引导有关的主题,例如引导加载程序、内核解压、初始 RAM 磁盘以及 Linux 引导的其他一些元素。
Linux宝库p(h9b Cc{H`nY

早期时,启动一台计算机意味着要给计算机喂一条包含引导程序的纸带,或者手工使用前端面板地址/数据/控制开关来加载引导程序。尽管目前的计算机已经装备了很多工具来简化引导过程,但是这一切并没有对整个过程进行必要的简化。Linux宝库;_E'\@i3p

Linux宝库C8O4Q"ln@R'y

让我们先从高级的视角来查看 Linux 引导过程,这样就可以看到整个过程的全貌了。然后将回顾一下在各个步骤到底发生了什么。在整个过程中,参考一下内核源代码可以帮助我们更好地了解内核源代码树,并在以后对其进行深入分析。Linux宝库:_s$Y o$l1r@)U

ZF9W`&[,g `S1j!B0概述

Xq9Gu9M*F0当系统首次引导时,或系统被重置时,处理器会执行一个位于已知位置处的代码。在个人计算机(PC)中,这个位置在基本输入/输出系统(BIOS)中,它保存在主板上的闪存中。嵌入式系统中的中央处理单元(CPU)会调用这个重置向量来启动一个位于闪存/ROM 中的已知地址处的程序。在这两种情况下,结果都是相同的。因为 PC 提供了很多灵活性,BIOS 必须确定要使用哪个设备来引导系统。稍后我们将详细介绍这个过程。

4qlXe'w0当找到一个引导设备之后,第一阶段的引导加载程序就被装入 RAM 并执行。这个引导加载程序在大小上小于 512 字节(一个扇区),其作用是加载第二阶段的引导加载程序。

8~7eP'R%|,H aH0

KtRcnuP0当第二阶段的引导加载程序被装入 RAM 并执行时,通常会显示一个动画屏幕,并将 Linux 和一个可选的初始 RAM 磁盘(临时根文件系统)加载到内存中。在加载映像时,第二阶段的引导加载程序就会将控制权交给内核映像,然后内核就可以进行解压和初始化了。在这个阶段中,第二阶段的引导加载程序会检测系统硬件、枚举系统链接的硬件设备、挂载根设备,然后加载必要的内核模块。完成这些操作之后启动第一个用户空间程序(init),并执行高级系统初始化工作。Linux宝库vV~}#E}

t0F S f VK v0这就是 Linux 引导的整个过程。现在让我们深入挖掘一下这个过程,并深入研究一下 Linux 引导过程的一些详细信息。Linux宝库*v A/hp~$gZX3m

Linux宝库 Y1p%n%}2w&yD
Linux宝库fn7S7s(u0}

_G,a/zdYSK;k0U-L0
Linux宝库X#_(JO!j$V"f.W8?

系统启动

\&f%U} i5D"C$p0

6^/fY+e:|0系统启动阶段依赖于引导 Linux 系统上的硬件。在嵌入式平台中,当系统加电或重置时,会使用一个启动环境。这方面的例子包括 U-Boot、RedBoot 和 Lucent 的 MicroMonitor。嵌入式平台通常都是与引导监视器搭配销售的。这些程序位于目标硬件上的闪存中的某一段特殊区域,它们提供了将 Linux 内核映像下载到闪存并继续执行的方法。除了可以存储并引导 Linux 映像之外,这些引导监视器还执行一定级别的系统测试和硬件初始化过程。在嵌入式平台中,这些引导监视器通常会涉及第一阶段和第二阶段的引导加载程序。

RrPYv0
提取 MBR 的信息Linux宝库2bk$?k(mo"R `S
Linux宝库y L2Kv:oa-A^z

要查看 MBR 的内容,请使用下面的命令:

h(P1j&`s0#dd if=/dev/hda of=mbr.bin bs=512 count=1#od -xa mbr.binLinux宝库+W:J(V!}4Un1^

这个dd命令需要以 root 用户的身份运行,它从 /dev/hda(第一个 IDE 盘) 上读取前 512 个字节的内容,并将其写入mbr.bin文件中。od命令会以十六进制和 ASCII 码格式打印这个二进制文件的内容。Linux宝库x)iR!S0[-KU\w

Linux宝库!L[p w `p,V-PA!]e

在 PC 中,引导 Linux 是从 BIOS 中的地址 0xFFFF0 处开始的。BIOS 的第一个步骤是加电自检(POST)。POST 的工作是对硬件进行检测。BIOS 的第二个步骤是进行本地设备的枚举和初始化。Linux宝库g(`+i)v{u0E2c

` QzFzOMe0给定 BIOS 功能的不同用法之后,BIOS 由两部分组成:POST 代码和运行时服务。当 POST 完成之后,它被从内存中清理了出来,但是 BIOS 运行时服务依然保留在内存中,目标操作系统可以使用这些服务。

@(Ak'T5wbD!wT0Linux宝库u Y a^%Em,T

要引导一个操作系统,BIOS 运行时会按照 CMOS 的设置定义的顺序来搜索处于活动状态并且可以引导的设备。引导设备可以是软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备,甚至是 USB 闪存。Linux宝库:d0])o*a \&H*N v

Linux宝库t8a nV$dq.G%aE5G

通常,Linux 都是从硬盘上引导的,其中主引导记录(MBR)中包含主引导加载程序。MBR 是一个 512 字节大小的扇区,位于磁盘上的第一个扇区中(0 道 0 柱面 1 扇区)。当 MBR 被加载到 RAM 中之后,BIOS 就会将控制权交给 MBR

6a,L-nzkU!{#B4x0Linux宝库{7kX T%s^8Y
Linux宝库 m:b kbB

:O5K6]Nx'H0

,I-z3~(S-I7m0D&V0
回页首

_?,m'GT C@zrk0
yo9v4[(l$s p9N0

-\%d1_*q:j.kum!d;w0第一阶段引导加载程序

q5e@#V#n6C0Linux宝库v _5T*\0[F$?,F0f

MBR 中的主引导加载程序是一个 512 字节大小的映像,其中包含程序代码和一个小分区表(参见图 2)。前 446 个字节是主引导加载程序,其中包含可执行代码和错误消息文本。接下来的 64 个字节是分区表,其中包含 4 个分区的记录(每个记录的大小是 16 个字节)。MBR 以两个特殊数字的字节(0xAA55)结束。这个数字会用来进行 MBR 的有效性检查。

t[Xr[@]6]P N0主引导加载程序的工作是查找并加载次引导加载程序(第二阶段)。它是通过在分区表中查找一个活动分区来实现这种功能的。当找到一个活动分区时,它会扫描分区表中的其他分区,以确保它们都不是活动的。当这个过程验证完成之后,就将活动分区的引导记录从这个设备中读入 RAM 中并执行它。
qOiJ?"S\0
Linux宝库 n{e!c8mr]f0\
Linux宝库(j;@.i*[]-L+Cm~
Linux宝库`0N \@o5Gs+WB
回页首

6ndWDO ii0Linux宝库Dkb LF

ly%~ nQh{ZJ0第二阶段引导加载程序

qo8|+U#}+[H%@0Linux宝库yS)I7h xj

次引导加载程序(第二阶段引导加载程序)可以更形象地称为内核加载程序。这个阶段的任务是加载 Linux 内核和可选的初始 RAM 磁盘。Linux宝库 C)BR@6TW

GRUB 阶段引导加载程序
}G6p0Z&k0

Ru'PS0`T0/boot/grub目录中包含了stage1stage1.5stage2引导加载程序,以及很多其他加载程序(例如,CR-ROM 使用的是iso9660_stage_1_5)。

$Y4mG,k9q!z,o-g0
Linux宝库|j`*x0t9?*C]

在 x86 PC 环境中,第一阶段和第二阶段的引导加载程序一起称为 Linux Loader(LILO)或 GRand Unified Bootloader(GRUB)。由于 LILO 有一些缺点,而 GRUB 克服了这些缺点,因此下面让我们就来看一下 GRUB。(有关 GRUB、LILO 和相关主题的更多内容,请参阅本文后面的参考资料部分的内容。)

se^,D v0Linux宝库6U,ly5h2H G

关于 GRUB,很好的一件事情是它包含了有关 Linux 文件系统的知识。GRUB 不像 LILO 一样使用裸扇区,而是可以从 ext2 或 ext3 文件系统中加载 Linux 内核。它是通过将两阶段的引导加载程序转换成三阶段的引导加载程序来实现这项功能的。阶段 1 (MBR)引导了一个阶段 1.5 的引导加载程序,它可以理解包含 Linux 内核映像的特殊文件系统。这方面的例子包括reiserfs_stage1_5(要从 Reiser 日志文件系统上进行加载)或e2fs_stage1_5(要从 ext2 或 ext3 文件系统上进行加载)。当阶段 1.5 的引导加载程序被加载并运行时,阶段 2 的引导加载程序就可以进行加载了。Linux宝库Y4}\ a,j{T{

F"R"tV~W*\0当阶段 2 加载之后,GRUB 就可以在请求时显示可用内核列表(在/etc/grub.conf中进行定义,同时还有几个软符号链接/etc/grub/menu.lst/etc/grub.conf)。我们可以选择内核甚至修改附加内核参数。另外,我们也可以使用一个命令行的 shell 对引导过程进行高级手工控制。

@ ?9z @p` E1qL2Hx0Linux宝库)YnY%^ P1b

将第二阶段的引导加载程序加载到内存中之后,就可以对文件系统进行查询了,并将默认的内核映像和initrd映像加载到内存中。当这些映像文件准备好之后,阶段 2 的引导加载程序就可以调用内核映像了。Linux宝库Q/N qtH5W.d!K

Linux宝库)D7u,R%Q C

2R3S3vYL0

;C5yX8s$X0

,H4cot S@&Sv0y,a:W$A0
回页首

n7fZ^%s%k0Linux宝库8XL/dFxJ*b7\W1C|
Linux宝库?5AHCU`L T-nx

内核

\5d4i _6oN0
GRUB 中的手工引导
LK8T4G S]z:s0Linux宝库D5["I!xWyV\

在 GRUB 命令行中,我们可以使用initrd映像引导一个特定的内核,方法如下:Linux宝库$h.Z!W CHr

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.
Linux宝库!a\8yp-]?.^ c M
Linux宝库"R_[9~P

如果您不知道要引导的内核的名称,只需使用斜线(/)然后按下 Tab 键即可。GRUB 会显示内核和initrd映像列表。Linux宝库;K NCa W:|k

Linux宝库 |$?LA6sm.L8A%s'r

当内核映像被加载到内存中,并且阶段 2 的引导加载程序释放控制权之后,内核阶段就开始了。内核映像并不是一个可执行的内核,而是一个压缩过的内核映像。通常它是一个 zImage(压缩映像,小于 512KB)或一个 bzImage(较大的压缩映像,大于 512KB),它是提前使用 zlib 进行压缩过的。在这个内核映像前面是一个例程,它实现少量硬件设置,并对内核映像中包含的内核进行解压,然后将其放入高端内存中,如果有初始 RAM 磁盘映像,就会将它移动到内存中,并标明以后使用。然后该例程会调用内核,并开始启动内核引导的过程。

1{:UiOL Oz!r0

4eA-Q,LrM$?4O5p0当 bzImage(用于 i386 映像)被调用时,我们从./arch/i386/boot/head.Sstart汇编例程开始执行(主要流程图请参看图 3)。这个例程会执行一些基本的硬件设置,并调用./arch/i386/boot/compressed/head.S中的startup_32例程。此例程会设置一个基本的环境(堆栈等),并清除 Block Started by Symbol(BSS)。然后调用一个叫做decompress_kernel的 C 函数(在./arch/i386/boot/compressed/misc.c中)来解压内核。当内核被解压到内存中之后,就可以调用它了。这是另外一个startup_32函数,但是这个函数在./arch/i386/kernel/head.S中。

L5B]&} }B Z0Linux宝库&{-KZ D(M G0\A

在这个新的startup_32函数(也称为清除程序或进程 0)中,会对页表进行初始化,并启用内存分页功能。然后会为任何可选的浮点单元(FPU)检测 CPU 的类型,并将其存储起来供以后使用。然后调用start_kernel函数(在init/main.c中),它会将您带入与体系结构无关的 Linux 内核部分。实际上,这就是 Linux 内核的main函数。

)bE jg,Hh0Linux宝库~1tpa!~7Z\5}
 Linux宝库g9D8~&E o4e!c
Linux宝库pX*JLu

通过调用start_kernel,会调用一系列初始化函数来设置中断,执行进一步的内存配置,并加载初始 RAM 磁盘。最后,要调用kernel_thread(在arch/i386/kernel/process.c中)来启动init函数,这是第一个用户空间进程(user-space process)。最后,启动空任务,现在调度器就可以接管控制权了(在调用cpu_idle之后)。通过启用中断,抢占式的调度器就可以周期性地接管控制权,从而提供多任务处理能力。

tF2MS#FA0Linux宝库$g2Q)`Mp7c

在内核引导过程中,初始 RAM 磁盘(initrd)是由阶段 2 引导加载程序加载到内存中的,它会被复制到 RAM 中并挂载到系统上。这个initrd会作为 RAM 中的临时根文件系统使用,并允许内核在没有挂载任何物理磁盘的情况下完整地实现引导。由于与外围设备进行交互所需要的模块可能是initrd的一部分,因此内核可以非常小,但是仍然需要支持大量可能的硬件配置。在内核引导之后,就可以正式装备根文件系统了(通过pivot_root):此时会将initrd根文件系统卸载掉,并挂载真正的根文件系统。

3` E?,A+G0C*y{0
decompress_kernel 输出Linux宝库W]E:C.}
Linux宝库9pg)_oORn3w

函数decompress_kernel就是显示我们通常看到的解压消息的地方:Linux宝库U*gasGT F%kL y

Uncompressing Linux... Ok, booting the kernel.
Linux宝库I0E M;p*bw1x

b4B"t+Bmd1t_T0initrd函数让我们可以创建一个小型的 Linux 内核,其中包括作为可加载模块编译的驱动程序。这些可加载的模块为内核提供了访问磁盘和磁盘上的文件系统的方法,并为其他硬件提供了驱动程序。由于根文件系统是磁盘上的一个文件系统,因此initrd函数会提供一种启动方法来获得对磁盘的访问,并挂载真正的根文件系统。在一个没有硬盘的嵌入式环境中,initrd可以是最终的根文件系统,或者也可以通过网络文件系统(NFS)来挂载最终的根文件系统。

'?mx+IJ0Linux宝库wMCP K@Yi{4|'\

"C$~N"D"{R'R` mVHC0
Linux宝库p#Mi"X!Z.E

9z0rG(F4YjK1}0
回页首
Linux宝库8_"m*Xex
Linux宝库!dV'y'M%G q2Pe+V%t
Linux宝库;Jb/QxH

InitLinux宝库b QL4Nn(n

Linux宝库N1p?I9P

当内核被引导并进行初始化之后,内核就可以启动自己的第一个用户空间应用程序了。这是第一个调用的使用标准 C 库编译的程序。在此之前,还没有执行任何标准的 C 应用程序。

E5X^Te+~ k] el0Linux宝库*_0w5z {7Kg

在桌面 Linux 系统上,第一个启动的程序通常是/sbin/init。但是这不是一定的。很少有嵌入式系统会需要使用init所提供的丰富初始化功能(这是通过/etc/inittab进行配置的)。在很多情况下,我们可以调用一个简单的 shell 脚本来启动必需的嵌入式应用程序。Linux宝库r/J(h$U6r+`)O!k

Linux宝库1Bp4YgnM

*c0T3py@6r R6tg:{#Fu\0
Linux宝库f!_Uj1bm7e%Xw1V

e5`D'T%su.Q0
回页首
Linux宝库3]EG9eA0wc

.j3_A.RgUds0Linux宝库n H.n$a f})F

结束语

N g`3QV0

0AN4Hi*V1G$_y0与 Linux 本身非常类似,Linux 的引导过程也非常灵活,可以支持众多的处理器和硬件平台。最初,加载引导加载程序提供了一种简单的方法,不用任何花架子就可以引导 Linux。LILO 引导加载程序对引导能力进行了扩充,但是它却缺少文件系统的感知能力。最新一代的引导加载程序,例如 GRUB,允许 Linux 从一些文件系统(从 Minix 到 Reise)上进行引导。Linux宝库2NP s'},R)x"b$k


"AYf9TVn7Ke{-U^!h0

O}%rqw_0
Linux宝库^3ON-@e#n{(fh
Linux宝库3JG3|9O$yHq,c}}
回页首

x;z2R,s\7Oe0P$`v.aQ0Linux宝库j A,P)Y;y'q8K fb(b
Linux宝库|!kRr0B@0X;j

参考资料

2o_8x5L b9X!?9]0学习Linux宝库;@3_p"A}0GC
  • 您可以参阅本文在 developerWorks 全球站点上的英文原文Linux宝库mG|2gnc i?%L8C

    q/AWUS2u:C$?#f0
  • Boot Records Revealed是有关 MBR 和各种引导加载程序很好的资源。这个资源不仅仅是有关 MBR 的资料的汇编,还讨论了 GRUB、LILO 和各种 Windows® 引导加载程序的问题。Linux宝库`L@*dlojz
    Linux宝库F|:IL|;p'\a
  • 请查看Disk Geometry页面来理解磁盘及其结构。您会发现有关磁盘的有用属性。
    v"C dL&f)F T7TI.J0
    :D4_%i3x2M-Yu)B-`0i0
  • live CD是一个可以从 CD 或 DVD 上引导的操作系统,它不需要使用硬盘。Linux宝库IL0ip-nGcmP
    Linux宝库0po?8@7f)c
  • 引导加载程序之争:了解 LILO 和 GRUB”(developerWorks,2005 年 8 月)详细介绍了 LILO 和 GRUB 引导加载程序。Linux宝库jq7y[,xU*N

    YpH?fPc]W&]0
  • 在 developerWorks 上的LPI 考试准备系列教程中,我们可以学习有关引导 Linux 系统的详细介绍,以及在准备参加系统管理员认证考试时需要准备的 Linux 基础知识。
    ?fk,X J3YSx2]&p0Linux宝库@)?(t9bS,r
  • LILO是 GRUB 的先驱,但是我们可能发现它依然可以引导 Linux。
    +fNKm6g'Cjf)anq0
    U,Hh~'\ O0
  • mkintrd命令用来创建初始的 RAM 磁盘映像。这个命令可以用来构建初始的根文件系统,它可以用来引导允许提前加载访问真正根文件系统所需要的块设备的配置。
    lq:f.GhQNvM [Q0Linux宝库;c;Za6O)kU$N!i
  • Debian Linux Kernel Project中,我们可以找到更多有关 Linux 内核、引导和嵌入式开发的信息。Linux宝库 D H(GPdW'c
    Linux宝库X|-{/M|0y5[w%L
  • developerWorks Linux 专区中可以找到为 Linux 开发人员准备的更多资源。Linux宝库C.L5g{b
    Linux宝库o#o\g-C
  • 随时关注developerWorks 技术事件和网络广播

n:{A Y']:lg8X0获得产品和技术
.\"et x)|/h k@kx0
  • MicroMonitor为各种小型的目标设备提供了引导环境。我们可以使用这个监视器在嵌入式环境中引导 Linux。它已经移植到 ARM、 XScale、MIPS、PowerPC、Coldfire 和 Hitachi 的 Super-H 上了。
    +W bS"uS%i2Q0
    H2W-gc$@*~0
  • GNU GRUB是一个具有众多选项和灵活性的引导 shell。
    7K3A3oK[:r%a:y v,X0
    z ZN:C6d4pA3t0
  • LinuxBIOS是 BIOS 的一个替代品。LinuxBIOS 不但可以引导 Linux,而且它本身就是一个压缩的 Linux 内核。
    ]TOx.@9K6^*h/O0
    RQ+dTv ]w,K$E0
  • OpenBIOS是另一个可移植的 BIOS 项目,可以在很多体系结构上进行操作,例如 x86、Alpha 和 AMD64。
    cpc}H!tCd0Linux宝库bmb {|$m5^5{@
  • kernel.org上可以找到最新的内核树。
    ` gJG)@"Dk*CY0Linux宝库v3asG Vaq5B%}q)F
  • 订购免费的 SEK for Linux,它有两张 DVD,其中包括最新的 IBM for Linux 的试用版软件,这些软件包括 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere®。Linux宝库a^[.U\hFY

    k.oLiRK*z K0
  • 使用IBM 试用版软件改进您的下一个开发项目,从 developerWorks 上可以直接下载这些软件。

TAG: 情感绿洲 电脑网络

redhatlinux的个人空间 redhatlinux 发布于2006-08-04 18:40:50
先看看了
{zb6G
q{*[N(_
我是刚接触的,反正WINDOWS引导过程好动的多 了!
我来说两句

(可选)

Open Toolbar