开机过程指的是从打开计算机电源直到 LINUX 显示用户登录画面的全过程
分析 LINUX 开机过程也是深入了解 LINUX 核心工作原理的一个很好的途径
计算机开机过程是一个非常复杂的过程, 想真正理解透彻并不容易
计算机启动是一个很矛盾的过程: 必须先运行程序, 然后计算机才能启动, 但是计算机不启动就无法运行程序!
早期真的是这样, 必须想尽各种办法, 把一小段程序装进内存, 然后计算机才能正常运行
先了解下 BIOS 是什么?
BIOS 是英文 "Basic Input Output System" 的缩略词, 直译过来后中文名称就是 "基本输入输出系统" 其实, 它是一组固化到计算机内主板上一个 ROM 芯片上的程序
BIOS 系统文件是存在 ROM 芯片上的, 但是 BIOS 设置信息是存储在 RAM 的, 断电会丢失这个 RAM 一般在主板边缘有一个长约一厘米的长方形相片, 可以拔差
1BIOS 自检, 按硬盘启动顺序, 进入操作系统所在的硬盘
计算机通电之后, 首先从主板上读取 BIOS
BIOS 程序首先检查, 计算机硬件能否满足运行的基本条件, 这叫做 "加电自检"(Power-On Self-Test), 缩写为 POST
如果硬件出现问题, 主板会发出不同含义的蜂鸣, 启动中止如果没有问题, 屏幕就会显示出 CPU 内存硬盘等信息
自检完成后, BIOS 把控制权转交给下一阶段的启动程序
这时, BIOS 需要知道,"下一阶段的启动程序" 具体存放在哪里? 到底是光驱, 普通硬盘, 固态硬盘, U 盘里面的哪一种?
打开 BIOS 的操作界面, 里面有一项就是 "设定启动顺序"
2 读取 MBR(主引导记录 Master boot record), 找到操作系统
找到第一个硬盘之后, 计算机就开始读取该硬盘上的 MBR 主引导记录他会告诉计算机应该去到硬盘上哪个位置才能找到操作系统
MBR 指的是硬盘上第 0 磁道第一个扇区, 它的大小是 512 字节, 它由三个部分组成:
(1) 第 1-446 字节: 引导 (PRE-BOOT) 区, 调用操作系统的机器码找到标记为活动 (ACTIVE) 的分区, 并将活动分区的引导区读入内存
(2) 第 447-510 字节: 分区表 (Partition table) 记录硬盘的分区信息
(3) 第 511-512 字节: 主引导记录签名 (0x55 和 0xAA) 最后两个字节是 0x55 和 0xAA, 表明这个设备可以用于启动; 如果不是, 表明设备不能用于启动, 控制权于是被转交给 "启动顺序" 中的下一个设备
分区表:
硬盘分区有很多好处考虑到每个区可以安装不同的操作系统,"主引导记录" 因此必须知道将控制权转交给哪个区
分区表的长度只有 64 个字节, 里面又分成四项, 每项 16 个字节所以, 一个硬盘最多只能分四个一级分区, 又叫做 "主分区"
每个主分区的 16 个字节, 由 6 个部分组成:
(1) 第 1 个字节: 如果为 0x80, 就表示该主分区是激活分区, 控制权要转交给这个分区四个主分区里面只能有一个是激活的
(2) 第 2-4 个字节: 主分区第一个扇区的物理位置(柱面磁头扇区号等等)
(3) 第 5 个字节: 主分区类型
(4) 第 6-8 个字节: 主分区最后一个扇区的物理位置
(5) 第 9-12 字节: 该主分区第一个扇区的逻辑地址
(6) 第 13-16 字节: 主分区的扇区总数
最后的四个字节("主分区的扇区总数"), 决定了这个主分区的长度也就是说, 一个主分区的扇区总数最多不超过 2 的 32 次方
如果每个扇区为 512 个字节, 就意味着单个分区最大不超过 2TB 再考虑到扇区的逻辑地址也是 32 位, 所以单个硬盘可利用的空间最大也不超过 2TB 如果想使用更大的硬盘, 只有 2 个方法: 一是提高每个扇区的字节数, 二是增加扇区总数
3 加载启动管理器 bootloader, 选择进入哪个操作系统
系统找到 BIOS 所指定的硬盘的 MBR 后, 就会将其复制到 0×7c00 地址所在的物理内存中其实被复制到物理内存的内容就是启动管理器 Boot Loader, 而具体到不同的操作系统, 拿 linux 来说, 常见的就是 grub 了
这时, 计算机的控制权就要转交给硬盘的某个分区了, 这里又分成三种情况
3.1 情况 A: 卷引导记录
上一节提到, 四个主分区里面, 只有一个是激活的计算机会读取激活分区的第一个扇区, 叫做 "卷引导记录"(Volume boot record, 缩写为 VBR)
"卷引导记录" 的主要作用是, 告诉计算机, 操作系统在这个分区里的位置然后, 计算机就会加载操作系统了
3.2 情况 B: 扩展分区和逻辑分区
随着硬盘越来越大, 四个主分区已经不够了, 需要更多的分区但是, 分区表只有四项, 因此规定有且仅有一个区可以被定义成 "扩展分区"(Extended partition)
所谓 "扩展分区", 就是指这个区里面又分成多个区这种分区里面的分区, 就叫做 "逻辑分区"(logical partition)
计算机先读取扩展分区的第一个扇区, 叫做 "扩展引导记录"(Extended boot record, 缩写为 EBR)它里面也包含一张 64 字节的分区表, 但是最多只有两项(也就是两个逻辑分区)
计算机接着读取第二个逻辑分区的第一个扇区, 再从里面的分区表中找到第三个逻辑分区的位置, 以此类推, 直到某个逻辑分区的分区表只包含它自身为止 (即只有一个分区项) 因此, 扩展分区可以包含无数个逻辑分区
但是, 似乎很少通过这种方式启动操作系统如果操作系统确实安装在扩展分区, 一般采用下一种方式启动
3.3 情况 C: 启动管理器
在这种情况下, 计算机读取 "主引导记录" 前面 446 字节的机器码之后, 不再把控制权转交给某一个分区, 而是运行事先安装的 "启动管理器"(boot loader), 由用户选择启动哪一个操作系统
Linux 环境中, 目前最流行的启动管理器是 Grub
4 加载内核
进入操作系统后, 首先将内核加载到内存
以 Linux 系统为例, 先载入 / boot 目录下面的 kernel
内核加载成功后, 根据 grub 设定的内核映像所在路径, 系统读取内存映像, 并进行解压缩操作此时, 屏幕一般会输出 Uncompressing Linux 的提示当解压缩内核完成后, 屏幕输出 OK, booting the kernel
系统将解压后的内核放置在内存之中, 并调用 start_kernel()函数来启动一系列的初始化函数并初始化各种设备, 完成 Linux 核心环境的建立至此, Linux 内核已经建立起来了, 基于 Linux 的程序应该可以正常运行了
5 用户层 init 依据 inittab 文件来设定运行等级
内核被加载后, 第一个运行的程序便是 / sbin/init, 该文件会读取 / etc/inittab 文件, 并依据此文件来进行初始化工作
其实 / etc/inittab 文件最主要的作用就是设定 Linux 的运行等级, 它表明 Linux 需要运行在等级 3 上
- [root@localhost] ~$ cat /etc/inittab
- id:3:initdefault:
6init 进程执行 rc.sysinit
在设定了运行等级后, Linux 系统执行的第一个用户层文件就是 / etc/rc.d/rc.sysinit 脚本程序, 它做的工作非常多, 包括设定 PATH 设定网络配置 (/etc/sysconfig/network) 启动 swap 分区设定 / proc 等等如果你有兴趣, 可以到 / etc/rc.d 中查看一下 rc.sysinit 文件
线程 init 的最终完成状态是能够使得一般的用户程序可以正常地被执行, 从而真正完成可供应用程序运行的系统环境它主要进行的操作有:
. 设置网络环境 / etc/sysconfig/network, 如主机名, 网关, IP,DNS 等
. 挂载 / proc 此文件是个特殊文件, 大小为 0, 因为它是在内存当中里面东东最好别删
. 根据内核在开机时的结果 / proc/sys/kernel/modprobe 开始进行周边设备的侦测
. 载入用户自定义的模块 / etc/sysconfig/modules/*modules
. 读取 / etc/sysctlconf 文件对内核进行设定
. 设定时间, 终端字体, 硬盘 LVM 或 RAID 功能, 以 fsck 进行磁盘检测
. 将开机状况记录到 / var/log/dmesg 中(可以用命令 dmesg 查看结果)
至此, init()函数结束, Linux 内核的引导 部分也到此结束
7 启动内核模块
具体是依据 / etc/modules.conf 文件或 / etc/modules.d 目录下的文件来装载内核模块
8 执行不同运行级别的脚本程序
根据运行级别的不同, 会有不同的服务启动到 / etc/rc.d 目录中, 不同的 level 会有不同的目录其中, S(start)开头的表明开机启动, K(kill)开头的表明开机不启动数字表示启动顺序数字越小, 启动越早
9 执行 / etc/rc.d/rc.local
你如果打开了此文件, 里面有一句话, 读过之后, 你就会对此命令的作用一目了然:
- # This script will be executed *after* all the other init scripts.
- # You can put your own initialization stuff in here if you dont
- # want to do the full Sys V style init stuff.
rc.local 就是在一切初始化工作后, Linux 留给用户进行个性化的地方你可以把你想设置和启动的东西放到这里
10 执行 / bin/login 程序, 进入登录状态
此时, 系统已经进入到了等待用户输入 username 和 password 的时候了, 你已经可以用自己的帐号登入系统了
1 加电后从主板读取 BIOS 程序, 找到启动硬盘
2 从硬盘上读取 MBR 主引导记录(硬盘的第一个扇区)
3 从 MBR 主引导记录上读取 boot loader 启动管理器(grub)
4 加载内核, 执行第一个程序 / sbin/init
5 运行环境初始化
6 启动系统服务
参考
- http://blog.csdn.net/bailyzheng/article/details/7485105
- http://blog.csdn.net/bailyzheng/article/details/7485105
- http://www.ruanyifeng.com/blog/2013/02/booting.html
来源: http://www.bubuko.com/infodetail-2506900.html