开机启动流程分析

本节索引



在对系统启动流程进行分析的时候,我想你一定是对系统有了一定的了解。系统的启动目前来讲大都为串行接力的方式来启动。而所谓的并行方式的启动方式也是某一个阶段的并行。所以我按照系统启动的顺序来把文章连缀起来。

    *  BIOS阶段

    *  BootLoader阶段

    *  内核阶段

    *  用户层阶段

BIOS阶段



加载BIOS

当按下开机键后,系统会自动自动加载BIOS,加载的详细过程不再详述,感兴趣的读者可学习微机原理和或对汇编代码分析

BIOS从CMOS芯片中读取硬件配置信息

开机所需要的BIOS设置和用户自定义的设置都保存在CMOS芯片中。

POST自检

POST(power on system  test)

BIOS的代码中包含有诊断功能,用以保证重要硬件被正确初始化,比如内存,CPU,以及一些主板上的各种芯片组。如果硬件损坏,用户可通过主板的debug显示或者蜂鸣器的声音来诊断哪些硬件有故障。

加载Bootloader

当POST自检无误后,BIOS会执行一个 INT 13的中断例程来进入加载Bootloader阶段。

INT13 中断会从第一启动项的0磁道1扇区读取BootLoader,把系统启动的任务移交给BootLoader。

Bootloader阶段



Bootloader具体到Linux系统就是grub了。早期使用的LILO以不再使用。

BootLoader的主要作用就是识别和加载操作系统的内核文件,并移交至内存中运行,进而启动操作系统。

磁盘的第一块扇区被称为主引导记录(MBR—Master boot Record ),该扇区的前446字节存储grub第一阶段的代码。把一个庞大的操作系统内核交给446个字节来引导显然是不现实的,所以可以简单理解为第一阶段的grub的任务就是为了加载第二阶段的grub。

第二阶段的grub把对资源的控制权转交给内核镜像。

BootLoader主要功能

  1. 提供菜单功能,让用户选择操作系统。
  2. 加载内核文件 。
  3. 移交给其他的BootLoader(该项有些bootloader不支持,比如Windows的loader)。
  4. 命令行编辑 当系统BootLoader 加载内核出现故障,用户可在命令行模式下修改启动参数。

以grub为例分析BootLoader阶段多做的那些事:

  1. BIOS 进行POST自检并无误后,执行INT 13中断,读取对应MBR中前446字节的grub stag1代码并执行。
  2. 加载boot分区文件系统驱动。Grubstag1阶段存储了grub的预启动信息和grub stag1_5阶段代码地址信息,grub stag1_5 阶段的代码位于磁盘的主引导记录之后的27个扇区中(修复grub时的数据,非标准),该段空间主要存储挂载/boot分区文件系统所需要的驱动程序。一般在系统的/boot/grub目录下会有stag1_5阶段的备份文件。
  3. 挂载/boot目录,进入grubstag2阶段,读取grub.conf配置文件,根据配置信息,启动或者由用户选择内核启动或者移交给其他其他BootLoader,并提供命令行功能用于手动加载内核。把所有的控制权移交给内核。

注:此阶段的不含有rootfs的概念,寻找内核文件都是以boot为根

Grub.conf文件如下:


default=0

timeout=5

title CentOS 6 (2.6.32-696.el6.x86_64)

root  (hd0,0)

kernel   /vmlinuz-2.6.32-696.el6.x86_64 ro  root=/dev/mapper/vg_centos6-lv_root

#以boot为根的内核路径

initrd   /initramfs-2.6.32-696.el6.x86_64.img

内核阶段



Linux内核的设计风格是单内核,单内核设计要支持市面大部分硬件设备的前提下就要把很多的驱动程序编译在内核文件中,会使得内核文件体积异常庞大。但是Linux系统内核在设计上吸收了微内核的一些优点,把大部分的驱动程序,文件系统驱动程序还有一些外围的驱动程序封装成一个个单独的模块,在使用过程中只需动态的加载所需要的模块就好了。

内核模块文件在/lib/modules/`uname -r` 这个目录下,这时候问题就来了,如果内核文件要加载模块驱动,就要先从根分区查找模块位置,而要找到根分区,就要有根文件系统的驱动模块,而模块又在根文件系统下又回到了先有鸡先有蛋的问题。

