Linux操作系统启动流程

开机的程序是这样的:
1. 加载 BIOS 的硬件信息,并取得第一个开机装置的代号;
2. 读取第一个开机装置的 MBR 的 boot Loader (亦即是 lilo, grub, spfdisk 等等) 的开机信息;
3. 加载 Kernel 操作系统核心信息, Kernel 开始解压缩,并且尝试驱动所有硬件装置;
4. Kernel 执行 init 程序并取得 run-level 信息;
5. init 执行 /etc/rc.d/rc.sysinit 档案;
6. 启动核心的外挂模块 (/etc/modprobe.conf);
7. init 执行 run-level 的各个批次档( Scripts );
8. init 执行 /etc/rc.d/rc.local 档案;
9. 执行 /bin/login 程序,并等待使用者登入;
10. 登入之后开始以 Shell 控管主机。

电脑家电后,首先是启动BIOS程序,BIOS自检完成后,找到硬盘上的主引导记录MBR,MBR读取GPT(分区表),从中找出活动的主分区,然后读取活动分区的PBR(分区引导记录),PBR再搜寻分区内的启动管理器文件bootmgr,在bootmgr被找到后,控制权就交给了bootmgr。bootmgr读取\boot\bcd文件(BCD=Boot Configuration Data,也就是启动配置数据,简单地说,Windows7下的bcd文件就相当于xp下的boot.ini文件)。Bootmgr首先从BCD中读取启动管理器bootmgr菜单的语言版本信息,然后再调用Bootmgr与相应语言的BOOTMGR.EXE.MUI(在boot文件夹对应语言文件夹中)组成相应语言的启动菜单,之后在显示器上显示多操作系统选择画面。如果存在着多个操作系统并且选择操作系统的等待时间不为0的话,这是就会在显示器上显示操作系统的选择界面。在我们选择启动Win7后,bootmgr就会去启动盘寻找Windows\System32\winload.exe,然后通过winload.exe加载windows7内核,从而启动整个Windows7系统。可以把这个启动流程简单的概括为:

BIOS –> MBR –> GPT –> PBR –> Bootmgr –> bcd –> Winload.exe –> 内核加载 –> 整个Windows7系统

电脑启动过程详细版本:
1.按下开机电源,电源向主板和其他设备供电,此时电压不稳,主板控制芯片会向CPU发送并保持RESET(复位)信号,让CPU初始化。当电源开始稳定后,芯片组撤去RESET信号。CPU会从FFFF0h处执行指令,此处为一条跳转指令,是CPU跳转到系统BIOS的启动代码处。
2.系统的BIOS的的启动代码首先进行POST(加电自检)。POST主要对一些关键硬件进行检查。如显卡,内存,主板等。由于此处在显卡初始化之前,所以图像无法显示,如果检查出错只能通过声音报错。
3.接着系统BIOS查找显卡BIOS(通常地址C0000H处),找到后调用它的初始化代码,由显卡BIOS完成显卡的初始化,此处会在屏幕上显示显卡信息,厂商,显卡容量等。
4.接着系统BIOS会查找其他设备的BIOS,并调用他们的初始化代码。
5.接着系统BIOS检查CPU类型,工作频率,并显示检查结果。之后系统BIOS检测内存并显示信息。
6.内存测试通过后,检测其他安装的硬件设备。包括:硬盘,CD-ROM,串行接口,并行接口等。
7.标准设备检查完后,系统BIOS内部的支持即插即用的代码检测和配置系统中安装的即插即用设备,每检测到一个,系统BIOS在屏幕上显示该设备信息,同时为设备分配中断,DMA通道和I/O端口资源。
8.到此,硬件设备检测完毕,系统BIOS会重新清屏并在屏幕上显示一个系统配置表,其中概略列出系统中安装的各种标准硬件设备,及他们使用的资源和一些相关参数。
9.接下来系统BIOS更新ESCD(扩展系统配置数据)。ESCD是系统BIOS用来与操作系统交换硬件配置信息的数据,存放在CMOS中。通常ESCD数据只有在硬件配置改变时才更新。
10.ESCD更新完毕后,系统BIOS根据用户指定的启动顺序从指定设备启动(加载MBR到7c00h处,同时会把设备的驱动号给dl,这点很重要)。

MBR的构成:446字节的引导代码 + 64字节的4个分区表 + 0xAA55引导区标志

硬盘分区表中每个分区表的第一个字节表示该区是否为活动分区。0x00表示非活动分区;80表示活动分区。

在计算机概论里边降到了BIOS和CMOS两个东西。其中CMOS是记录各项硬件参数且嵌入在主板上面的存储器,BIOS则是一个写入到主板上的一个韧体(韧体就是写入到硬件上的一个软件程序)。这个BIOS就是开机的时候计算机系统会主动执行的第一个程序。

简单说,在开机启动流程中的各个环节如下描述:
BIOS : 开机主动执行的韧体,会认识到第一个可开机的设备。
MBR : 第一个可开机设备的第一个扇区中的主引导分区块,内包含引导加载程序。
引导加载程序(Boot loader) : 一支可读取内核文件来执行的软件。
内核文件 : 开始操作系统的功能。

需要说明的是BIOS和MBR都是硬件本身会支持的功能,至于Boot Loader则是操作系统安装在MBR上面的一套软件。Boot loader的主要任务是以下项目:
提供菜单:用户可以选择不同的开机选项,这是多重引导的重要功能。
载入内核文件:直接指向可开机的程序段来开始操作系统。
转交其他Loader:间引导加载功能转交给其他的loader负责。

引导加载程序除了可以安装在MBR之外,还可以安装在每个分区的引导扇区中。

总结:
1.每个分区都有自己的启动分区。
2.bootloader只会认识自己的系统分区内的可开机内核文件,以及其他的loader而已。
3.loader可直接指向或者间接将管理权交给另一个管理程序。

为什么人家常说”如果要安装多重引导,最好先安装windows再安装Linux呢”?
因为安装linux时,你可以选择将引导加载程序安装在MBR或个别分区的启动扇区,而且Linux的Loader可以手动设置菜单,所以你可以在Linux的Boot Loader里面加入Windows开机选项。Windows在安装的时候,它的安装程序会主动覆盖掉MBR以及自己所在分区的启动扇区,你没有选择的机会,而且它没有让我们自己选择菜单的功能。

硬盘的0柱面,0磁头,1扇区称为主引导扇区,FDISK程序写到该扇区的内容称为主引导记录(MBR)。
硬盘的主引导记录(MBR)是不属于任何一个操作系统的,也不能用操作系统提供的磁盘操作命令来读取它。但我们可以用ROM-BIOS中提供的INT 13h的2号功能来读出该扇区的内容,也可用软件工具Norton8.0中的DISKEDIT.EXE来读取。

MBR的主要功能及工作流程
在CPU上电之后,若由硬盘启动,则BIOS将硬盘的主引导记录(位于0柱面、0磁道、1扇区)读入7C00处,然后将控制权交给主引导代码。主引导代码的任务包括:
扫描分区表,找到一个激活(可引导)分区;
找到激活分区的起始扇区;
将激活分区的引导扇区装载到内存7C00处;
将控制权交给引导扇区代码;

如果主引导代码无法完成上述任务,它将显示一下错误信息如下:
No active partition.
Invalid partition table.
Error loading operating system.
Missing operating system.

机器加电或按reset键后,都要进行系统复位,复位后CS=FFFFH,IP=0000H,那么自然就从FFFF:0000H处开始执行指令,这个地方只有一个JMP指令跳转到系统自检程序处,系统自检完成后把硬盘的第一个扇区,即MBR扇区读入到0:7C00H处,然后把控制权交出,从0:7C00H处继续执行。

引导扇区是硬盘相应分区的第一个扇区,是和操作系统有关的。操作系统的引导是由它来完成的,而MBR并不负责,MBR和操作系统无关。引导扇区的任务是把控制权转交给操作系统的引导程序。

在启动过程中MBR的主引导程序,扫描分区表,找到一个激活分区;把激活分区的引导扇区装入内存7C00中,并把控制权教引导扇区。grub不能引导DOS系统的bootloader,MBR找到激活分区,使用chainloader+1加载DOS的引导程序。使用DD把DOS的IMG拷入硬盘的分区中,可以引导。

MBR修复方法:
首先使用光驱引导进入纯dos模式,再用fdisk /mbr命令恢复系统固有的主引导程序。

在双系统中,为了能够引导linux,已经修改了主引导记录(MBR),当删除linux分区后,可用fdisk /mbr命令恢复Windows依赖的主引导程序。

MBR不属于任何一个操作系统,不随操作系统的不同而不同,即使不同,MBR也不会夹带操作系统的性质,具有公共引导的特性。但是安装某些多重引导功能的软件或Linux的LILO时有可能改写它,它先于所有的操作系统被调入内存并发挥作用,然后将控制权交给活动分区内的操作系统。

MBR = 主引导代码 + 硬盘分区表(DPT)
主引导代码实现下列功能:
1.扫描分区表查找活动分区;2.寻找活动分区的起始扇区;3.将活动分区的引导扇区读到内存;4.执行引导扇区的运行代码。

主引导扇区的最后两个字符,其值为AA55H,它表示该扇区是个有效的引导扇区,可用来引导磁盘系统。
分区引导扇区DBR(DOS BOOT RECORD)是由FORMAT高级格式化命令写到改善去的内容。
DBR是由硬盘的MBR装载的程序段。DBR装入内存后,即开始执行该引导程序段,其主要功能是完成操作系统的自举并将控制权交给操作系统。每个分区都有引导扇区,但只有被设为活动分区的DBR才会被MBR装入内存运行。

DBR中含有操作系统的引导程序。

分区和文件系统

分区引导记录中的分区引导代码是和操作系统相关的。
例如:在Windows7系统下,使用winhex软件查看分区引导记录可以看到字符“BOOTMGR”,这个软件名是Win7下的bootloader程序。
在Window XP系统下,使用winhex软件查看分区引导记录可以看到字符“MTLDR”,这个软件名是WinXP下的bootloader程序。

在NTFS文件系统中,有一个名为“$BOOT”文件,这个元文件由分区的第一个扇区,即分区引导记录(DBR)和后边的15个扇区(即NTLDR区域)组成。其中DBR有“跳转指令”,“OEM代号”,“BPB”,“引导程序”和“结束标志”组成。
引导程序:DBR的引导程序占用426字节,其负责完成将系统文件NTLDR装入,对于没有安装系统的分区是无效的。
结束标志:DBR的结束标志与MBR,EBR的结束标志相同,为“55 AA”。

在Windows系统中,在格式化NTFS分区时,会安装特定的“引导程序”,这个“引导程序”在Windows XP和Windows 7是不同的,应为这两个系统的引导机制不同。

stage1写进了(hd0)的MBR中,stage1_5写进了(hd0)的MBR以后的15个扇区中(因为e2fs_stage1_5的大小为7.5k)。将stage1_5写进MBR以后的扇区中,会不会影响正常的文件系统分区呢?不会,因为stage1_5比较小,只占15个扇区,银盘上的第一个文件系统分区的开始扇区最小也只能从0柱面,1磁头,1扇区开始。就是说MBR所在0磁头就只用到了1个扇区而已(其它扇区都是未用的,不属于任何分区),按照硬盘的规格来说,一般一个柱面磁头都有60+个扇区,所以这些扇区用来放stage1_5,但是放stage2不够了(100多k),所以只能将stage2放进文件系统中。

硬盘分区IDE和SCSI两中总线类型,linux下可通过fdisk -l命令查看硬盘属于哪种。Linux下对IDE的设备是以hd命名的,后面加字母a,b,c表示第几块,比如第一个ide设备是hda,第二个是hdb;SCSI以sd命名,同样第一个设备是sda,第二个是sdb。而hda1代表第一块硬盘的第一个分区,硬盘最多可以有四个主分区,数字为1~4,从5开始就是逻辑分区了,一般情况只有一个主分区用来引导系统,这个分区在windows下来说是C盘,而在linux为hda1或sda1,D,E,F盘在linux分别为hda5,had6,hda7。

在grub中命名硬盘的方式又有不同,可以打开grub的配置文件/boot/grub/grub.conf查看(即menu.lst文件,这只不过是grub.conf的一个快捷方式,Linux下称符号链接,可通过ln -s menu.lst grub.conf命令)。

default=2
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS(2.6.27)
    root (hdX,Y)
    kernel /vmliuz-2.6.27 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
    initrd /initrd-2.6.27.img

其中root(hdX,Y)表示grub的安装位置,X表示第几块硬盘,Y表示第几个分区,X,Y都是从0开始编号的,比如(hd0,0)表示第1块硬盘的第1个分区。即这条命令表示把grub安装在第1块硬盘的第1分区,kernel指明了需要加载的内核映像文件,kernel后的root表示该内核文件的位置。在grub中不区分IDE和SCSI,均以hd开始。

grub源程序编译完成后包括一下内容:
stage1:源码目录stage1/s,汇编后便成了一个512字节的img,被写在硬盘的0面0道第1扇区,即硬盘的主引导扇区。(这512字节还包括分区表DPT以及主引导扇区标志“55AA”)。
*_stage1_5:文件系统的解释代码,根据/boot分区(或/boot所在分区)的具体文件系统类型而异,如:ext3分区的话就是e2fs_stage1_5。在stage1_5没有被加载以前,系统无法识别任何文件系统(但是可以通过BIOS中断方式INT 13h读取磁盘指定扇区的内容)。
stage2:grub核心部分。它运行后,会把系统切入保护模式,设置好C运行环境然后寻找menu.list,如果没有的话就会执行一个shell,等待我们输入命令。

MBR中存放grub(bootloader)的关键引导程序。
当BIOS把引导程序加载到内存后就把控制权交给grub,而后grub的剩余代码将完成其他代码的加载和搬移以及文件系统初始化查找等工作,最终加载内核映像文件,从而把控制权交给真正的内核运行。

简单开机过程
1.按下电源后,计算机自检(POST),如果硬件设备(CPU,内存,硬盘,光驱)有没有问题,BIOS会检查各个硬盘的MBR,看有没有可以执行的代码,如果把grub安装到第一个硬盘的MBR上,那BIOS就会找到它,然后把控制权交给这段代码(其实就是512字节大小的stage1)。
2.stage1根据安装时提供的信息,如stage2在什么地方,需不需要加载文件系统对应的stage1_5文件等,找到stage2文件,并把控制权交给stage2.
3.stage2会需要特定位置的grub配置文件menu.lst文件(此文件是/boot/grub/grub.conf的链接文件),如果找到,就分析其中的内容,形成操作系统选择菜单(grub称之为Menu Interface),如果没有找到menu.lst或者这个文件的格式,内容有错误,那就显示grub的命令行提示符。
4.当你选择了菜单中对应的条目,或者输入ule相关的命令,就可以开始引导系统了。比如引导linux的话,stage2会负责将vmlinuz和initrd(如果有的话)装载到内存,并把控制权交给vmlinuz。
5.linux的内容完成对硬件的初始化,并把控制权交给init程序,完成后续的工作。

http://www.ibm.com/developerworks/cn/linux/l-linuxboot/index.html

本文包括3部分内容
1. Linux的引导过程
2. 运行级别
3. /etc/rc.d/ 与/etc/rc.d/init.d的关系

都仅限于自身的理解,如有差错和不足的地方请指正和补充!一起学习,一起进步。

/etc/rc.d/init.d/目录下的脚本就类似与windows中的注册表,在系统启动的时候某些指定脚本将被执行。

一、 Linux的引导过程
加载BIOS–>读取MBR–>Boot Loader–>加载内核–>用户层init一句inittab文件来设定系统运行的等级(一般3或者5,3是多用户命令行,5是界面)–>init进程执行rc.syninit–>启动内核模块–>执行不同级别运行的脚本程序–>执行/etc/rc.d/rc.local(本地运行服务)–>执行/bin/login,就可以登录了。
  系统启动之后,在进入init.d之前,我们先来看看系统都做了什么工作,先看看一个图(此图来自网络,后期补上)
  从这个图中,我们从比较高的角度去看开始引导的整个过程,比较清晰明了。系统加电之后,首先进行的硬件自检,然后是bootloader对系统的初始化,加载内核。
  内核被加载到内存中之后,就开始执行了。一旦内核启动运行,对硬件的检测就会决定需要对哪些设备驱动程序进行初始化。从这里开始,内核就能够挂装根文件系统(这个过程类似于Windows识别并存取C盘的过程)。内核挂装了根文件系统,并已初始化所有的设备驱动程序和数据结构等之后,就通过启动一个叫init的用户级程序,完成引导进程。

