zoukankan      html  css  js  c++  java
  • linux系统启动过程

    BIOS

    当我们给计算机加电的时候,计算机系统怎么知道该如何启动我们的操作系统呢?

    首先计算机之中在主板上,有一个东西叫ROM(Read Only Memor),在ROM上固话了一些程序,被称为BIOS(基本输入输出系统),由于系统刚刚启动时处于实模式,关于什么是实模式,以及保护模式,可以看这篇文章

    实模式可操作的空间非常有限,只有2^20也就是1M的地址空间

    在X86系统之中,将 1M 空间最上面的 0xF0000 到 0xFFFFF,一共64K映射给了ROM,当访问到这块地址的时候,就会访问到ROM。当加电的时候,系统加载ROM之中的BIOS之前,会完成一系列初始化工作

    1. CS(代码段寄存器)置为0xFFFF
    2. IP(指令指针寄存器)置为0x0000

    所以对于第一条指令会指向0xFFFF+0x0000,也就是0xFFF0,处于ROM的地址空间内,这是一个JMP指令会调到ROM中执行初始化的工作,也就是开始了BIOS

    BIOS会检查两件事情

    1. 系统硬件是否完好
    2. 建立中断向量表和中断服务程序

    在BIOS阶段,也可以通过键盘的方式对BIOS发出指令,一旦通过键盘,就肯定会触发一个中断来让系统处理你的指令,所以第二个步骤是很有必要的。此时BIOS前期的工作就算完成

    BootLoader

    BIOS完成上述步骤后,就需要开始加载操作系统。一般的操作系统,例如在windows我们都会安装在C盘也就是硬盘上。在BIOS上我们也可以看到启动盘的选择。

    启动盘的特点如下:

    - 一般位于第一个扇区
    - 占用512字节
    - 以0xAA55结束

    满足上述条件,可以称之为启动盘,并且在512字节内完成启动的相关代码。

    启动盘里的代码是GRUB2(Grand Unified Bootloader Version2),定义的。也就是说BIOS执行了启动盘中由GRUB2定义好的一系列加载操作系统的步骤

    可以通过 grub2-mkconfig -o /boot/grub2/grub.cfg 来定义系统启动执行的选项。这些代码

    grub2定义的操作系统的步骤可以分为以下几步:

    - boot.img
    - diskboot.img
    - lzma_decompress.img
    - kernel.img
    - 启动内核

    boot.img

    由boot.S编译而成,一共512字节,正好符合启动盘的第一个扇区的大小,所以会安装在这个第一扇区,通常这个扇区成为MBR(主引导记录扇区)

    BIOS会将boot.img从硬盘加载到内存中的0x7c00来运行,因为只有512个字节,所以boot.img的唯一使命就是加载grub2的另一个镜像core.img

    core.img由lzma_decompress.img,diskboot.img,kernel.img和一系列模块组成

    boot.img会先加载core.img的第一个扇区,也就是diskboot.img

    diskboot.img

    由diskboot.S编译而成,任务是将core.img的其他部分一块加载到进来,显示解压它的下一步骤,lzma_decompress.img,再往下就是kernel.img,最后则是各个modules的映射,这里还不到linux的内核,所有都是grub的内核

    lzma_decompress.img

    由startup_raw.S编译而成,因为后续的kernel.img是经过压缩过后的,所以需要解压,同时它还需要完成从 实模式——>保护模式 的切换,为的是能在更大的寻址空间里,加载更多的东西

    切换到保护模式,需要完成一系列动作

    1、启动分段,将寄存器里的段寄存器变成段选择子(类似于索引),来指向某个段描述符(真正的段的起始地址),实现不同进程切换

    2、启动分页

    3、打开Gate A20,也就是第21根地址线的控制线,在8086模式下,一共只有20个地址线,总共可以访问1M的地址空间,所以保护模式需要启动第21根,来增大可以寻址的空间

    资源搜索网站大全 https://www.renrenfan.com.cn

    kernel.img

    由startup.S及一堆C文件编译而成,startup.S会调用grub_main(grub kernel的主函数)

    主函数中

    1. grub_load_config解析gurb.conf文件中的配置信息

    2. 选定操作系统

    3. 调用grub_menu_execute_entry,解析并执行选择的那一项

    4. 其中选择的那一项可能会有很多指令,例如linux16,initrd等,都会执行对应的函数

    5. 调用grub_command_execute,真正启动内核

    总结

  • 相关阅读:
    TEN
    out.println()、document.write()、document.getelementbyid()
    正则表达式
    DOM与BOM
    伪类和伪元素
    Grid(未完全完成)
    position
    表单
    API,WEB API
    Event Flow
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/14031577.html
Copyright © 2011-2022 走看看