电脑启动过程

来源:互联网 发布:linux 进入dracut 编辑:程序博客网 时间:2024/04/29 14:00

        电脑及操作系统的启动过程是一个很复杂的过程,对于我们大多数只是希望把电脑玩的更好一点、处理一些常见问题清晰一点的朋友来说,自然是无需了解到详尽通透——本帖的目的也不在于此。爱好者博墅NSqAW\3?5@K)_A
  可是要想把电脑玩的好一点,比如出现启动故障、想要安装多系统、安装windows类和linux类多系统的话,这个启动过程却又是不能不了解的———但也不用了解到头晕眼花^_^!

 

 (一) windows启动过程

 

从按下机箱电源键开始,直到用户进入操作系统,操作系统正常启动,整个过程可分为以下几个部分。
1. 预引导(Pre-Boot)阶段

2. 引导阶段

3. 加载内核阶段

4. 初始化内核阶段

5. 用户登录阶段

 

预引导阶段
    首先让我们来了解一些基本概念。第一个是大家非常熟悉的BIOS(基本输入输出系统),BIOS是直接与硬件打交道的底层代码,它为操作系统提供了控制硬件设备的基本功能。BIOS包括有系统BIOS(即常说的主板BIOS)、显卡BIOS和其它设备(例如IDE控制器、SCSI卡或网卡等)的BIOS,其中系统BIOS是本文要讨论的主角,因为计算机的启动过程正是在它的控制下进行的。BIOS一般被存放在ROM(只读存储芯片)之中,即使在关机或掉电以后,这些代码也不会消失。
  第二个基本概念是内存的地址,我们的机器中现在一般安装有128MB或256MB甚至更大容量的内存,这些内存的每一个字节都被赋予了一个地址,以便CPU访问内存。32MB的地址范围用十六进制数表示就是0~1FFFFFFH,其中0~FFFFFH的低端1MB内存非常特殊,因为最初的8086处理器能够访问的内存最大只有1MB,这1MB的低端640KB被称为基本内存,而A0000H~BFFFFH要保留给显示卡的显存使用,C0000H~FFFFFH则被保留给BIOS使用,其中系统BIOS一般占用了最后的64KB或更多一点的空间,显卡BIOS一般在C0000H~C7FFFH处,IDE控制器的BIOS在C8000H~CBFFFH处。
    第一步: 当我们按下电源开关时,电源就开始向主板和其它设备供电,此时电压还不太稳定,主板上的控制芯片组会向CPU发出并保持一个RESET(重置)信号,让CPU内部自动恢复到初始状态,但CPU在此刻不会马上执行指令。当芯片组检测到电源已经开始稳定供电了(当然从不稳定到稳定的过程只是一瞬间的事情),它便撤去RESET信号(如果是手工按下计算机面板上的Reset按钮来重启机器,那么松开该按钮时芯片组就会撤去RESET信号),CPU马上就从地址FFFF0H处开始执行指令,从前面的介绍可知,这个地址实际上在系统BIOS的地址范围内,无论是Award BIOS还是AMI BIOS,放在这里的只是一条跳转指令,跳到系统BIOS中真正的启动代码处。
    第二步: 系统BIOS的启动代码首先要做的事情就是进行POST(Power-On Self Test,加电后自检),POST的主要任务是检测系统中一些关键设备是否存在和能否正常工作,例如内存和显卡等设备。由于POST是最早进行的检测过程,此时显卡还没有初始化,如果系统BIOS在进行POST的过程中发现了一些致命错误,例如没有找到内存或者内存有问题(此时只会检查640K常规内存),那么系统BIOS就会直接控制喇叭发声来报告错误,声音的长短和次数代表了错误的类型。在正常情况下,POST过程进行得非常快,我们几乎无法感觉到它的存在,POST结束之后就会调用其它代码来进行更完整的硬件检测。
    第三步: 接下来系统BIOS将查找显卡的BIOS,前面说过,存放显卡BIOS的ROM芯片的起始地址通常设在C0000H处,系统BIOS在这个地方找到显卡BIOS之后就调用它的初始化代码,由显卡BIOS来初始化显卡,此时多数显卡都会在屏幕上显示出一些初始化信息,介绍生产厂商、图形芯片类型等内容,不过这个画面几乎是一闪而过。系统BIOS接着会查找其它设备的BIOS程序,找到之后同样要调用这些BIOS内部的初始化代码来初始化相关的设备。
    第四步: 查找完所有其它设备的BIOS之后,系统BIOS将显示出它自己的启动画面,其中包括有系统BIOS的类型、序列号和版本号等内容。
    第五步: 接着系统BIOS将检测和显示CPU的类型和工作频率,然后开始测试所有的RAM,并同时在屏幕上显示内存测试的进度,我们可以在CMOS设置中自行决定使用简单耗时少或者详细耗时多的测试方式。
    第六步: 内存测试通过之后,系统BIOS将开始检测系统中安装的一些标准硬件设备,包括硬盘、CD-ROM、串口、并口、软驱等设备,另外绝大多数较新版本的系统BIOS在这一过程中还要自动检测和设置内存的定时参数、硬盘参数和访问模式等。
    第七步: 标准设备检测完毕后,系统BIOS内部的支持即插即用的代码将开始检测和配置系统中安装的即插即用设备,每找到一个设备之后,系统BIOS都会在屏幕上显示出设备的名称和型号等信息,同时为该设备分配中断、DMA通道和I/O端口等资源。
  第八步: 到这一步为止,所有硬件都已经检测配置完毕了,多数系统BIOS会重新清屏并在屏幕上方显示出一个表格,其中概略地列出了系统中安装的各种标准硬件设备,以及它们使用的资源和一些相关工作参数。
  第九步: 接下来系统BIOS将更新ESCD(Extended System Configuration Data,扩展系统配置数据)。ESCD是系统BIOS用来与操作系统交换硬件配置信息的一种手段,这些数据被存放在CMOS(一小块特殊的RAM,由主板上的电池来供电)之中。
  通常ESCD数据只在系统硬件配置发生改变后才会更新,所以不是每次启动机器时我们都能够看到“Update ESCD… Success”这样的信息,不过,某些主板的系统BIOS在保存ESCD数据时使用了与Windows系统不相同的数据格式,于是Windows在它自己的启动过程中会把ESCD数据修改成自己的格式,但在下一次启动机器时,即使硬件配置没有发生改变,系统BIOS也会把ESCD的数据格式改回来,如此循环,将会导致在每次启动机器时,系统BIOS都要更新一遍ESCD,这就是为什么有些机器在每次启动时都会显示出相关信息的原因。
  第十步: ESCD更新完毕后,系统BIOS的启动代码将进行它的最后一项工作,即根据用户指定的启动顺序从软盘、硬盘或光驱启动。
  第十一步:以从硬盘盘启动为例,
  1、系统BIOS将磁盘第一个物理扇区加载到内存,读取并执行位于硬盘第一个物理扇区的MBR
    2、接着将系统控制权交给MBR来进行
    3、MBR运行后,搜索MBR中的分区表,查找活动分区(Active Partition)的起始位置
  4、MBR将活动分区的第一个扇区中的引导扇区——分区引导记录载入到内存。
   5、MBR检测当前使用的文件系统是否可用。
  第十二步:主引导记录加载系统启动器(windows loader)
  1、MBR查找ntldr文件,找到之后初始化NTLDR文件启动它——NT内核操作系统的启动器(windows loader)。[I]    注:win98引导 在这个环节,如果硬盘中安装的只有win98系统,已经被加载的win98的分区引导记录(和win2k这样基于NT内核的操作系统不同,DOS和win9x的系统启动器——windows loader就是分区引导记录)将负责读取并执行IO.SYS,这是DOS和Windows 9x最基本的系统文件。Windows 9x的IO.SYS首先要初始化一些重要的系统数据,然后就显示出我们熟悉的蓝天白云,在这幅画面之下,Windows将继续进行DOS部分和GUI(图形用户界面)部分的引导和初始化工作。
    2、MBR将控制权转交给ntldr,由ntldr继续完成操作系统的启动。
  MBR(Master Boot Record)——主引导记录,位于启动磁盘的第一个扇区,其中主要包含引导代码(Boot Code)和分区表(Partition Table)数据。引导代码主要用于引导系统。而分区表则主要用于标识基本分区和扩展分区。
  这整个过程便是计算机在打开电源开关(或按Reset键)进行冷启动时所要完成的各种初始化工作,如果我们在DOS下按Ctrl+Alt+Del组合键(或从Windows中选择重新启动计算机)来进行热启动,那么POST过程将被跳过去,直接从第三步开始,另外第五步的检测CPU和内存测试也不会再进行。我们可以看到,无论是冷启动还是热启动,系统BIOS都一次又一次地重复进行着这些我们平时并不太注意的事情,然而正是这些单调的硬件检测步骤为我们能够正常使用电脑提供了基础。

 

引导阶段 (以XP系统为例,2000和2003大致相同)
  在引导阶段中,Windows XP将会依次经历初始引导加载器阶段、操作系统选择阶段、硬件检测阶段以及配置选择阶段这四个小的阶段。
    初始引导加载器阶段
    1、设置内存使用模式:初始引导加载器阶段中,NTLDR将为Windows NT系统把计算机的微处理器从实模式转换为32位平面内存模式。
    对基于X86CPU的计算机来说,第一次启动的时候总是进入所谓的实模式(RealMode)。在实模式下CPU的某些特性不能完全发挥,这是因为它要保证同8位或16位的CPU(如8086、8088)相兼容。这时系统会为MS-DOS或win 9x这样的16位系统预留640KB大小的内存空间,其余的内存都被看做是扩展内存。
    而实模式下由于系统规格的限制,无法对大容量内存进行直接存取,而必须通过分段的方式完成。对于32位的Windows NT系统来说,8位或16位的CPU显然是无用的。对于32位的Windows NT系统来说,ntldr首先会将CPU切换到32位的模式,从而确保Windows XP的正常,然后设置CPU的运行使用32位的平面内存模式。
  在CPU的32位模式下,可以对大容量内存进行直接存取,可以将所有内存都视为可用内存,而彻底抛弃了原先在8位或16位下分段存取内存的不便。这也是为什么32位模式称作平面(Flat)内存模式的原因。
   2、启动文件系统:NTLDR执行适当的小型文件系统驱动程序(ntldr 中包含相应的代码,能够帮助Windows XP完成对NTFS或FAT格式的磁盘进行读写。从而能够读取、访问和复制文件。),这时NTLDR可以识别每一个用NTFS或FAT格式的文件系统分区,至此初始引导加载器阶段结束。
    操作系统选择阶段
  当初始引导加载器阶段结束后将会进入操作系统选择阶段,NTLDR在活动分区根目录寻找并加载Boot.ini文件。(呵呵,这里贴的是我的机子上的boot.ini,搜集的资料中的boot.ini只有XP一项,所以贴上我的,丰富一点 o0_0o注)
  在我的boot.ini中,包含以下内容:
[boot loader]
timeout=5
default=multi(0)disk(0)rdisk(0)partition(4)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(4)\WINDOWS="Windows XP Media Center Edition" /noexecute=optin /fastdetect
multi(0)disk(0)rdisk(0)partition(3)\WINNT="Microsoft Windows 2000 Advanced Server" /fastdetect
C:\BOOTSECT.DOS="WINDOWS 98 SE"
C:\CHAIN0="MAC OS X 86PC"
C:\GHLDR="一键GHOST v2006.03.12"
    其中,multi(0)表示磁盘控制器,disk(0)rdisk(0)表示磁盘,partition(x)表示分区。NTLDR就是从这里查找Windows XP Professional的系统文件的位置的。(*本文不会更详细地讲解boot.ini的组成结构,因为其与本主题关系不大,如果想了解,可以到一些专门的网站处查询相关信息。)
  如果计算机上安装了不止一个操作系统(也就是多系统),而且正确设置了boot.ini ,BOOT.INI 文件里面将含有两个或两个以上的启动选项,如果只有一个操作系统,Boot.ini文件中将只有一个操作系统的启动选项。在Boot.ini中只有一个启动选项或其中的超时值为0时,将不会出现选择操作系统的菜单画面。否则NTLDR将把Boot.ini中的所有启动项显示在屏幕上——这就是要求选择操作系统的多操作系统启动菜单,这时NTLDR 暂停系统引导,并且按照Boot.ini文件中的超时值开始读秒,等待用户选择一个启动选项直至超时。超时值由BOOT.INI 里面的TimeOut 值设定。
  读秒超时以后,NTLDR 读取BOOT.INI里面DEFAULT 后面的信息,获取默认启动项对应的Windows 目录的路径以便执行后面的启动流程。
  选择要启动的操作系统后,NTLDR 读取BOOT.INI里面相应启动项的位置信息,获取启动项对应的Windows 目录的路径以便执行后面的启动流程。
  如果选择的启动选项是一个NT内核系统, NTLDR将会加载运行同目录下的NTDETECT.COM文件。
  如果选择启动旧式的微软操作系统,如MS-DOS、Windows 9x/ME,NTLDR将按照Boot.ini中该启动项的信息加载BOOTSECT.DOS,然后ntldr会从bootsect.dos文件中读取MBR代码,然后将控制权交给bootsect.dos中的MBR(BOOTSECT.DOS由NT内核操作系统的安装程序在安装操作系统时读取活动分区中已经存在的DOS或win9x系统的分区引导记录来转换生成)。
  如果选择了其它类别的操作系统,NTLDR将按照该启动项在Boot.ini中的启动配置进行加载(如我的Boot.ini中的C:\CHAIN0)
  如果Boot.ini文件非法或不存在,那么NTLDR将会尝试从默认系统卷启动系统。
  这里解释一下我的boot.ini。C:\BOOTSECT.DOS="WINDOWS 98 SE",大家都知道啦!C:\CHAIN0="MAC OS X 86PC",是我机子上安装的苹果的Tiger 10.4.5操作系统,CHAIN0像上边说的bootsect.dos一样,也是一个引导启动的转储文件。C:\GHLDR="一键GHOST v2006.03.12",安装的DOS之家的"一键恢复GHOST ",同上边一样,GHLDR也是这个工具的一个引导启动的转储文件。看到这里,你应该比较明白一点了吧?
  比如你装了Linux,使用工具把Linux的引导扇区记录做成转储文件,然后放到NTLDR所在的分区根目录,然后再在boot.ini里添加相应的启动项,在开机的多启动菜单里选择这个启动选项,NTLDR一样可以成功启动Linux。
  我的第一个分区是活动分区(主分区),装的是98;第二个分区是一个MAC系统格式的主分区,安装的是MAC Tiger 10.4.5; 2000 Advanced Server装在扩展分区中的第一个逻辑分区;XP Media Center Edition装在扩展分区中的第二个逻辑分区。
  其实引导启动的程序有很多,不过我们常用的是windows的Loader罢了。Linux下常用的启动器是Grub,其它常见的第三方工具有System Commander、Bootmanager BootStar等等。
  1、NTLDR启动后,如果在系统根目录下发现有Hiberfil.sys文件且该文件有效,那么NTLDR将读取Hiberfil.sys文件里的信息并让系统恢复到休眠以前的状态,这时并不处理Boot.ini文件。Hiberfil.sys文件是在XP系统启用休眠时生成的内存转储文件。
  2、BOOTSECT.DOS:OS或Windows 9x系统启动扇区的转储文件。文件由Windows NT 安装程序创建,一般为512 字节。
  3、Windows NT 架构操作系统:指在Windows NT 操作系统上发展起来的操作系统,目前主流的有:Windows 2000、WindowsXP 和Windows Server 2003 等。
  4、NTLDR 的兼容性:NTLDR 具有向下兼容性。高版本的NTLDR 能够启动低版本的Windows NT 操作系统。目前最新版本的NTLDR 是在Windows Server 2003附带的版本。所以安装多系统时要按照从低到高的版本顺序。比如装了XP之后再装2000,2000会用自己的NTLDR来覆盖原有的XP的NTLDR,这时XP就不能启动了——2000的NTLDR不能引导XP以及比XP更高版本的系统。
  5、从Windows XP with Service Pack 2 开始,操作系统安装程序在安装的时候将检测硬盘上活动分区中NTLDR和NTDETECT.COM的版本,如果发现现有的版本比安装源上的版本新的话,将使用现有版本而不使用安装源上的版本。
  如果选择启动NT内核系统操作系统,在加载NTDETECT.COM文件后,硬件检测阶段开始。
  在处理完boot.ini文件之后,ntldr会启动ntdetect.com程序。在基于X86的系统中,ntdetect.com会通过调用系统固件程序收集安装的硬件信息,然后由ntdetect.com将收集的计算机硬件信息列表并将列表返回到ntldr。这样做的目的是便于以后将这些硬件信息加入到注册表HKEY_LOCAL_MACHINE下的hardware中。
  Ntdetect.com 会收集如下类型的硬件信息:
  & 系统固件信息,例如时间和日期等
  & 总线适配器的类型
  & 显卡适配器的类型
   & 键盘
  & 通信端口
  & 磁盘
   & 软盘
   & 输入设备,例如鼠标
  & 并口
  & 安装在ISA槽中的ISA设备
    配置选择阶段
  硬件检测完成后,进入配置选择阶段。Ntldr获取系统内的硬件配置文件,如果计算机含有多个硬件配置文件列表,可以通过按上下按钮来选择。如果只有一个硬件配置文件,计算机不显示此屏幕而直接使用默认的配置文件加载ntoskrnl.exe 程序——Windows XP内核。检测硬件和配置硬件阶段结束
  至此,整个引导阶段结束
  在引导阶段,系统要用到的文件一共有:NTLDR,Boot.ini,ntdetect.com,ntokrnl.exe,Ntbootdd.sys,bootsect.dos(可选的,如果已经有的情况下),这些文件默认的位置都在活动分区的根目录下。
    注:如果在启动的时候按F8键,那么我们将会在启动菜单中看到多种选择启动模式,这时NTLDR将根据用户的选择来使用启动参数加载NT内核,用户也可以在Boot.ini文件里设置启动参数。

