Linux内核的启动

Posted by MaggicQ on October 6, 2016

Linux 内核的启动

前几天因为Ubuntu升级,本来装的双系统在开机启动时出现了一些问题,因为我对开机启动方面的不了解,最后导致了系统的重装,产生了很多不必要的麻烦,还丢失了很多数据。所以在这里总结了一些Linux系统启动方面的常识,希望下次再遇到能用上:)

启动过程概述

下面是简化之后的整个启动过程:

  • BIOS或者启动固件加载并运行引导装载程序
  • 引导装载程序在磁盘上找到内核映像,将其载入内存并启动
  • 内核初始化设备及其驱动程序
  • 内核挂载root文件系统
  • 内核使用PID 1来运行一个叫_init_ 的程序,用户空间在此时开始启动
  • init启动其他的系统进程
  • init还会启动一个进程,通常发生在整个过程的尾声,负责用户登录

启动消息

传统的UNIX系统在启动时会显示许多系统信息,这些消息一开始来自内核,然后是进程和init执行的初始化进程。不过现在大部分的Linux发行版一般不会显示这些消息。要想查看内核启动信息和运行时的诊断信息。

  • 查看内核系统日志文件。这些信息通常放在/var/log/kern.log中,由于系统配置的不同,位置可能也会有所区别。
  • 使用dmesg命令查看。

内核初始化和启动选项

在启动时,linux内核初始化的过程如下:

  • 检查CPU

  • 检查内存

  • 检测设备总线

  • 检测设备

  • 设置附加内核子系统(如网络等)

  • 挂载root目录

  • 启动用户空间

内核参数

运行linux内核的时候,引导装载程序会向内核传递一系列文本系列的内核参数来设定内核的启动方式。你可以通过/proc/cmdline文件查看内核启动时使用的内核参数:

luo@luo-ThinkPad-Edge-E431:~$ sudo cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.4.0-42-generic.efi.signed root=UUID=e8693d64-f8de-41e5-9060-2cfb0b06afe6 ro quiet splash vt.handoff=7

其中root参数是root文件系统存放的位置,UUID可以唯一确定其在硬盘上的位置。ro表示以只读模式挂载root文件系统。

引导装载程序

引导装载程序是在启动过程的最开始时启动内核用的,它的工作分为两步:

  • 将内核加载到内存
  • 使用一系列内核参数启动内核。

Linux引导程序的核心功能还包括:

  • 能灵活的从多个内核一级内核参数中选择使用
  • 允许用户手动更改内核映像名和参数
  • 支持其他操作系统

GRUB简介

GRUB是_Grand Unified Boot Loader_的缩写,它近乎与Linux系统标准,且易于操作,现在已经成为linux系统的主流引导装载程序。一些常见的引导装载程序还有:LILO , SYSLINUX , efilinux , coreboot等等。

可以通过一下步骤查看Grub:

  1. 打开Linux
  2. 在BIOS 固件自检或者启动屏幕显示时,按住Shift键显示Grub菜单

下面是一个Grub菜单的实例:

grub

在这里你可以进入Grub命令行模式,设置参数等等。

关于这方面,想了解的更多可以参考:GRUB入门教程

当然也可以直接在你的计算机上面用info grub查看grub的文档。

GRUB工作原理

MBR启动

MBR是主引导记录(Master Boot Record) ,是一种比较典型的分区表(另外一种逐渐普及的是全局唯一标识符分区表,简称为GPT)。在MBR中有一个441字节大小的去有,BIOS在开机自检之后加载其中的内容。因为空间太小无法容纳引导装载程序,就引入了多场景引导装载程序。大部分GRUB采用都是这种方式。但是这种方式并不适用与GPT。

UEFI启动

由于传统的BIOS有很多限制,不能跟上日益发展的硬件,UEFI(统一可拓展固件接口)就是为了代替它而开发的。GPT通常和UEFI一起使用,而不是BIOS。

GRUB工作过程

  1. BIOS或者固件初始化硬件,在启动存储设备上寻找启动代码。
  2. BIOS和固件运行找到的启动代码,开始GRUB。
  3. 加载GRUB核心。
  4. 初始化GRUB核心,此时GRUB可以读取磁盘和文件系统。
  5. GRUB识别启动分区,在那里加载配置信息。
  6. GRUB为用户提供一个更改配置的机会。
  7. GRUB执行配置。
  8. 执行过程中,GRUB可能会在启动分区中加载额外的代码。
  9. GRUB执行boot命令,一加载和执行配置信息中linux命令指定的内核。

用户空间的启动

前面主要是内核的启动过程,这里顺便提一下用户空间的启动。

内核启动第一个用户空间进程是init开始的。这时不仅意味着内存和CPU已经准备就绪,而且你还能看到系统的其余部分是咋样启动运行的。

用户空间启动顺序

  1. init
  2. 基础的底层服务启动
  3. 网络配置
  4. 中高层服务
  5. 登录提示符,GUI以及其他应用程序

init简单介绍

init是Linux上的一个用户空间程序,主要负责启动和终止系统中的基础服务进程。Linux 系统中,init有以下三种主要的实现版本:

  • System V init
  • systemd
  • Upstart

使用man init命令可以查看你的init实现的版本。我的系统(Ubuntu16.04LTS)采用的是systemd方式。除了负责常规的启动过程,systemd还包含了一系列的Unix标准服务。同时它还具有一个重要的特性:它可以延迟一些服务和操作系统功能的开启,直到需要它们才开启。