二、 运行级别(run level)

  Init进程是系统启动之后的第一个用户进程,所以它的pid(进程编号)始终为1。init进程上来首先做的事是去读取/etc/目录下inittab文件中initdefault id值,这个值称为运行级别(run-level)。它决定了系统启动之后运行于什么级别。运行级别决定了系统启动的绝大部分行为和目的。这个级别从0到6 ,具有不同的功能。不同的运行级定义如下:
  # 0 - 停机(千万别把initdefault设置为0,否则系统永远无法启动)
  # 1 - 单用户模式
  # 2 - 多用户,没有 NFS
  # 3 - 完全多用户模式(标准的运行级)
  # 4 – 系统保留的
  # 5 - X11 (x window)
  # 6 - 重新启动 (千万不要把initdefault 设置为6,否则将一直在重启 )
  这是两个表较常用运行级别(后期补上),左图redhat9 级别3启动的将是文本界面,右图fc7级别5启动的将是图形界面。

三、 /etc/rc.d/与/etc/rc.d/init.d的关系

  写到这里,应该差不多要进入init.d了,可是我觉得单写/etc/rc.d/init.d的话不一定能说得清楚明白,就拿它跟/etc/rc.d这个它上一级的目录一起来讨论,可能比较合适一些,因为他们之间有着千丝万缕的关系。
  在这里先解释一下init.d里面放的都是什么东西。这个目录存放的是一些脚本,一般是linux以rpm包安装时设定的一些服务的启动脚本。系统在安装时装了好多rpm包,这里面就有很多对应的脚本。执行这些脚本可以用来启动,停止,重启这些服务。
  前面说到,/etc/rc.d/init.d这个目录下的脚本就类似与windows中的注册表,在系统启动的时候执行。程序运行到这里(init进程读取了运行级别),相信从命名的角度大家也能猜到该运行/etc/rc.d/init.d里面的脚本了,不然它为什么也叫init(.d)呢是吧。没错,是该运行init.d里的脚本了,但是并不是直接运行,而是有选择的因为系统并不需要启动所有的服务。
  那么,系统是如何选择哪些需要启动哪些不要呢?这时刚才说的运行级别就起作用了。在决定了系统启动的run level之后,/etc/rc.d/rc这个脚本先执行。在RH9和FC7的源码中它都是一上来就check_runlevel()(虽然实现的代码不一样,也大同小异),知道了运行级别之后,对于每一个运行级别,在rc.d下都有一个子目录分别是rc0.d,rc1.d ….. rc6.d。每个目录下都是到init.d目录的一部分脚本一些链接。每个级别要执行哪些服务就在相对应的目录下,比如级别5要启动的服务就都放在rc5.d下,但是放在这个rc5.d下的都是一些链接文件,链接到init.d中相对应的文件,真正干活到init.d里的脚本。
  
到这里,估计大家可能都比较清楚了,我开始也以为是这样的。可是后来我仔细看过和比较这些链接文件和init.d里真正被执行的脚本的文件名之后,一直有几个问题没弄明白。借着写这个文章的机会,我做了一些功课,总算是大概解开了那些疑惑。
1、这些链接文件前面为什么会带一个Kxx或者Sxx呢?
  是这样的,带K的表示停止(Kill)一个服务,S表示开启(Start)的意思
2、K和S后面带的数字呢?干什么用的
  这个我开始的时候还以为是排列起来好看或者数数用呢。后来发现不是的。它的作用是用来排序,就是决定这些脚本执行的顺序,数值小的先执行,数值大的后执行。很多时候这些执行顺序是很重要的,比如要启动Apache服务,就必须先配置网络接口,不然一个没有IP的机子来启动http服务那岂不是很搞笑。。。
3、无意中我发现同一个服务带S的和带K的链接到init.d之后是同一个脚本。我就纳闷了,为什么会是执行同一个脚本呢?
  这个时候真是S和K的妙用了,原来S和K并不止是用来看起来分的清楚而已。S给和K还分别给init.d下面的脚本传递了start和stop的参数。哦,是这样的(焕然大悟的样子,呵呵)!这时我才想起来原来曾经无数用过的/etc/rc.d/init.d/network restart命令。原来传S时相当于执行了/etc/rc.d/init.d/xxx start这条命令,当然K就相当于/etc/rc.d/init.d/xxx stop了

你可能感兴趣的:(杂七杂八)