【转载】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 ...
随机推荐
- Pattern Recognition And Machine Learning读书会前言
读书会成立属于偶然,一次群里无聊到极点,有人说Pattern Recognition And Machine Learning这本书不错,加之有好友之前推荐过,便发了封群邮件组织这个读书会,采用轮流讲 ...
- 每一个C#开发者必须知道的13件事情
1.开发流程 程序的Bug与瑕疵往往出现于开发流程当中.只要对工具善加利用,就有助于在你发布程序之前便将问题发现,或避开这些问题. 标准化代码书写 标准化代码书写可以使代码更加易于维护,尤其是在代码由 ...
- 3DMax 物体选择方法
全选: Ctrl + A, 取消选择:Ctrl +D 加选:ctrl+鼠标左键:减选:alt+鼠标 窗口与交叉:下面红框内的右边的按钮, 是切换两种模式: 选择模式一:只要选框碰到物体边缘, 就可选中 ...
- C语言文件的读写
对文件的读和写是最常用的文件操作.在C语言中提供了多种文件读写的函数: 字符读写函数 :fgetc和fputc 字符串读写函数:fgets和fputs 数据块读写函数:freed和fwrite 格式 ...
- Allegro 中手动制作螺丝孔封装
以直径2.5mm的螺丝孔为例: 添加过孔,通常过孔的尺寸稍大于实际的螺丝直径,这里设置为2.8mm的直径. 添加过孔焊盘的其他属性. 制作边上的小焊盘. 新建Package Symbol然后点击Lay ...
- STL数组处理常用函数
reverse(a,a+n)反转 sort(a,a+n,cmp)排序 unique(a,a+n,cmp)对于有序集合进行去重,返回新数组最后一个元素的指针 next_permutatoin(a,a+n ...
- 如何实现侧边栏菜单之间的分割线——不用border-bottom
相信大家都遇到过这样一个老生常谈的问题,就是如果当我们所要做的菜单是侧边栏,垂直方向自上而下的排列的菜单栏,我们在做的时候通常的构想是这样的,就是在每两个菜单之间添加分割线,通常的想法就是说给每个菜单 ...
- 1103简单SQL 行转列思路
转自http://www.cnblogs.com/lhj588/p/3315876.html -- 经典行列转化DROP TABLE IF EXISTS TabName;CREATE TABLE Ta ...
- [Bundling and Minification ] 一、如何绑定
绑定和压缩(缩小)是ASP.NET 4.5出现的用来提高程序性能的两个重要的技术.绑定(Bundling)是将多个文件合并为一个文件,压缩(Minification)主要是将文件缩小,如Js .CSS ...
- iOS开发小技巧--修改按钮内部图片和文字之间的间距(xib)
调整按钮的Edge属性,选择调整图片的Edge还是label的Edge,如图: