【转载】Linux启动过程
转自:http://cizixs.com/2015/01/18/linux-boot-process
简介
我们都知道:操作系统运行的代码是在硬盘上的,最终要跑到内存和 CPU 上,才能被我们使用。
那从摁下电源键到看到系统界面,操作系统是怎么霸占了所有的硬件资源,把自己加载到内存开始运行的呢? 可以想到有两个可能性:操作系统自己实现的,或者有其他贵人帮忙。如果是操作系统自己启动的,就有了一个“鸡生蛋,蛋生鸡”的问题;如果是后者的话,一定有在操作系统启动之前就能工作的神力,把沉睡在硬盘的操作系统变到工作状态。
事实上,Linux 系统的启动正是上面第二种情况。帮助把 Linux 内核(Kernel)加载到内存的程序是 Boot Loader,下图的箭头表示加载关系。
Boot Loader —-> Linux Kernel
现在只需要知道 Boot Loader
位于启动盘的第一个扇区,功能是引导 Linux 系统就可以啦,至于更详细的说明会在后面提到。那现在的问题是 Boot Loader
是怎么运行起来的?而且,系统怎么知道哪个可启动设备要使用呢?有时候计算机可能启动的设备可能有多个:网络、硬盘、U 盘,CD 盘等。这就需要另外一个东西来做这件事,那就是 BIOS。
BIOS —-> Boot Loader
顺着上面的思路,现在的问题是:BIOS 的谁启动的?呃,这好像是个没有止境的过程。不过幸运的是,难题就到此结束了。BIOS 是嵌在主板上的固件,计算机启动时候的约定就是启动 BIOS 开始执行。
最后总结一下 Linux 的启动过程:
- 摁下电源键,BIOS(Basic Input/Output System)启动初始化硬件的工作,包括屏幕和键盘,内存检测,这个过程也被成为 POST(Power On Self Test),然后按照 CMOS RAM 中设置的启动设备查找顺序,来寻找可启动设备 。注:BIOS 程序嵌在主板的 ROM 芯片上的。
- POST 过程结束后,系统的控制权从 BISO 转交到 boot loader。Boot loader 一般存储在系统的硬盘上(传统的 BIOS/MBR 系统),或者 EFI 分区上(最近的 EFI 系统)。这个时候机器不能获取外部的存储或者网络信息,一些重要的值(日期、时间、其他外部值)都是从 CMOS 里读取。CMOS 在计算机断电后也能工作的设备,Boot Loader 会在后面讲解。
- Boot Loader 选择要启动的操作系统,加载内核镜像和初始化 RAM disk 到内存。系统的内核开始运行,直到关机为止。
BIOS
摁下电源键的时候,计算机的一些寄存器被设置初值,指令寄存器 CS:IP 指向 BIOS 的第一条指令。BIOS 掌握控制权,来执行硬件检测的程序,BIOS 在结束自己生命之前会寻找可启动设备。那么,BIOS 怎么知道哪些设备室可以启动的呢?如果计算机要从一个不能启动的设置加载系统,会发生严重的错误。启动设备的第一个扇区的末尾两个字节一定是:0x55
和 0xAA
,这两个魔法数就是区分可启动设备和不可启动设备的关键。使用sudo head -c 512 /dev/sda | hd
可以看到第一个扇区的内容,注意最后两个字符。
BIOS 如果找不到可启动设备的话,就会报No Bootable Device Error
。
Boot Loader
对于使用 BIOS/MBR 模式的系统来说,Boot Loader 位于硬盘的第一个扇区,也称为 MBR(Master Boot Record)。MBR 只有 512 字节,主要工作就是检查分区表,并找到可以启动的分区,一旦找到启动分区,就在该分区里找到后面的 Boot Loader – 比如GRUB,把它加载到内存(RAM)。
MBR 这么有限的字节空间里,主要包括了三部分的内容:
- bootstrap code:启动操作系统的代码
- 分区表:指示系统盘的位置
- 魔法数:0x55AA
对于使用 EFI/UEFI 模式的系统来说,UEFI 固件读取 Boot Manager 的数据来决定启动哪一个 UEFI 应用,已经找到它的位置。该固件然后启动 UEFI 应用,比如 GRUB。
现在的控制权都到了 GRUB 启动程序的手里,GRUB 根据你选择的系统(多系统的情况会有界面出现让用户选择,只有一个系统的情况会直接选择该系统),把系统的内核加载到内存开始运行,同时也会初始化 RAM disk 文件系统(initramfs)到内存,供内核使用,并把控制权交给内核。
Linux Kernel
内核一般都是压缩的,所以它的首要任务是解压缩,然后检查和分析系统的硬件并初始化内核里的硬件驱动程序。内核刚加载到内存的时候,文件系统还不能使用,它使用的是 Boot Loader 加载金内存的 initramfs。 内核被加载到内存后首要工作是:初始化和配置机器的内存、处理器、存储设备等,内核也会启动一些用户态的程序。
initramfs
前面提到过 boot loader 加载到内存的 RAM disk,也就是 initramfs,现在就详细讲一讲它。initramfs 包含的一些程序和二进制文件,会执行一系列的动作,保证 root 文件系统 mount 到系统。这里动作包括,为需要的文件系统提供内核的功能,以及使用 udev(User Device) 工具来发现和加载硬盘的驱动程序。 等到 root 文件系统找到后,它会检查错误然后 mount 到系统。
mount 程序告诉操作系统某个文件系统可以使用,并把它加载到文件系统的某个路径(mount point)。如果这些动作都成功的话,initramfs 就会从内存中清除,init 程序(位于 /sbin/init)开始执行。
/sbin/init
init 处理挂载(mount)工作,是整个的文件系统正常运行的枢纽。需要注意的时,如果在访问存储设备的时候,需要的硬件驱动,必须在 initramfs 阶段都加载好。
到目前为止,内核程序准备好了所有的硬件资源,也把文件系统都挂载好了。它运行了 /sbin/init 程序,也就是第一个系统进程(之前运行的程序都不是 OS 级别的,不在 OS 的管辖范围),它的进程号(pid)就是 1。下面是我在自己的系统上运行 ps aux | grep init
的结果,第二列就是进程号:
root 1 0.0 0.0 24320 864 ? Ss Jan15 0:00 /sbin/init
第一个启动的程序当然也肩负着比较重要的责任:把系统需要其他程序都启动起来。传统的 System V UNIX 工作模式下,这个过程是遍历 runlevels 序列的程序脚本,来启动或者停止预先定义的服务(service)。除了上面那个主要的任务外,init 也负责保持系统一直运行和在 shutdown 系统的清理工作,还有用户登入和登出的工作。
登陆和使用
前面已经说过了,init 程序负责用户的登入和登出。如果是服务器 linux 或者其他文本模式的 linux,init 就会启动 getty 程序来接受用户输入的用户名和密码来验证用户。
如果是图形界面的 linux, 会有 display manager 的服务负责检测显示屏和启动 X-server。display manager 也负责图形界面的用户登陆,以及启动正确的桌面环境。
参考资料
- edx 上 introduction to linux 的启动章节
- 阮一峰介绍计算机启动的文章
- wikipedia 上相关文章
【转载】Linux启动过程的更多相关文章
- [转载] Linux启动过程详解-《别怕Linux编程》之八
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket.为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. = ...
- (转载)Linux启动过程详解
启动第一步--加载BIOS当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬盘 ...
- 深入理解Linux启动过程
深入理解Linux启动过程 本文详细分析了Linux桌面操作系统的启动过程,涉及到BIOS系统.LILO 和GRUB引导装载程序,以及bootsect.setup.vmlinux等映像文件 ...
- Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)
启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...
- Linux启动过程详解
Linux启动过程详解 附上两张图,加深记忆 图1: 图2: 第一张图比较简洁明了,下面对第一张图的步骤进行详解: 加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...
- 嵌入式Linux启动过程中的问题积累
嵌入式Linux启动过程中的问题积累 Dongas 07-12-19 1.Bad Magic Number ## Booting image at 33000000 ... Bad Magic Num ...
- [linux 整理] linux启动过程3
本文介绍linux启动过程的第三步 busybox--------------------> rc init busybox位置即内容 busybox/init/init.c 1.各种设置信号 ...
- 从Linux启动过程到android启动过程
Linux启动过程: 1.首先开机给系统供电,此时硬件电路会产生一个确定的复位时序,保证cpu是最后一个被复位的器件.为什么cpu要最后被复位呢?因为 如果cpu第一个被复位,则当cpu复位后开始运行 ...
- Linux启动过程简述
Linux启动过程: 图片来自:https://www.cnblogs.com/codecc/p/boot.html 简单来讲: 加载BIOS–>读取MBR–>Boot Loader–&g ...
- Linux 启动过程详解
目录 1. Linux启动过程 2. 启动过程概述 3. 引导加载阶段 4. 内核阶段 4.1 内核加载阶段 4.2 内核启动阶段 5. 早期的用户空间 6. 初始化过程 6.1 SysV init ...
随机推荐
- git的安装以及遇到的问题
git安装以及遇到的问题 之前没有学会如何在Ubuntu下使用git,国庆放假回来后,完成了git的安装,补回来了之前没有学会的东西. 以下是我安装的过程以及遇到问题.解决问题的过程. 这次安装git ...
- 【腾讯GAD暑期训练营游戏程序开发】游戏中的动画系统作业
游戏中的动画系统作业说明文档 一.实现一个动画状态机:至少包含3组大的状态节点
- canvas api
基本骨骼 <canvas id="canvas" width=1000 height=1000 style="border: 1px black dotted&qu ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- 深入理解python的yield和generator
原文发表在我的博客主页,转载请注明出处 前言 没有用过的东西,没有深刻理解的东西很难说自己会,而且被别人一问必然破绽百出.虽然之前有接触过python协程的概念,但是只是走马观花,这两天的一次交谈中, ...
- 自己存档:asp.net mvc 从filterContent得到controller和action
//filterContext.RouteData.GetRequiredString("controller") + "/" + filterContext. ...
- sFlow
http://www.sflow.org/developers/specifications.php http://www.inmon.com/technology/index.php sFlow s ...
- poj 1324 Holedox Moving
poj 1324 Holedox Moving 题目地址: http://poj.org/problem?id=1324 题意: 给出一个矩阵中,一条贪吃蛇,占据L长度的格子, 另外有些格子是石头, ...
- Spring学习进阶(四) Spring JDBC
Spring JDBC是Spring所提供的持久层技术.主要目的是降低使用JDBC API的门槛,以一种更直接,更简洁的方式使用JDBC API.在Spring JDBC里用户仅需要做哪些比不可少的事 ...
- CSS hack技术
首先我们要了解一个概念CSS hack 不同浏览器,比如IE6.IE7.IE8,Mozilla Firefox等,对CSS的支持及解析结果不同,因此会导致相同的网页生成的页面效果不一样. 这个时候我们 ...