深入Linux启动过程

深入Linux启动过程


在IBM上看了这边文章,决定翻译下,,,结果翻译了一半之后发现已经有翻译过了的,,不过还是继续坚持翻译完了,眼过千遍不如手过一遍。

原文地址 http://www.ibm.com/developerworks/linux/library/l-linuxboot/#resources

------------------------------------------------------------------------------------------------------------------------------------------------


游览从主引导记录到第一个用户空间应用


导: Linux系统的启动过程由一系列阶段构成。不论你在启动一个标准的x86桌面计算机还是一个深度嵌入式的PowerPC,其大部分的流程都是惊人的相似。本文就要探索Linux的启动过程,从初始引导到启动第一个用户空间的应用程序。从中你将了解到许多与启动相关的话题,如bootloaders,kernel解压,引导RAM磁盘,和其他Linux启动的元素。



最初的时候,引导一台计算机意味着喂给它一条包含启动程序的纸带或者由人工从前面板操作地址、数据、控制开关去加载一个启动程序。如今的计算机已经装备了很多新的设备让启动过程变的看起来简单。。但这确实没有让这个过程边的简单。

首先我们来从一个宏观角度看一下Linux的启动,先形成整体的印象。然后我们再逐步了解每个具体的过程。整个过程参考源码,以便你能了解内核树并深入挖掘。


概括
图一给你展示出一个以20,000个步骤为单位的过程图

图1.  20,000个步骤为单位的Linux启动过程
上电/重启
| 系统启动BIOS/自检
| 第一阶bootloader主引导记录(MBR)
| 第二阶bootloader引导程序(LILO,GRUB,etc.)
| KernelLinux
| Init用户空间
V
操作
当系统刚刚加上电源,或按下了RESET,处理器会去执行位于一个众所周知的位置上的代码。在一台PC上,这就是位于安装在主板上的一块闪存中的基础输入/输出系统(BIOS)。而在嵌入式系统中,中央处理单元(CPU)则会调用重启向量去启动位于flash/ROM里已知地址上的程序。这两种情况下会得到相似的结果。因为PC有着相当的灵活性,BIOS必须确定哪些设备是候选引导项。我们将在后面讨论这里更多的细节。

当找到了启动设备后,第一阶bootloader呗载入到内存中并被执行。这个bootloader的长度小于512字节(一个扇区的大小),它的工作是去载入第二阶bootloader。

当第二阶bootloader被载入到内存并被执行,通常这时会在屏幕显示一个启动画面,Linux的可选初始化RAM磁盘镜像(临时的root文件系统)也会被载入到内存。当镜像被载入后,第二阶bootloader把控制权交给Kernel镜像并解压内核镜像,完成初始化。在这个阶段,第二阶bootloader会检查系统硬件,枚举已连接的硬件设备,挂载根设备,最后载入必要的内核模块。当这一系列操作完成后,第一个用户空间的程序(init)启动,开始更高层的系统初始化工作。

以上是简而言之的Linux启动过程。接下来我们就来更深入的去探索Linux启动过程中的一些细节。


系统启动
系统启动阶段依赖于要启动的Linux的硬件。在嵌入式平台上,引导环境会在系统通电或重启时被启用。比如像U-Boot,RedBoot,还有Lucent公司的MicroMonitor。嵌入式平台通常都会和启动监视器一起,这些程序位于目标硬件闪存的特殊位置,它们会吧Linux内核镜像载入到内存并随后运行它。除了存储和启动Linux镜像,这些启动监视器还会去做不同级别的系统测试和硬件初始化。在嵌入式设备上,这些启动监视器通常会涵盖第一阶和第二阶bootloader的作用。

在PC上,启动Linux由BIOS的0xFFFF0地址开始。BIOS的第一步是开机自检(POST)。开机自检的工作是检查硬件。BIOS的第二步是本地设备枚举和初始化。

对应BIOS不同用途的功能,是由两部分组成:POST代码和运行时服务。开机自检完成后,POST代码会被从内存中清除,但是BIOS的运行时服务依然存在并对目标操作系统可用。

为启动操作系统,BIOS的运行时服务会去搜索CMOS设定中定义的启动顺序,以找到活动的并可引导的设备。引导设备可以是软盘,CD-ROM,硬盘分区,网络上的设备,甚至是USB闪存。

通常情况下Linux会从硬盘上包含主bootloader的主引导记录(MBR)启动。MBR是一个512字节的,位于硬盘最开始的一个扇区(柱面0,磁头0扇区1)。MBR被完全载入到内存后,BIOS会把控制交给它。
--------查看BMR
要查看MBR的内容,使用如下命令
# dd if=/dev/hda of=mbr.bin bs=512 count=1
# od -xa mbr.bin
dd命令需要root权限,它会从/dev/hda的最开始读取512字节(第一个电子集成驱动器或IDE磁盘)并写入到mbr.bin文件。od命令会将二进制文件以十六进制和ASC II格式输出。
--------


第一阶bootloader

位于MBR的主bootloader是512字节的一个镜像,包含程序代码和一个小的分区表(图2)。最开始的446字节是主bootloader,包含可执行代码和错误信息文本。接下来的64字节是分区表,包含了4个分区的记录(每个分区16字节)。MBR由被定义为魔数(0xAA55)的两个字节标记为结束。模式被MBR用于有效性验证。
图2. MBR结构图
......
分区内容:分区flag|起始CHS|分区字节|结束CHS|起始LBA|容量
主bootloader的工作是找到并载入第二阶bootloader(第二阶段)。它通过从分区表中找到活动分区。找到活动分区后,它会扫描分区表中的其余分区以确认他们不是活动的。当确认完成后,活动分区的启动记录将会被载入到RAM并被运行。