加载内核阶段
  Ntldr获取从ntdetect.com发来的信息后,将这些信息组织成为内部结构形式,然后由ntldr 启动ntoskrnl.exe程序,并将这些信息和boot.ini文件中的信息,以及注册表中的硬件和软件信息传递给ntoskrnl.exe 程序——Windows XP内核。
  1、将内核(ntoskrnl.exe)和硬件抽象层(hal.dll)载入到内存
  在加载内核阶段,ntldr加载称为内核的ntokrnl.exe,但是没有将它初始化。 接着ntldr加载硬件抽象层(HAL,hal.dll)。
  2、加载控制集信息
  在这一过程中,ntldr从注册表中HKEY_LOCAL_MACHINE\SYSTEM的位置读取select键来决定哪一个控制集(Control Set)信息将被加载,并确定在启动过程中要加载的设备驱动。控制集中包含设备的驱动程序以及需要加载的服务。
  3、加载设备驱动程序和服务
  在这一步中,系统会在BIOS的帮助下开始加载设备驱动程序,以及服务。
  设备驱动程序,NTLDR将加载HKEY_LOCAL_MACHINE\system\service\...下start键值为0的最底层设备驱动。
  当作为Control Set的镜像的Current Control Set被加载时,NTLDR将把控制权传递给Windows XP内核NTOSKRNL.EXE。
  至内核加载阶段结束,接下来是初始化内核阶段。

 

初始化内核阶段
  在初始化内核阶段开始的时候,彩色的Windows XP的logo以及进度条显示在屏幕中央,在这个阶段,系统完成了启动的4项任务:
  1、内核使用在硬件检测时收集到的数据来创建了HKEY_LOCAL_MACHINE\HARDWARE键。
  2、内核通过引用HKEY_LOCAL_MACHINE\system\Current的默认值复制Control Set来创建了Clone Control Set。Clone Control Set配置是计算机数据的备份,不包括启动中的改变,也不会被修改。
  3、系统完成初始化以及加载设备驱动程序
  内核初始化那些在加载内核阶段被加载的底层驱动程序,然后内核扫描HKEY_LOCAL_MACHINE\system\CurrentControlSet\service\...下start键值为1的设备驱动程序。这些设备驱动程序在加载的时候便完成初始化,如果有错误发生,内核使用ErrorControl键值来决定如何处理。
  start键值为3时,错误标志为危机/关键,系统初次遇到错误会以LastKnownGood Control Set重新启动,如果使用LastKnownGood Control Set启动仍然产生错误,系统报告启动失败,错误信息将被显示,系统停止启动;
  值为2时错误情况为严重,系统启动失败并且以LastKnownGood Control Set重新启动,如果系统启动已经在使用LastKnownGood值,它会忽略错误并且继续启动;
  当值是1的时候错误为普通,系统会产生一个错误信息,但是仍然会忽略这个错误并且继续启动;当值是0的时候忽略,系统不会显示任何错误信息而继续运行 。
    4、启动会话管理器Session Manager
  内核会启动会话管理器(Session Manager),这是一个名为smss.exe 的程序,其作用表现如下:
  (1)创建系统环境变量
  (2)创建虚拟内存页面文件
  (3)启动了Windows XP高级子系统以及服务
   (4)启动了控制所有输入、输出设备以及访问显示器屏幕Win32子系统
    初始化内核完毕。


 用户登录阶段
  在这一过程中,Windows 子系统会启动winlogon.exe,这是一个系统服务,用于提供对Windows 用户的登录和注销的支持。Winlogon.exe 可以完成如下一些工作:
  1、启动服务子系统(services.exe),也称服务控制管理器(Service Control Manager, SCM)。
  2、启动本地安全授权(Local Security Authority , LSA)过程(lsass.exe),同时Windows XP Professional欢迎屏幕或者登陆对话框显示,这时候,系统还可能在后台继续初始化刚才没有完成的驱动程序
  3、在开始登录提示的时候,对Crtl+Alt+Del组合键进行分析处理。
  4、调用一个图形化的识别和认证组件提示输入有效的用户名或密码,收集用户的帐号和密码,然后将这些信息安全地传送给LSA以进行认证处理。如果用户提供的信息是正确的,能够通过认证,就允许用户对系统进行访问。 这时用户成功登录操作系统。
  要注意的是,如果您的计算机中,只有Administrator这一个用户,那么在欢迎屏幕中就会显示Administrator 用户项。如果您的计算机中不仅有Administrator用户,还有别的可以交互登录的用户,那么欢迎屏幕中就只显示出Administrator之外的用户,而不显示Administrator用户。
  如果用户希望以Administrator用户登录,该怎么办呢?实际很简单,直接在欢迎屏幕中按下两次Crtl+Alt+Del组合键,即可打开标准的登录窗口,可以再输入Administrator 的用户名和密码,以便用最高管理员的身份登录。
  Service Controller最后执行以及扫描HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servives来检查是否还有服务需要加载,Service Controller查找start键值为2或更高的服务,服务按照start的值以及DependOnGroup和DepandOnService的值来加载。
  即插即用设备的检测过程
  对即插即用设备的检测,实际上是和登录过程异步进行的。由系统固件、硬件、设备驱动和系统特性决定了Windows XP如何对新设备进行检测和枚举。当即插即用组件正常工作后,Windows XP会对新设备进行检测,为它们分配系统资源,并在尽量不要用户提供选择的情况下,为新设备安装一个合适版本的驱动程序。
    启动完成
  只有用户成功登陆到计算机后,Windows XP的启动才被认为是完成,在成功登陆后,系统拷贝Clone Control Set到LastKnownGood Control Set,完成这一步骤后,系统才意味着已经成功引导了。

 

(二)Linux启动过程

 

Linux系统启动过程大致按照如下步骤进行(这是一个简述):
第一阶段:BIOS启动引导阶段;
                        在该过程中实现硬件的初始化以及查找启动介质;
                        从MBR中装载启动引导管理器(GRUB)并运行该启动引导管理
第二阶段:GRUB启动引导阶段;
                        装载stage1
                        装载stage1.5
                        装载stage2
                        读取/boot/grub.conf文件并显示启动菜单;
                        装载所选的kernel和initrd文件到内存中
第三阶段:内核阶段:
                        运行内核启动参数;
                        解压initrd文件并挂载initd文件系统,装载必须的驱动;
                        挂载根文件系统
第四阶段:Sys V init初始化阶段:
                        启动/sbin/init程序;
                        运行rc.sysinit脚本,设置系统环境,启动swap分区,检查和挂载文件系统;
                        读取/etc/inittab文件,运行在/et/rc.d/rc<#>.d中定义的不同运行级别的服务初始化脚本;
                        打开字符终端1-6号控制台/打开图形显示管理的7号控制台

