MIT 6.828 操作系统工程 lab1 2018 fall part1 & part2 笔记 and 中文注释源代码阅读

本文详细记录了MIT 6.828操作系统实验室的第一个实验,包括PC引导加载程序(Bootstrap)和引导加载器的工作原理。内容涵盖x86汇编、实模式到保护模式的切换、BIOS的执行流程、以及引导加载程序如何加载内核。实验中还提供了代码阅读笔记和GDB调试方法,特别关注了ELF二进制文件的加载过程,并设有练习进行实践操作。
摘要由CSDN通过智能技术生成

mit 6.828 lab 代码和笔记,以及中文注释源代码已放置在github中:
https://github.com/yunwei37/xv6-labs

init

  1. setup

    实验内容采用git分发:

    git clone https://pdos.csail.mit.edu/6.828/2018/jos.git lab
    

    测试的话可以使用:

    make grade
    
    

Part 1: PC Bootstrap

  • 需要了解x86汇编以及内联汇编的写法,参看:

    http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
    https://pdos.csail.mit.edu/6.828/2018/readings/pcasm-book.pdf

  • 运行 qemu

    cd lab
    make 
    make qemu
    
    
  • PC的物理地址空间:

    +------------------+  <- 0xFFFFFFFF (4GB)
    |      32-bit      |
    |  memory mapped   |
    |     devices      |
    |                  |
    /\/\/\/\/\/\/\/\/\/\
    
    /\/\/\/\/\/\/\/\/\/\
    |                  |
    |      Unused      |
    |                  |
    +------------------+  <- depends on amount of RAM
    |                  |
    |                  |
    | Extended Memory  |
    |                  |
    |                  |
    +------------------+  <- 0x00100000 (1MB)
    |     BIOS ROM     |
    +------------------+  <- 0x000F0000 (960KB)
    |  16-bit devices, |
    |  expansion ROMs  |
    +------------------+  <- 0x000C0000 (768KB)
    |   VGA Display    |
    +------------------+  <- 0x000A0000 (640KB)
    |                  |
    |    Low Memory    |
    |                  |
    +------------------+  <- 0x00000000
    
    
  • 使用 gdb 调试qemu:

打开新的窗口:

cd lab
make qemu-gdb

在另外一个终端:

make
make gdb

开始使用gdb调试,首先进入实模式;

  • IBM PC从物理地址0x000ffff0开始执行,该地址位于为ROM BIOS保留的64KB区域的最顶部。
  • PC从CS = 0xf000和IP = 0xfff0开始执行。
  • 要执行的第一条指令是jmp指令,它跳转到分段地址 CS = 0xf000和IP = 0xe05b。

物理地址 = 16 *网段 + 偏移量

然后,BIOS所做的第一件事就是jmp倒退到BIOS中的较早位置;

Part 2: The Boot Loader 引导加载程序

PC的软盘和硬盘分为512个字节的区域,称为扇区。

当BIOS找到可引导的软盘或硬盘时,它将512字节的引导扇区加载到物理地址0x7c00至0x7dff的内存中,然后使用jmp指令将CS:IP设置为0000:7c00,将控制权传递给引导程序装载机。

引导加载程序必须执行的两个主要功能:

  • 将处理器从实模式切换到 32位保护模式;
  • 通过x86的特殊I / O指令直接访问IDE磁盘设备寄存器,从硬盘读取内核;

引导加载程序的源代码:

boot/boot.S

#include <inc/mmu.h>

# 启动CPU:切换到32位保护模式,跳至C代码;
# BIOS将该代码从硬盘的第一个扇区加载到
# 物理地址为0x7c00的内存,并开始以实模式执行
# %cs=0 %ip=7c00.

.set PROT_MODE_CSEG, 0x8         # 内核代码段选择器
.set PROT_MODE_DSEG, 0x10        # 内核数据段选择器
.set CR0_PE_ON,      0x1         # 保护模式启用标志

.globl start
start:
  .code16                     # 汇编为16位模式
  cli                         # 禁用中断
  cld                         # 字符串操作增量,将标志寄存器Flag的方向标志位DF清零。
                              # 在字串操作中使变址寄存器SI或DI的地址指针自动增加,字串处理由前往后。

  # 设置重要的数据段寄存器(DS,ES,SS)
  xorw    %ax,%ax             # 第零段
  movw    %ax,%ds             # ->数据段
  movw    %ax,%es             # ->额外段
  movw    %ax,%ss             # ->堆栈段

  # 启用A20:
  #   为了与最早的PC向后兼容,物理
  #   地址线20绑在低电平,因此地址高于
  #   1MB会被默认返回从零开始。  这边代码撤消了此操作。
seta20.1:
  inb     $0x64,%al               # 等待其不忙状态
  testb   $0x2,%al
  jnz     seta20.1

  movb    $0xd1,%al               # 0xd1 -> 端口 0x64
  outb    %al,$0x64

seta20.2:
  inb     $0x64,%al               # 等待其不忙状态
  testb   $0x2,%al
  jnz     seta20.2

  movb    $0xdf,%al               # 0xdf -> 端口 0x60
  outb    %al,$0x60

  # 使用引导GDT从实模式切换到保护模式
  # 并使用段转换以保证虚拟地址和它们的物理地址相同
  # 因此
  # 有效内存映射在切换期间不会更改。
  lgdt    gdtdesc
  movl    %cr0, %eax
  orl     $CR0_PE_ON, %eax
  movl    %eax, %cr0
  
  # 跳转到下一条指令,但还是在32位代码段中。
  # 将处理器切换为32位指令模式。
  ljmp    $PROT_MODE_CSEG, $protcseg

  .code32                     # 32位模式汇编
protcseg:
  # 设置保护模式数据段寄存器
  movw    $PROT_MODE_DSEG, %ax    # 我们的数据段选择器
  movw    %ax, %ds                # -> DS: 数据段
  movw    %ax, %es                # -> ES:额外段
  movw    %ax, %fs                # -> FS
  movw    %ax, %gs                # -> GS
  movw    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值