为了解决这个问题,一种方法是可以把根文件系统的文件系统驱动程序直接编译在内核文件中,但是市场上的Linux发行版本要支持很多文件系统类型,把所有的文件系统驱动程序编译进内核又会让内核文件体积变得非常庞大。为了解决这一矛盾,就有了initrd这个文件,当然这个是最早期的,在centos6版本称为initramfs也称为虚拟文件系统,该文件是在系统安装的最后阶段生成的,只用来加载根文件系统的驱动程序,在内核无法驱动根文件系统的时候就要加载虚拟文件系统,然后在根文件系统下找到对应的驱动模块后在进行根切换。

系统启动内核阶段的步骤

  1. 加载内核至内存后解压运行,尝试挂载根文件系统,如果挂载成功,动态加载个驱动模块,对周围硬件设备进行探测并进行初始化。
  2. 如果无法挂载根文件系统,加载initrd虚拟文件系统,然后挂载真正的根文件系统,并切换根,再执行第一步。

至此,Linux内核已经建立起来了。

用户层阶段



内核被加载成功之后,这个系统已经正常运行,这也是最初的Linux,但是作为一个用户是无法直接使用内核的。所以就要初始化启动相关的进程或者服务来供用户来使用。

管理进程的工具多种,以centOS为例,有sysVinit和systemd两种。本文主要分析sysVinit的启动方式。

Systemd是由sysVint进化而来,因此更好的掌握了sysVinit启动方式有助于理解systemd的启动方式

执行init程序

内核在引导完成之后会执行系统的第一个进程init。这时也就正式进入了sysVinit的引导环境。Init之后的所有进程都是由init派生出来,它的PID永远为1

init进程加载inittab配置文件

init进程依据inittab文件来设定运行级别,不同的运行级别可以定义一组不同服务的启动顺序。CentOS5和6版本默认有7个运行级别。详情如下:


#  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:     #默认的运行级别

生产环境中默认使用3级别,运行级别的只是用于定义一组不同的启动顺序,用户完全可以自定义,也可以自定义这7种运行级别。

执行rc.sysinit

init在得到运行级别之后并不会立即执行该运行级别的一组服务程序,而执行的第一个程序是/etc/rc.d/rc.sysinit脚本程序。该程序的在centos5的inittab文件中有如下一行:


si:sysinit:/etc/rc.d/rc.sysinit

这个脚本所做的工作有很多,包括主机名,文件系统,swap,SELinux,udev,内核参数,系统时钟,Raid和LVM等服务的开启。为后续服务启动准备基础环境。

加载rc$runlevel.d下的服务

在rc.sysinit脚本初始化完成之后,会加载默认启动级别下的一组服务。这个时候可以查看对应rc$runlevel.d下的文件,有大量以K和S开头的脚本文件(软连接),跟踪rc.d目录下的rc脚本可以发现这样两个循环结构,仔细研究之后符合以下逻辑。


for i  in /etc/rc$runlevel.d/K* ; do

$i stop        #依次关闭以K开头的服务

done

for i  in /etc/rc$runlevel.d/S* ; do

$i   start  #依次开启以S开头的服务,即开机自启动

Done

通过这个结构我们很容易发现服务的启动时顺序执行的,前一个服务脚本没有执行成功的后续脚本就要等待。

通过对rc脚本的分析可以得出对应runlevel下以S开头的脚本是开机启动的,我们可以通过chkconfig命令调整程序是否开启启动或者指定模式下的开机自启动。

跟踪对应模式下的脚本软连接可以,找到服务脚本大多放置在/etc/init.d目录之下。可以使用service 命令来管理这些脚本。

在2345运行级别所对应的rc$runlevel.d目录中都有一个$99local的脚本软连接,该脚本一般是最后一个执行的脚本,该脚本位置在/etc/rc.d/local。所以用户可以把开机后需要执行的操作写在该脚本中。

当然也可以把开机需要的操作定义为服务放置于/etc/init.d目录下,这时需要修改服务脚本的格式。

时间: 2024-12-06 05:16:35

开机启动流程分析的相关文章

CentOS 6开机启动流程实验篇

CentOS 6开机启动流程实验篇 centos 系统的启动流程 grub 破坏Linux的核心文件再修复体验系统启动流程 CentOS 6开机启动的具体详情请参见理论篇! 了解了系统启动的基本流程,以下我们通过"破坏式实验",即破坏系统启动过程中的一些关键环节,使系统无法启动,然后我们再通过修复这些文件使得系统正常重启,进而体验Linux系统的启动流程,这些关键环节包括破坏grub三个stage(stage1.stage1-5.stage2) 中的任何一个阶段,甚至是整个grub;