同时在上述过程中各阶段所需要读取的文件和操作的对象:
BIOS启动引导阶段                          GRUB启动引导阶段                    内核阶段                            /init/sysinit阶段
==================================================================================================
None                                         /boot/grub/grub.conf               /boot/vmlinuz-<version>      /etc/rc.d/rc.sysinit
                                                /boot/grub/stage1_5               /boot/initrd-<version>         /etc/inittab
                                                /boot/grub/stage2                                                         /etc/rc.d/rc<#>.d
                                                                                                                                 /etc/rc.d/init.d/*
                                                                                                                                             

 

(下面是详细的过程)                                                                                                                     
第一阶段:
系统上电开机后,主板BIOS(Basic Input / Output System)运行POST(Power on self test)代码,检测系统外围关键设备(如:CPU、内存、显卡、I/O、键盘鼠标等)。硬件配置信息及一些用户配置参数存储在主板的CMOS( Complementary Metal Oxide Semiconductor)上(一般64字节),实际上就是主板上一块可读写的RAM芯片,由主板上的电池供电,系统掉电后,信息不会丢失。
执行POST代码对系统外围关键设备检测通过后,系统启动自举程序, 根据我们在BIOS中设置的启动顺序搜索启动驱动器(比如的硬盘、光驱、网络服务器等)。选择合适的启动器,比如通常情况下的硬盘设备,BIOS会读取硬盘设备的第一个扇区(MBR,512字节),并执行其中的代码。实际上这里BIOS并不关心启动设备第一个扇区中是什么内容,它只是负责读取该扇区内容、并执行,BIOS的任务就完成了。此后将系统启动的控制权移交到MBR部分的代码。
注: 在我们的现行系统中,大多关键设备都是连在主板上的。因此主板BIOS提供了一个操作系统(软件)和系统外围关键设备(硬件)最底级别的接口,在这个阶段,检测系统外围关键设备是否“准备好”,以供操作系统使用。

第二阶段:
BIOS通过下面两种方法之一来传递引导记录:
第一,        将控制权传递给initial program loader(IPL),该程序安装在磁盘主引导记录(MBR)中
第二,        将控制权传递给initial program loader(IPL),该程序安装在磁盘分区的启动引导扇区中
无论上面的哪种情况中,IPL都是MBR的一部分并应该存储于一个不大于446字节的磁盘空间中,因为MBR是一个不大于512字节的空间。
因此IPL仅仅是GRUB的第一个部分(stage1),他的作用就是定位和装载GRUB的第二个部分(stage2);stage2对启动系统起关键作用,该部分提供了GRUB启动菜单和交互式的GRUB的shell。启动菜单在启动时候通过/boot/grub/grub.conf文件所定义的内容生成。在启动菜单中选择了kernel之后,GRUB会负责解压和装载kernel image并且将initrd装载到内存中。最后GRUB初始化kernel启动代码。
完成之后后续的引导权被移交给kernel。

假设Boot Loader为grub (grub-0.97),其引导系统的过程如下:
grub分为stage1 (stage1_5) 和stage2两个阶段。stage1可以看成是initial program loaderI(IPL),而stage2则实现了grub的主要功能,包括对特定文件系统的支持(如ext2,ext3,reiserfs等),grub自己的shell,以及内部程序(如:kernrl,initrd,root)等。
stage 1:MBR(512 字节,0头0道1扇区),前446字节存放的是 stage1,后面存放硬盘分区表信息,BIOS将stag1载入内存中0x7c00处并跳转执行。stage1(/stage1/start.S)的任务非常单纯,仅仅是将硬盘0头0道2扇区读入内存。0头0道2扇区内容是源代码中的/stage2/start.S,编译后512字节,它是stage2或者stage1_5的入口。
注:此时stage1是没有能力识别文件系统的,其定位硬盘0头0道2扇区过程如下:
BIOS将stage1载入内存0x7c00处并执行,然后调用BIOS INIT13中断,将硬盘0头0道2扇区内容载入内存0x7000处,然后调用copy_buffer将其转移到内存0x8000处。定位0头0道2扇区有两种寻址方式:LBA、CHS。
start.S的主要功能是将stage2或stage1_5从硬盘载入内存,如果是stage2,则载入0x820处;如果是 stage1_5,则载入0x2200处。
注:这里的stage2或者stage1_5不是/boot分区/boot/grub目录下的文件,这个时候grub还没有能力识别任何文件系统。分以下两种情况:
(1)假如start.S读取的是stage1_5,它存放在硬盘0头0道3扇区向后的位置,stage1_5作为stage1和stage2中间的桥梁,stage1_5有识别文件系统的能力,此后grub才有能力去访问/boot分区/boot/grub目录下的 stage2文件,将stage2载入内存并执行。
(2)假如start.S读取的是stage2,同样,这个stage2也不是/boot分区/boot/grub目录下的stage2,这个时候start.S读取的是存放在/boot分区Boot Sector的stage2。这种情况下就有一个限制:因为start.S通过BIOS中断方式直接对硬盘寻址(而非通过访问具体的文件系统),其寻址范围有限,限制在8GB以内。因此这种情况需要将/boot分区分在硬盘8GB寻址空间之前。
假如是情形(2),我们将/boot/grub目录下的内容清空,依然能成功启动grub;假如是情形(1),将/boot/grub目录下stage2删除后,则系统启动过程中grub会启动失败。
这个地方经常要进行的操作:
是关于grub常用的几个指令对应的函数:
grub>root (hd0,0)                                                                                                --root指令为grub指定了一个根分区
grub>kernel /xen.gz-2.6.18-37.el5                                                                          --kernel指令将操作系统内核载入内存
grub>module /vmlinuz-2.6.18-37.el5xen ro root=/dev/sda2                                          --module指令加载指定的模块
grub>module /initrd-2.6.18-37.el5xen.img                                                                 --指定initrd文件
grub>boot                                                                                                          --boot 指令调用相应的启动函数启动OS内核


第三阶段:
如阶段2所述,grub>boot指令后,系统启动的控制权移交给kernel。Kernel会立即初始化系统中各设备并做相关配置工作,其中包括CPU、I/O、存储设备等。
关于设备驱动加载,有两部分:一部分设备驱动编入Linux Kernel中,Kernel会调用这部分驱动初始化相关设备,同时将日志输出到kernel message buffer,系统启动后dmesg可以查看到这部分输出信息。另外有一部分设备驱动并没有编入Kernel,而是作为模块形式放在initrd(ramdisk)中。
在2.6内核中,支持两种格式的initrd,一种是2.4内核的文件系统镜像image-initrd,一种是cpio格式。以 cpio 格式为例,内核判断initrd为cpio的文件格式后,会将initrd中的内容释放到rootfs中。
initrd是一种基于内存的文件系统,启动过程中,系统在访问真正的根文件系统/时,会先访问initrd文件系统。将initrd中的内容打开来看,会发现有bin、devetc、lib、procsys、sysroot、init等文件(包含目录)。其中包含了一些设备的驱动模块,比如scsi ata等设备驱动模块,同时还有几个基本的可执行程序 insmod, modprobe, lvm,nash。主要目的是加载一些存储介质的驱动模块,如上面所说的scsi ideusb等设备驱动模块,初始化LVM,把/根文件系统以只读方式挂载。
initrd中的内容释放到rootfs中后,Kernel会执行其中的init文件,这里的init是一个脚本,由nash解释器执行。这个时候内核的控制权移交给init文件处理,我们查看init文件的内容,主要也是加载各种存储介质相关的设备驱动。
驱动加载后,会创建一个根设备,然后将根文件系统/以只读的方式挂载。这步结束后释放未使用内存并执行switchroot,转换到真正的根/上面去,同时运行/sbin/init程序,开启系统的1号进程,此后系统启动的控制权移交给 init 进程。关于switchroot是在nash中定义的程序。
Linux Kernel需要适应多种不同的硬件架构,但是将所有的硬件驱动编入Kernel又是不实际的,而且Kernel也不可能每新出一种硬件结构,就将该硬件的设备驱动写入内核。实际上Linux Kernel仅是包含了基本的硬件驱动,在系统安装过程中会检测系统硬件信息,根据安装信息和系统硬件信息将一部分设备驱动写入 initrd 。这样在以后启动系统时,一部分设备驱动就放在initrd中来加载。

第四阶段:
init进程起来后,系统启动的控制权移交给init进程。
/sbin/init进程是所有进程的父进程,当init起来之后,它首先会读取配置文件/etc/inittab,进行以下工作:
1)执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本的配置,以读写方式挂载根文件系统及其它文件系统,到此系统基本算运行起来了,后面需要进行运行级别的确定及相应服务的启动;
2)确定启动后进入的运行级别;
3) 执行/etc/rc.d/rc,该文件定义了服务启动的顺序是先K后S,而具体的每个运行级别的服务状态是放在/etc/rc.d/rcn.d(n=0~6)目录下,所有的文件均链接至/etc/init.d下的相应文件。
4)有关key sequence的设置
5) 有关UPS的脚本定义
6)启动虚拟终端/sbin/mingetty
7)在运行级别5上运行X
这时呈现给用户的就是最终的登录界面。
至此,系统启动过程完毕:)
说明:
1)/etc/rc.d/rc.sysint -- System Initialization Tasks
它的主要工作有:
配置selinux,
系统时钟,
内核参数(/etc/sysctl.conf),
hostname,
启用swap分区,
根文件系统的检查和二次挂载(读写),
激活RAID和LVM设备,
启用磁盘quota
检查并挂载其它文件系统
等等。

GRUB的基本原理以及对GRUB的操作控制方法:
GRUB全称为Grand Unified Boot Loader,是Linux操作系统主流的启动引导管理器。主要作用是启动和装载Linux操作系统。系统启动过程中一旦完成了BIOS自检,GRUB会被立刻装载。在GRUB里面包含了可以载入操作系统的代码以及将操作系统引导权传递给其他启动引导管理器的代码。GRUB可以允许用户选择使用不同的kernel启动系统,或者在启动系统的过程中设置不同的启动参数。
而通常BIOS会以下面两种方法之一来调用启动引导管理器:
将控制权移交给于驱动器主引导记录的initial program loader(IPL);
将控制权移交给其他启动引导管理器,再由他们将控制权移交给安装在分区引导扇区的IPL
通常情况下启动引导管理器GRUB由两部分组成(stage1和stage2):
stage1比较小,通常可以驻留在MBR或者各个磁盘分区的启动扇区中,主要作用是装载stage2。
stage2比较大,从磁盘的启动引导分区读取
至于在stage1和stage2之间存在一个stage1.5,是因为starge1.5具有识别文件系统的能力。
在Linux系统中对GRUB的配置有两种方法:
主要引导管理器:
会将启动引导管理器的stage1安装在MBR上,这时启动引导管理器必须被配置为可以传递控制权到其他操作系统;
次要引导管理器:
会将启动引导管理器的stage1安装在一些分区的引导扇区上,而其他的启动引导管理器会被安装在MBR上,由他们来向Linux启动引导管理器传递控制权。
GRUB在启动过程中可以提供命令行交互界面,可以从ext系列,reiserfs,fat等多种文件系统引导系统,并且可以提供密码加密功能,其内容在/boot分区下,系统启动过程中由配置文件/boot/grub/grub.conf来定义启动方式,对该配置文件的更改会立即生效。
在配置文件/boot/grub/grub.conf文件中定义的内容包括:
grub所在的分区,引导系统所使用的kernel文件位置,硬件初始化使用的initrd文件位置,以及启动参数。
例如:
grub>root (hd0,0)                                                                                         --root指令为grub指定了一个根分区
grub>kernel /xen.gz-2.6.18-37.el5                                                                   --kernel指令将操作系统内核载入内存
grub>module /vmlinuz-2.6.18-37.el5xen ro root=/dev/sda2                                   --module指令加载指定的模块
grub>module /initrd-2.6.18-37.el5xen.img                                                          --指定initrd文件
grub>boot                                                                                                   --boot 指令调用相应的启动函数启动OS内核

可见其指定的内容大多数在/boot分区,如果切换到/boot分区之后会看到这些内容:
/boot/vmlinuz-*                 linux kernel的一个copy;
/boot/initrd*.img                初始化的ram disk文件
/boot/grub/device.map        linux设备名和grub设备名的映射文件
/boot/grub/grub.conf          主配置文件

通常GRUB出错几率不是很大,但一旦出现问题恐怕采用最多的方式是重装grub到MBR中。
在这种时候需要注意的问题有:
首先,设备映射关系:
GRUB里面对设备名称的定义和系统中对设备名称的定义方法不一样:
        (fd0)                /dev/fd0
        (hd0)                /dev/sda        /dev/hda
        (hd1)                /dev/sdb        /dev/hdb
如够进入系统或者救援模式,可执行命令/sbin/grub-install /dev/sda(或者hda)进行GRUB重装:
        # /sbin/grub-install device
处于某种原因MBR中信息出错可以使用上面的命令将其重装到磁盘主引导记录中;但是如果在不能进入系统的情况下就需要通过grub的命令行界面进行手动设置,这个时候就要注意上面所提到的映射关系。

同时,在grub命令行中对grub进行手动设置的时候需要注意所使用的命令:
        # root (hd0,0)                                --指定启动分区
        # setup(hd0)                                  --表示将grub安装在主引导记录上
        # quit                                              --退出grub        shell

下面是一个完整的grub.conf文件内容:
[root@dhcp-0-195 ~]# cat /etc/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/VolGroup001/LogVol00
#          initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=30
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$apEcJWbA$DTJ8a6mKn/3yrTTSXBtdH0
title Red Hat Enterprise Linux Client (2.6.18-8.1.1.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-8.1.1.el5 ro root=/dev/VolGroup001/LogVol00 crashkernel=128M@16M
        initrd /initrd-2.6.18-8.1.1.el5.img

系统启动运行级别的概念以及服务的定制方法;
当initrd可以正常检测和装载之后,最后的工作就基本上由操作系统来进行了。当系统的init进程起来之后系统启动的控制权移交给init进程。
/sbin/init进程是所有进程的父进程,当init起来之后,它首先会读取配置文件/etc/inittab,进行以下工作:
1)执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本的配置,以读写方式挂载根文件系统及其它文件系统,后面需要进行运行级别的确定及相应服务的启动,(从这个角度可以看出如果要定义系统的init动作,需要修改/etc/rc.d/rc.sysinit脚本)
2)通过对/etc/inittab文件的读取确定启动后进入的运行级别;
3) 在相应的运行级别中执行/etc/rc.d/rcx.d目录下的脚本名称,该文件定义了服务启动的顺序是先K后S,而具体的每个运行级别的服务状态是放在/etc/rc.d/rcn.d(n=0~6)目录下,但这些文件均是到/etc/init.d下的相应文件的链接。
系统会按照在该目录下的文件名称和优先级执行对应运行级别目录下的脚本:
在某个运行级别的对应目录下,K开头的服务被关闭,S开头的服务被开启,K在S开始之前执行,在执行过程中按照数字来定义优先级,数字越低优先级越高。
4)按照/etc/rc.d/rcX.d目录中的定义,系统会于后台启动相应的服务,如果要对某个运行级别中的服务进行更具体的定制,通过chkconfig命令来操作,或者通过setup/ntsys/system-config-services来进行定制。
5)在/etc/inittab文件中存在有关key sequence,UPS的脚本定义,启动虚拟终端/sbin/mingetty的设置,这时呈现给用户的就是最终的登录界面。
也就是说后台启动的服务完毕之后,如果系统默认进入字符界面,则运行mgetty进入1-6号终端控制台,如果系统默认进入图形界面,则开启gdm服务进入7号虚拟图形控制台。
至此,系统启动过程完毕。

对于/etc/rc.d/rc.sysinit文件的说明:
/etc/rc.d/rc.sysint -- System Initialization Tasks 执行系统初始化任务的脚本。
它的主要工作有:
配置selinux,
系统时钟,
内核参数(/etc/sysctl.conf),
hostname,
启用swap分区,
根文件系统的检查和二次挂载(读写),
激活RAID和LVM设备,
启用磁盘quota
检查并挂载其它文件系统

这是其基本要实现的工作内容:
#!/bin/bash
#
# /etc/rc.d/rc.sysinit - run once at boot time
#
# Taken in part from Miquel van Smoorenburg's bcheckrc.


# Check SELinux status
               
# Because of a chicken/egg problem, init_crypto must be run twice.  /var may be
# encrypted but /var/lib/random-seed is needed to initialize swap.

# Only read this once.

# Initialize hardware

# Set default affinity

# Load other user-defined modules

# Load modules (for backward compatibility with VARs)

# Start the graphical boot, if necessary; /usr may not be mounted yet, so we
# may have to do this again after mounting

# Configure kernel parameters

# Set the hostname.

# Initialize ACPI bits

# RAID setup

# Device mapper & related initialization

# Update quotas if necessary

# Remount the root filesystem read-write.

# Clean up SELinux labels

# Clear mtab

# Remove stale backups

# Enter mounted filesystems into /etc/mtab

# Mount all other filesystems (except for NFS and /proc, which is already
# mounted). Contrary to standard usage,
# filesystems are NOT unmounted in single user mode.

# Check to see if a full relabel is needed

# Start the graphical boot, if necessary and not done yet.

# Initialize pseudo-random number generator

# Use the hardware RNG to seed the entropy pool, if available

# Configure machine if necessary.

# Clean out /.

# Do we need (w|u)tmpx files? We don't set them up, but the sysadmin might...

# Clean up /var.  I'd use find, but /usr may not be mounted.

# Reset pam_console permissions

# Clean up utmp/wtmp

# Clean up various /tmp bits

# Make ICE directory

# Start up swapping.