zoukankan      html  css  js  c++  java
  • 图解linux启动过程


    概述


    图1 linux系统过程big view

    第一阶段引导载入程序

    MBR 中的主引导载入程序是一个 512 字节大小的映像,当中包括程序代码和一个小分区表(參见图 2)。前 446 个字节是主引导载入程序,当中包括可运行代码和错误消息文本。接下来的 64 个字节是分区表,当中包括 4 个分区的记录(每一个记录的大小是 16 个字节)。

    MBR 以两个特殊数字的字节(0xAA55)结束。这个数字会用来进行 MBR 的有效性检查。

    图2 MBR剖析

    第二阶段引导载入程序

    次引导载入程序(第二阶段引导载入程序)能够更形象地称为内核载入程序。

    这个阶段的任务是载入 Linux 内核和可选的初始 RAM 磁盘

    GRUB 阶段引导载入程序

    /boot/grub 文件夹中包括了 stage1stage1.5 和stage2 引导载入程序。以及非常多其它载入程序(比如,CR-ROM 使用的是 iso9660_stage_1_5)。

    关于 GRUB。非常好的一件事情是它包括了有关 Linux 文件系统的知识。GRUB 不像 LILO 一样使用裸扇区。而是能够从 ext2 或 ext3 文件系统中载入 Linux 内核。它是通过将两阶段的引导载入程序转换成三阶段的引导载入程序来实现这项功能的。

    阶段 1 (MBR)引导了一个阶段 1.5 的引导载入程序,它能够理解包括 Linux 内核映像的特殊文件系统。

    这方面的样例包括reiserfs_stage1_5(要从 Reiser 日志文件系统上进行载入)或 e2fs_stage1_5(要从 ext2 或 ext3 文件系统上进行载入)。当阶段 1.5 的引导载入程序被载入并执行时,阶段 2 的引导载入程序就能够进行载入了。

    当阶段 2 载入之后,GRUB 就能够在请求时显示可用内核列表(在 /etc/grub.conf 中进行定义。同一时候还有几个软符号链接/etc/grub/menu.lst 和 /etc/grub.conf)。我们能够选择内核甚至改动附加内核參数。

    另外,我们也能够使用一个命令行的 shell 对引导过程进行高级手工控制。

    将第二阶段的引导载入程序载入到内存中之后,就能够对文件系统进行查询了。并将默认的内核映像和 initrd 映像载入到内存中。当这些映像文件准备好之后,阶段 2 的引导载入程序就能够调用内核映像了。

    内核


    图3 linux内核i386引导函数流程

    通过调用 start_kernel。会调用一系列初始化函数来设置中断,运行进一步的内存配置,并载入初始 RAM 磁盘。最后,要调用kernel_thread(在 arch/i386/kernel/process.c 中)来启动 init 函数。这是第一个用户空间进程(user-space process)。最后。启动空任务。如今调度器就能够接管控制权了(在调用 cpu_idle 之后)。通过启用中断,抢占式的调度器就能够周期性地接管控制权,从而提供多任务处理能力。

    在内核引导过程中,初始 RAM 磁盘(initrd)是由阶段 2 引导载入程序载入到内存中的,它会被拷贝到 RAM 中并挂载到系统上。这个initrd 会作为 RAM 中的暂时根文件系统使用,并同意内核在没有挂载不论什么物理磁盘的情况下完整地实现引导。因为与外围设备进行交互所须要的模块可能是 initrd 的一部分,因此内核能够很小,可是仍然须要支持大量可能的硬件配置。在内核引导之后,就能够正式装备根文件系统了(通过 pivot_root):此时会将 initrd 根文件系统卸载掉,并挂载真正的根文件系统。

    decompress_kernel 输出

    函数 decompress_kernel 就是显示我们通常看到的解压消息的地方:

    Uncompressing Linux... Ok, booting the kernel.

    initrd 函数让我们能够创建一个小型的 Linux 内核。当中包含作为可载入模块编译的驱动程序。这些可载入的模块为内核提供了訪问磁盘和磁盘上的文件系统的方法,并为其它硬件提供了驱动程序。因为根文件系统是磁盘上的一个文件系统,因此 initrd 函数会提供一种启动方法来获得对磁盘的訪问,并挂载真正的根文件系统。在一个没有硬盘的嵌入式环境中,initrd 能够是终于的根文件系统,或者也能够通过网络文件系统(NFS)来挂载终于的根文件系统

    Init

    当内核被引导并进行初始化之后,内核就能够启动自己的第一个用户空间应用程序了。

    这是第一个调用的使用标准 C 库编译的程序。在此之前,还没有运行不论什么标准的 C 应用程序。

    在桌面 Linux 系统上,第一个启动的程序一般是 /sbin/init。可是这不是一定的。非常少有嵌入式系统会须要使用 init 所提供的丰富初始化功能(这是通过 /etc/inittab 进行配置的)。

    在非常多情况下,我们能够调用一个简单的 shell 脚本来启动必需的嵌入式应用。



    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    浅谈 PHP 与手机 APP 开发(API 接口开发)
    Thinkphp+Nginx(PHPstudy)下报的404错误,403错误解决
    win7彻底卸载iis
    Java ByteCode 规格严格
    CPUID 规格严格
    Your First Plugin(转载) 规格严格
    SQLYog Enterprise注册码 规格严格
    WSUS API&&WUAPI 规格严格
    linux学习一则 规格严格
    Eclipse分析源代码时总是显示org.eclipse.core.runtime.CoreException错误,找不到***文件(转载) 规格严格
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4913831.html
Copyright © 2011-2022 走看看