MIT6.828 32位操作系统笔记(3)----系统的启动和初始化

MIT EDU 6.828 实验源代码

分类 MIT6.828 32位操作系统实验笔记

实验完善代码 LAB2-4下载链接 提取码:79t8

系统的启动过程

  • 物理内存的分布
    首先分析PC 开机以后的默认物理内存的分配。PC 的物理内存空间会由硬件规定产生如下所示 的布局。
    在这里插入图片描述
    早期的PC 是基于16位的处理器,只支持1M 的物理内存,即早期的PC物理内存是从 0x00000000 到0x 000FFFFF。图中的low memory 表示早期PC 的唯一可以使用的RAM 。从0x000A0000 到0x 000F0000 的区域是被硬件保留用于特殊用途的。
    从0x000F0000 到0x 00100000 的区域是最重要的部分,这里保存基本输入输出系统(BIOS)。
    BIOS 的作用是对系统进行初始化,比如激活显卡、检查内存的总量。进行完初始化后, BIOS便操作系统从一个合适的位置(硬盘、软盘都可以)装载到内存,之后将控制权交给操作系统。

尽管后来处理器可以支持4GB 的内存空间,但是为了向下兼容,最新的PC 仍然会保留物理内存低1MB 的布局方式,因此新的PC 会保留物理内存从0x000A0000 到0x 00100000 的区域,这样将系统可以使用的RAM分为了两部分,一个是低640KB 的low memory, 另一部分是1MB 以上部分的“扩展内存”。32位处理器的物理地址空间的最高部分往往被BIOS 保存留供32位的PCI外设所使用。

  • ROM BIOS
    在PC 启动的时候,首先会在实模式下运行BIOS , BIOS是电脑启动加载的第一个软件,是一组固化到计算机主板上一个 ROM芯片上的程序,保存着计算机最重要的基本输入输出程序、开机 后自检程序和系统启动程序,可以从 CMOS 中读写系统设置的具体信息。 主要功能是为计算机提供最底层、最直接的硬件设置和控制。

    因为刚开始的时候内存中没有任何其他的程序可以执行,于是将CS设置为0xF000,将 IP 设为0xFFF0, 实模式下,CS:IP 所指的物理地址为:0x000FFFF0,这样可以保证BIOS 在刚启动的时候获得控制权。
    BIOS运行时,设置IDT中断描述表并且初始化,在初始化PCI总线和一些重要的设备之后,BIOS寻找 bootable device可引导设备,然后从其中读取boot loader ,并将系统控制权交给boot loader 。

  • boot loader

对于PC来说,一个扇区是一次磁盘操作的最小粒度。每次读取或者写入操作都必须是一个或者多个扇区。如果一个磁盘可以用来启动操作系统的话,就称次磁盘的第一扇区为启动扇区。

boot loader 是操作系统内核运行之前的一小段程序,boot loader 程序会在被编译成可执行代码之后放在模拟硬盘的第一扇区,如果操作系统是从磁盘启动的话,则磁盘的第一扇区就被称为启动扇区,因为boot loader 的可执行程序放在该扇区。

BIOS 找到可引导的设备之后,便将第一扇区的内容装在到物理内存为0x7c00 到 0x7dff 的位置,紧接着再执行一个跳转指令,将CS设置为0x0000,IP 设置为0x7c00,这样控制权就交给了boot loader程序了。
启动引导程序(boot loader)主要任务:
(1)首先启动引导程序将操作系统从实模式转换为保护模式,因为只有这样才可以访问所有的内存,实模式下只能访问1M,保护模式下可以访问4G。

<程序boot.S> 首先将GDT表的首地址加载到GDTR(全局描述符表寄存器),然后将CR0寄存器的最低位置1,进入保护模式。最后用一个跳转指令让系统开始使用32位的寻址模式。
ljmp $ PROT_MODE_CSEG, $ protcseg;
PROT_MODE_CSEG代表段选择子,$protcseg代表接下来指令的链接地址,也就是可执行程序在内存中的虚拟地址。

进入保护模式后,程序重新对段寄存器进行初始化并且赋值了堆栈指针后便跳转到bootmain.c

(2)bootmain.c 程序的主要作用是将内核的可执行代码(ELF文件) 从硬盘镜像中读到内存中。

  • 链接地址和加载地址
    在boot.S 源程序中,有很多地址标识符,这些地址标识符到底代表的是一个什么样的地址呢?和内存中的物理地址之间有什么关系呢?

    链接地址和加载地址

==链接地址:==实际上就是程序自己假设在内存中存放的位置,即编译器在编译的时候会认定程序将会连续存放在从起始处的链接地址开始的内存空间 ,于是 地址标识符就被编译成了那段代码开始处的链接地址。 通过编译器链接器处理形成的可执行程序中指令的地址,逻辑地址(VMA)
加载地址: 是可执行程序在物理内存中真正存放的位置,在这个小型的操作系统程序中,Boot Loader 是被BIOS 装在到内存的,而这里BIOS 实际上规定Boot Loader 是要存放在物理内存 0x7c00处,无论程序的链接地址怎么改变,它装在在内存中的位置都不会变化。可执行文件真正被装入内存后运行的地址,物理地址(LMA)

  • ELF文件

    启动引导程序(boot loader)的第二个主要任务将内核的可执行代码(ELF文件) 从硬盘镜像中读到内存中。由bootmain.c 函数完成。因此要了解内核是如何装入内存的,首先需要了解ELF文件。
    (1)ELF文件可以分为下面几个部分:ELF头文件、程序头表、节头表和文件内容;文件内容给可以分为.text节、 .rodata节、 .stab节、 .stabstr节、 .data节、 .bss节 和 .comment节
    在这里插入图片描述
    .text:可执行指令的部分
    .rodata节:只读全局变量部分
    .stab节:符号表部分
    .stabstr节:符号表字符串部分
    .data节:可读可写的全局变量
    .bss节 :未初始化的全局变量
    .comment节:注释部分,不会加载到内存

    (2)ELF头文件、程序头表和节头表 都是用来让程序来识别ELF文件并且找到具体数据的位置。
    (3)ELF头文件
    ELF头文件数据结构,在Linux下可以用命令 vi /usr/include/elf.h 来查看ELF头文件数据结构。在这里插入图片描述
    其中,e_entry 是可执行程序的入口地址(虚拟地址),即从内存的这个位置开始执行。e_phoff 表示程序头表的第一项相对于ELF文件的开始位置偏移。
    在这里插入图片描述

  • 程序源代码的下载
    LAB1 MIT6.828

编译代码之后,用下面的命令来查看ELF文件的每个节的信息。

(1)从图中可以看到 VMA表示链接地址(逻辑地址) 0xf0100000, LMA表示加载地址(物理地址) 0x00100000
加载地址(物理地址)【0x00100000】 = 链接地址(逻辑地址)【0xf0100000】 & 0x00FFFFFF 。

(2)ELF文件的.text节、 .rodata节、 .stab节、 .stabstr节在一个段; .data节、 .bss节 在另外一个段,从 .data节的偏移地址以及.stabstr节的大小以及偏移地址可以推出。

(3).comment节没有被包含在任意一段,表明其没有被装入内存。

objdump -h obj/kern/kernel

在这里插入图片描述
用命令显示ELF文件的入口地址,kernel 的物理入口地址为 0x0010000c

objdump -f bji/kern/kernel

在这里插入图片描述

分类 MIT6.828 32位操作系统实验笔记

本文参考文章 http://grid.hust.edu.cn/zyshao/OSEngineering.htm
推荐这位博主系列的文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值