(转)CentOS 7系统详细开机启动流程和关机流程

CentOS 7系统详细开机启动流程和关机流程 原文:http://blog.csdn.net/yuesichiu/article/details/51350654 名称 bootup - 系统启动流程 描述 在系统启动过程中要涉及多个不同的组件.按下开机按钮后,首先BIOS/UEFI做最基本的硬件自检与初始化, 然后加载预设/手动选择的磁盘/网络上的引导加载器(例如GRUB2),引导加载器进一步从磁盘/网络上加载操作系统内核(例如Linux). 对于Linux来说,内核将会(可选的)解压一个i

Linux系统入门---开机启动流程

目录 Linux系统入门---开机启动流程 一.centos6 二.systemd管理进程 1.查看级别 三.centos7实践案例: 1.案例1:centos7系统,单用户修改root密码 案例2: 如果修改级别 案例3:救援模式 四.修改CentOS7网卡名称为eth0和eth1 1.环境准备 2.用命令配置网卡 方法1: 方法2: 3.系统基本环境优化 五.Systemd 进程管理 1.systemctl管理服务的启动.重启.停止.重载.查看状态等常用命令 2.systemctl设置服务开

u-boot启动流程分析(2)_板级(board)部分

转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global data介绍以及背后的思考 5. 前置的板级初始化操作 6. u-boot的relocation 7. 后置的板级初始化操作 1. 前言 书接上文(u-boot启动流程分析(1)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_i

CentOS开机启动流程简介

我们都知道按下电脑电源键后,屏幕上会一闪而过很多信息,然后显示登录界面,然后输入用户名,密码就可以畅享网络世界了.那么这中间到底发生了什么呢,今天就让我们来简单探讨一下CentOS的简易版开机启动流程吧. 第一阶段:通电自检过程 我们都知道电脑所有数据指令都是在内存上才能被cpu处理的吧,我们还知道内存在断电后其上面的所有数据都会丢失吧,那么开机的时候内存应该是没有东西的吧,那上面都不能干了,更别说启动一个操作系统了,其实啊,我们内存并不只是我们常见的那个内存卡,很多硬件都会映射一段内存到cpu

Cocos2d-x3.3RC0的Android编译Activity启动流程分析

本文将从引擎源代码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,以下是具体分析. 1.引擎源代码Jni.部分Java层和C++层代码分析 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXV4aWt1b18x/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > watermark/2/text/aHR0cDov

u-boot启动流程分析(1)_平台相关部分

转自:http://www.wowotech.net/u-boot/boot_flow_1.html 1. 前言 本文将结合u-boot的“board—>machine—>arch—>cpu”框架,介绍u-boot中平台相关部分的启动流程.并通过对启动流程的简单分析,掌握u-boot移植的基本方法. 注1:本文所使用的u-boot版本,是2016/4/23从u-boot官网(git://git.denx.de/u-boot.git)导入的一个快照,具体可参考“https://github

ubuntu upstart启动流程分析

ubuntu自从6.10版本之后就使用了较新的upstart机制来进行系统的初始化. upstart是一种基于事件驱动的服务启动机制,可以使多个系统任务在保持依赖关系的前提下并发启动(据说这样这样启动会比较快,理论上应当如此).使用upstart机制时,我们通过/etc/init下的一系列 *.conf 配置文件来指定各种系统服务的依赖关系(启动时机).系统启动时,upstart主进程/sbin/init会解析这些配置文件,按照指定的依赖关系并发启动各种服务与应用. 主要程序 upstart有三

Android -- Audio Native服务之启动流程分析(一)

Android -- Audio Native服务之启动流程分析(一) Android中的Audio系统是比较庞大.繁杂的一部分内容, 其中会涉及较多的音频编解码.多媒体制式与Android Audio HAL设备管理的知识.随着Android的发展,其所支持的音频设备也变得越来丰富,如扬声器.耳机.听筒等等:这种变化也为Android管理如此丰富的音频设备以及如何正确.合理地切换音频输出提出了更高的要求.面对如此繁杂的管理要求,我们分析Android Audio服务的历程想必也不会轻松.接下来