走进Linux 操作系统


;   附件——linux系统启动的标准流程   系统的启动是指从计算机加电到显示用户登陆提示的整个过程。我们将在这里对整个流程以及关系到的一 些内容做讨论。过程主要可以分为两个阶段:载入内核和准备运行环境,我们分别进行讨论。本部分的 讨论只基于i386硬 件架构,但大部分内容是有共通性的。 

                                             图一 启动过程 综述         载入内核(将内核载入内存,并将控制权传递给它)         计算机加电到boot loader开始工作,硬件含量 远大于软件含量,所以这里暂不提及,如果实在有关心的朋友,请先别着急,我们将在下期里讨论它。  这一阶段是 boot loader 的主战场。它必须将可执行的内核映像和内核启动所需的额外数据信息从存储介质上载入内存,这并不是 件简单的工作,因为除了从硬盘载入,可能还会需要从网络引导服务器这样的外部介质上载入。各种纷繁芜杂的文件系统类型也给载入带来了巨大的挑战。  boot loader 可能还需要改变cpu的运行特权级别,然后就可以让内核投 入运行了。  除此之外,boot loader 还要完成一些其它功能,比如从bios中获取系统信息,或者从启动时的命令行参数中提取信息等。有的 boot loader 还要扮演引导选择工具的角色,方便用户选择不同的操作系 统。       boot loader的职责:       判断到底要载入什么,这可以要求用户进行选择      载入内核和它可能需要用到的相关数据,比如initrd或者其它参数      为内核准备好运行环境,比如,让cpu进入特权模式      让内核投入运行                                                                       boot loader的 历史变迁:  早期的linux只支持软盘引导扇区和 shoelace 两种 boot loader。 shoelace 是从minix继承下来的、对文件系统相关的 boot loader。它只支持 minix 文件系统。当时linux只使用 minix 一种文件 系统,所以这样做并没什么问题。可是, minix 文件系统存在不能保存创建、修改和访问时间信息;文件名长度限制在14个字节等问题。随着linux的发展,这些与传统unix文件系统大相径庭的缺陷越来越让人 难以忍受,它已经不适合作为linux的主要文件系统了。  为了支持其它文件系统的实现,linux引入了vfs(虚拟文件系统)。这个举措很快就引起了热烈的反响,一大批新的文件系统实现出现了。其中一个 minix 文件系统的变体,扩展文件系统 xiafs (根据它的作者命名)突破了 minix 文件系统的文件名长度限制,将此长度一举提高到全部30个字符。当时文件系统之间的竞争着实激 烈,很难看出谁会胜出,甚至搞不清楚会不会有一个最终的“赢家”。       尽管不确定性很大,但是有一点却是清楚的:不管最后哪种文 件系统会受到青睐,但是除了 minix 作为根文件系统,谁也不能从硬盘上启动,因为 shoelace 只支持minix文件系统。lilo应运而生了。由于支持多种文件系统(当时内核支持的主流文件系统已经有 minix ,扩展文件系统 ext , xiafs 。还有人在移植 bsd 的 ffs ,根本看不出来什么时候是个尽头)在实现和维护上难度太大,而 boot loader 也不 应该成为人们试验新的文件系统的绊脚石,所以lilo采取了和文件系统无关的设计。  这种设计经受住了时间的考验,被证明是非常成功的。即使在今天,lilo仍旧可以从内核支持的绝大部分文件 系统的硬盘上启动。但是,由于ext2历经这么长的时间一直没有大的演变,成为了事实上的标准,所以跟文件系统相关的boot loader又渐渐流行了起来。尽管ext2已经能满足大部分人的日常需要,但 是文件系统的设计者们还是在研制以日志机制为特征的新的文件系统,并且已经取得了相当大的进展。考虑到当前又有可能出现多种文件系统的实现同时并存的情 况,因此对与文件系统无关的boot loader的需求可能会再次变得强劲。初始化基本的操作环境  一旦内核开始运行,它会初始化内部的数据结构,检测硬件,并且激活相应的驱动程序,为应用软件的准 备运行环境。其间包含一个重要操作——应用软件的运行环境必须要有一个文件系统,所以内核必须首先装载root文件系统。由于我们的目的是介绍基 本流程,所以相关的硬件初始化细节就不再讨论,相关内容在下一期杂志中会有详细介绍。         硬件初始化完成后,内核着手创建第一个进程——初始进程。说是创建, 其实也不尽然,该进程其实是整个硬件上电初始化过程的延续,只不过执行到这里,进程的逻辑已经完备,所以我们就按照进程的创建方式给它进行了“规格化” ——我们把这个初始进程也叫做“硬件进程”,它会占据进程描述符表的第一个位置,所以可以用task[0]?或init_task表示。该进程进而会再创建一 个新进程去执行init()函数,其实,这个新进程才是系统第一个实际有用的进程,它会负责接着执行下一个阶段的初始化操作; 而初始进程(init_task)自己则会开始执行idle循环,也就是说,内核初始化完成之后,初始进程唯一的任务就是在没有任何其它进程需要执行的时候, 消耗空闲的cpu时 间(因此初始进程也被称为idle进程)。  下一阶段的初始化工作要比前一阶段轻松一点,因为现在是由一个真正进程接手负责完成它们了,而前一 阶段都是由“硬件进程”手工去做的。在此阶段,这个由init_task创建的新进程需要初始化总线、网络并启动系统中的各种系统内核后台线程,然后再初始化外设、设置文 件格式,在这之后,它要为进入系统做最后的准备——初始化文件系统,安装root文件系统,打开/dev/console设备,重定向stdin、stdout和stderr到控制台,然后 搜索文件系统中的init程序,并使用 execve()系统调 用加载执行init程 序。系统自此进入了用户态。装载root文件系统  为了装载文件系统,内核需要:1知道root文件系统位于那个存储介质上;2有访问该种介质的驱动程序。最常见的情况是root是ext2文件系统,位于ide硬盘上。这种情况下需要的操作很简单:将设备号作为参数给内核就可以了,ide的设备驱动程序通常都会编译进内核 的。  如果内核没有相关介质的驱动程序,问题就会变得更为复杂。而这种情况并不罕见,比如linux的安装盘使用的“通用”内核一般都会碰到。如果内核把所有支持的硬件的设备驱动程序都包含进来,就会变成一个庞然 大物;而且一些驱动程序在检测硬件的时候会影响其它设备。  这个问题可以通过initrd机制解决,它允 许在装载实际的root文件系统之前先使用ram文件系统。除了上述两个原因,引入initrd还可以解决内核 的动态合成问题。(详见参考资料一。)  不过我们应该注意到,init在整个启动过程中并不是从来就有的,它可以说是一个插件,为了解决以上问题,而被加入启动过程,象图一所示,linux系统在启动时也可以不选择它。为什么要引入initrd?  linux启动过程中肯定要载入内核镜像,在此过程中有些要素必须考虑:  首先,内核镜像不能太大。由于受到各种硬件和兼容性的限制,linux的内核镜像不能太大,但是这并不 容易做到。linux内核的核心部分本身就不小了;而且还必须加入会使用到的驱动程序。  其次,要支持尽可能多的硬件设备。我们在启动过程中有一件重要工作:挂载root文件系统,因为进一步的数据和应用 软件都在其上,所以我们的内核必须能够访问root文件系统。对于一般用户,如果他们使用ide硬盘上的ext2文件分区作为root文件系统,不会有什么问题。因为不管是ide硬盘还是ext2文件系统,它们的驱动肯定会包含在内核镜像自身里面。但是,确实存在一些特殊情况:比如说我们希望 发行linux系 统的安装光盘,那么对光盘的驱动,就不一定包含在内核里面了。(有人可能要奇怪了,咦,光盘中的内核镜像不都已经读进来了吗,怎么内核还访问不了光盘呢? 注意,读入内核镜像的是 boot loader ,内核并不具备 boot loader 的功能。)如果没有光盘的驱动,我们又怎么把光盘里的软件包安装到用户的 计算机里呢?把驱动程序预先编译到内核里?听起来还不错,可是如果我们除了光盘还有一些其它的安装介质,那么所有这些驱动就会让内核镜像庞大不堪。  而且,还有更严重的问题,各种不同的驱动程序很有可能会发生冲突,特别是以前isa设备占市场主导地位的时候,这种冲突 简直难以避免。  那时的解决办法是发行商提供预先编译好的支持各种设备的不同内核,把每个内核放进一张软盘,随发行 包一起交给用户,用户自己选择装有合适内核的软盘进行引导。或者给用户提供制作引导盘的工具,让用户在安装前制作自己的启动盘。当然,哪一种办法都不能让 人满意。  唯一的希望在于使用模块化机制。在内核启动的时候调用相应的模块加载驱动程序,然后访问root文件系统。无论是通过内核对设备做 进一步的分析还是直接从用户那里得到配置信息,先配置再加载模块的办法,都能有效地避免冲突的发生。  除了在安装的时候需要在挂载root文件系统之前调用相应的模块之外,在完成安装的系统上,我们可能仍然需要在挂载root文件系统之前调用一些模块。这主要 是为给计算机进行配置——一般都要针对不同的计算机进行内核配置。  理想情况下,用户按照自己的实际情况配置编译文件,重新编译内核,一步步完成这种工作。但是没有几个用户喜欢这种冗长并且极易出现错误的工作。而且编译和生成内核需要相应的 工具,可是大部分用户不需要

COPYRIGHT(C) 2011 厦门永宏亚得机电科技有限公司版权所有(闽ICP备05025945号) ALL RIGHTS RESERVED?

电话: 0592-5190891 传真: 0592-5190720 E-Mail: E-mail:yade8895@163.com
地址: 厦门市海沧区兴港六里17号2607室 邮编:361009 联系人:翟先生