第二阶bootloader

第二步,或者说第二阶段的bootloader应该被更恰当的叫做Kernel加载器。这个阶段的任务就是载入Linux内核和可选的初始化RAM镜像。

第一阶和第二阶的启动加载器合起来被称作x86环境下的Linux Loader(LILO)或GRandUnified Bootloader(GRUB)。由于LILO有一些缺陷,并且在GRUB中被改正,这里就只讨论GRUB。

GRUB的牛逼之处在于它能识别Linux文件系统。GRUB没有像LILO那样去使用磁盘上的raw扇区,而是可以从ext2或ext3的文件系统上载入Linux内核。它通过把两步启动加载变成三步启动加载。第一阶段(MBR)启动了1.5阶段启动加载器,它是可以识别包含Linux内核镜像的常规文件系统。例如reiserfs_stage1_5 (从Reiser日志文件系统加载)或e2fs_stage1_5 (从ext2或ext3文件系统加载)。当1.5阶启动加载器被加载并运行,就可以载入第二阶启动加载器了。

第二阶段加载后,GRUB可以根据需要,列出可用的内核列表(在/etc/grub.conf中定义,这是/etc/grub/menu.lst的软链接)。你可以选择一个内核并修改加入内核参数。或者,你可以用命令行去完成更牛逼的手动控制启动过程。

随着第二阶bootloader被载入进内存,文件系统也可以使用,默认的内核镜像和initrd镜像也被载入到内存中。当镜像被载入完毕,第二阶bootloader会调用内核镜像。
---------GRUB阶段bootloaders
/boot/grub文件夹中包含第1阶,第1.5阶和第2阶的bootloader,以及一系列外设的加载器(例如光驱,使用iso9660_stage_1_5)。
---------


Kernel
随着内核镜像被载入到内存,并得到第二阶bootloader的控制权,内核阶段开始。内核镜像并不是一个可执行内核,而是被压缩过的内核镜像。通常是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镜像列出。
--------------

当bzImage(用于i386平台的镜像)被调用时,你会从./arch/i386/boot/head.S的start汇编程序开始。这段程序会做一些基本的硬件设置并调用./arch/i386/boot/compressed/head.S中的startup_32程序。这段程序会设置基本环境(堆栈,等等)并清除符号开始的块(BSS)。内核接下来会被一个叫做decompress_kernel(位于./arch/i386/boot/compressed/misc.c)的C函数调用解压。内核被完全解压到内存后,又一个startup_32方法被调用,不过这个方法位于./arch/i386/kernel/head.S。

在这个新的startup_32方法(也叫清理程序或进程0)里,分页表被初始化,同时内存分页功能生效。由CPU的可选的浮点运算单元检测出CPU类型,并存起来以备后用。接下来会调用start_kernel方法(位于init/main.c中),这会带你到非特定架构的Linux内核。本质上就是Linux内核的main函数。

图3. Linux内核在i386平台上启动时的主要函数流程
|
| start()./arch/i386/boot/head.S
|
| startup_32()./arch/i386/boot/compress/head.S
| \
| v
| decompress_kernel()./arch/i386/boot/compress/misc.c
|
| startup_32()./arch/i386/kernel/head.S
|
| start_kernel()./init/main.c
V
cpu_idle() ./init/main.c

start_kernel被调用后,有一系列的初始化函数被执行,它们设立起中断,完成进一步的内存配置,并载入初始化RAM镜像。最后,方法kernel_thread(在arch/i386/kernel/process.c中)被调用,开始init函数。这是第一个用户空间进程。最后,空闲任务启动,并可以被调度器控制(调用cpu_idle后)。当中断可用后,抢先调度开始周期性的控制,以提供多任务处理。

Kernel启动的过程中,初始化RAM镜像(initrd)被内存中的第二阶bootloader载入内存并挂载。initrd提供了内存中的临时root文件系统,以便内核不用加载任何物理外设就能够启动。由于与外设接口所需的模块可以是initrd的一部分,所以kernel的体积可以很小,但它依然可以支持很大一部分硬件的配置。当kernel启动后,根文件系统将会转移到卸载了initrd的根文件系统后挂载的真正的根文件系统上。

initrd具有创建一个小的Linux内核和编译为可载入模块的驱动。这些可载入的模块可以让内核访问磁盘以及磁盘上的文件系统,甚至其他硬件外设上的磁盘。由于根文件系统存在于磁盘上,所以initrd要能够提升磁盘访问权限并挂载真正的文件系统,或着要能通过网络文件系统(NFS)挂载最终的根文件系统。


-------------------decompress_kernel 函数输出
decompress_kernel函数调用时通常会显示解压信息和省略号:


Uncompressing Linux... Ok, booting the kernel.
-------------------


Init
当内核已启动并完成初始化,就会启动第一个用户空间的应用程序。这是启动后被调用的第一个由标准C库编译的程序。而在整个过程执行到这点之前,没有标准的C程序被执行。

在一个桌面Linux系统中,通常第一个被启动的程序是/sbin/init。但是这并不是必须的,很少有嵌入式系统会需要init去做很多的初始化工作(由/etc/inittab配置的)。而更多情况下,你可以执行一个简单的shell脚本启动必要的嵌入式程序。


总结
与Linux本身极为相似,Linux的启动过程是非常灵活的,支持大量的处理器和硬件平台。在一开始,载入的bootloader就提供了简单的方式去启动Linux而不需要其他辅助。启动器LILO具有启动的能力,但它缺少对文件系统的支持。而最新一代的bootloader,像GRUB那样,允许Linux从一些文件系统(从Minux到Raiser)中启动。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值