您的位置:首页 > 理论基础

【Linux】计算机的启动过程

2016-06-07 16:36 197 查看
  计算机启动是一个非常复杂的过程,大致可以分为四个步骤。  

1.第一阶段:BIOS

  BIOS是固化到计算机主板上一个ROM芯片上的一段程序,这段程序的主要作用有两个。

1.硬件自检Power-On Self-Test

  按下电源键后,计算机首先会读取BIOS,然后BIOS检查计算机硬件有没有问题,是否满足运行条件,这个过程叫做“硬件自检”。如果硬件有问题,电脑上的speaker会发出蜂鸣声,根据不同的声音,可以大致判断那部分硬件出现了问题,比如,电脑按下电源键发出短促持续的滴滴声,很有可能是内存条松了。如果没有问题,则会在屏幕上显示CPU、内存、硬盘等硬件信息。

2.获得启动顺序,转交控制权

  硬件自检通过后,BIOS就要转交控制权,那么到底应该交给谁呢?在BIOS当中有一个外部设备的排序,排在前面的设备就是优先转交控制权的设备。这种排序叫做”启动顺序”(Boot Sequence)。

  


  这就是为什么用U盘装系统的时候要将U盘设置为第一启动项。

2.第二阶段:MBR(主引导记录)

  BIOS根据启动顺序,将控制权转交给排在第一位的启动设备。

  此时,计算机将这个启动设备的第一个扇区,即boot sector读入内存。这个扇区的大小是512字节,这512个字节可以分为三个部分(参见上一篇文章)。

内容字节
MBR前446字节
DPT64字节
BRID2字节
  计算机判断这512字节的最后两个字节是否为0x55和0xAA。如果是,则表明这个设备可以用于启动,如果不是,则将控制权转交给排在第二位的启动设备。重复这个过程,直到找到可以启动的设备。

  主引导记录只有446个字节,里面一般装的是一个引导加载程序(boot loader)(严格来讲,只是boot loader的主程序),在Linux系统中一般是grub。引导加载程序会在分区表中找到活动分区(如果某个分区记录的第一个字节值为0x80,则该分区为活动分区,0x00表示非活动分区),从活动分区当中加载内核到内存当中来。

  在命令行输入fdisk -l ,即可查看那个分区是激活分区

  


在/dev/sda1后面有一个*号,表示这个分区是活动分区。

3.第三阶段:加载内核

  boot loader开始读取内核文件后,接下来,Linux就会将内核解压缩到内存当中,并且利用内核的功能开始测试与驱动各个周边设备,包括存储设备、CPU、网卡、声卡等。此时,Linux内核会重新检测一次硬件,不一定会用BIOS检测到的硬件信息。也就是说,内核此时才开始接管BIOS的工作。内核文件一般放在/boot当中,名字为/boot/vmlinux.

4.第四阶段:运行第一个进程init

  在内核加载完毕进行完硬件检测和驱动程序加载后,计算机的硬件应该已经准备就绪了。此时,内核会主动调用第一个进程,就是/sbin/init。init进程主要工作有下面几个:

1.获得运行级别

  init进程首先读取的文件是/etc/inittab,获得运行级别。这个文件其实只有一句话,就是设置默认的运行级别。

  (centos6和centos5有些区别,centos5的/etc/inittab文件当中出了设置默认运行级别外,还有其他内容。Centos 6弱化了inittab文件的作用)

  

inittab文件的内容如下:

# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:


前面全部都是注释,只有最后一行设定了默认的运行级别。

2.调用/etc/rc.d/rc.sysinit进行系统初始化

  init进程确定了运行级别之后,开始调用/etc/rc.d/rc.sysinit脚本,进行系统初始化,这个脚本的工作有很多,具体的工作请参看《鸟哥的Linux私房菜》。

3.根据运行级别启动系统服务

  系统初始化完成后,init进程根据inittab设置的运行级别(假设为N),执行/etc/rcN.d/*目录下的所有脚本(其实是链接文件,真实脚本在另外一个文件夹)。

  这个目录下的链接文件均已K或S开头,K表示要关闭的服务,S表示要启动的服务。数字表示运行的顺序。

4.执行用户自定义开机启动程序(/etc/rc.d/rc.local)

  /etc/rc.d/rc.local这个文件用于执行用户自定义的开机启动程序,如果你想启动某个脚本,或执行某项命令,直接将其写入这个文件,那么这个脚本或命令在计算机启动时就会被执行。这个文件默认只有一行。

  


  就是将/var/lock/subsys/local这个文件“摸”了一下,没有改变这个文件的内容,事实上,这个文件是空的。摸一下这个文件仅仅更新了这个文件的修改时间,即修改时间戳,就是说rc.local的程序已经启动了, 防止重复运行。

  


  

5.init执行终端模拟程序mingetty来启动login进程,最后等待用户登录。

  至此,计算机总算是启动了,这个过程真是无比的艰难。  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: