没有合适的资源?快使用搜索试试~ 我知道了~
18342075米家龙实验2第2部分1
需积分: 0 0 下载量 94 浏览量
2022-08-03
14:04:09
上传
评论
收藏 1.17MB PDF 举报
温馨提示
试读
19页
1. 虚拟机 1. 宏定义 2. 寄存器清零 3. 开启 A20 4. 开启保护模式 5. 执行32位代码 6. 初始化 gdt 1. bootloader 如
资源详情
资源评论
资源推荐
实验 2 第 1 部分
实验 2 第 1 部分
个人信息
实验名称
实验目的
实验要求
实验环境
1. 虚拟机
2. WSL
实验过程
练习3 分析 bootloader 进入保护模式的过程
1. 宏定义
2. 寄存器清零
3. 开启 A20
阶段1
阶段2
4. 开启保护模式
5. 执行32位代码
6. 初始化 gdt
练习4 分析 bootloader 加载 ELF 格式的 OS 过程
1. bootloader 如何读取硬盘扇区的
2. bootloader 如何加载 ELF 格式的 OS 的
练习5 实现函数调用堆栈跟踪函数
练习6 完善中断初始化和处理
中断向量表中一个表项占多少字节
其中哪几位代表中断处理代码的入口
完善 trap.c 中的 idt_init()
完善 trap.c 中的 trap()
实验结果
实验总结
问题1:尝试在 WSL 环境下运行相应代码
个人信息
数据科学与计算机学院
2018级 米家龙
实验名称
系统软件启动过程 - 第2部分
实验目的
熟悉并掌握 Ubuntu 系统的相关操作
了解并掌握硬件模拟器 Qemu 的操作
熟悉并掌握 gdb 的相关操作
学会使用 Qemu 和 gdb 运行和调试程序
了解 bootloader 进入保护模式的过程
了解 bootloader 加载 OS 的过程
了解并熟悉操作系统的中断和堆栈调用
实验要求
1. 练习3:分析 bootloader 从实模式进入保护模式的过程
2. 练习4:分析 bootloader 加载 ELF 格式 OS 的过程
1. bootloader 如何读取硬盘扇区的?
2. bootloader 如何加载 ELF 格式的 OS 的?
3. 练习5:实现函数调用堆栈跟踪函数
4. 练习6:完善中断初始化和处理
实验环境
1. 虚拟机
使用老师提供的 mooc-os-2015.vdi ,在虚拟机中创建 64 位的 Ubuntu 虚拟机并加载该 vdi ,获得了版
本为:
的虚拟机操作系统
2. WSL
WSL 配置如下:
实验过程
练习3 分析 bootloader 进入保护模式的过程
Linux moocos-VirtualBox 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014
x86_64 x86_64 x86_64 GNU/Linux
root@LAPTOP-QTCGESHO:/mnt/d/blog/work/matrix/step1/001# uname -a
Linux LAPTOP-QTCGESHO 4.4.0-19041-Microsoft #1-Microsoft Fri Dec 06 14:06:00 PST 2019
x86_64 x86_64 x86_64 GNU/Linux
从前两个练习中可以分析得到, bootloader 在接手 BIOS 之后,开始执行 bootasm.S 中的源码,此时
系统处于实模式的运行状态,地址为16位,需要通过修改 A20 地址线进行引导进入保护模式,从而扩大
地址到32位并且内存扩大到4G
查看 bootasm.S 的代码,了解 bootloader 是如何从实模式转到保护模式的
1. 宏定义
上述代码通过宏定义了内核代码段选择子、内核数据段选择子以及保护模式标志位
2. 寄存器清零
上述代码中,设置全局标识符为 start ,在该代码中,先设置了运行模式为16位,关闭中断并清除了
方向标志
之后将代码段寄存器(DS)、附加段寄存器(ES)和堆栈段寄存器(SS)清零
3. 开启 A20
如前面所受,为了进入保护模式,需要修改 A20 地址线为1,从而开启 A20,修改 A20 是因为:
未开启 A20 时,可访问的物理内存空间为 1MB ,任何地址高于 1MB 的都将被置为 0x00000 ,32位
CPU 所能够管理的的 4G 内存无法使用
启用 A20 分为两个阶段
阶段1
.set PROT_MODE_CSEG, 0x8 # kernel code segment selector
.set PROT_MODE_DSEG, 0x10 # kernel data segment selector
.set CR0_PE_ON, 0x1 # protected mode enable flag
# start address should be 0:7c00, in real mode, the beginning address of the running
bootloader
.globl start
start:
.code16 # Assemble for 16-bit mode
cli # Disable interrupts
cld # String operations increment
# Set up the important data segment registers (DS, ES, SS).
xorw %ax, %ax # Segment number zero
movw %ax, %ds # -> Data Segment
movw %ax, %es # -> Extra Segment
movw %ax, %ss # -> Stack Segment
# Enable A20:
# For backwards compatibility with the earliest PCs, physical
# address line 20 is tied low, so that addresses higher than
# 1MB wrap around to zero by default. This code undoes this.
seta20.1:
# Wait for not busy(8042 input buffer empty).
inb $0x64, %al # 获取状态寄存器值,存入 al 中
testb $0x2, %al # 比较首位是否为1
jnz seta20.1 # 如果为0,则跳转到 seta20.1
movb $0xd1, %al # 0xd1 -> port 0x64
outb %al, $0x64 # 0xd1 means: write data to 8042's
P2 port
该阶段有两个步骤:
等待8042缓冲区为输入为空
通过写命令将数据写到8042的 P2 端口
阶段2
等待8042缓冲区输入为孔
通过写命令将数据传送到8042缓冲区,从而开启 A20
4. 开启保护模式
该过程分为4个步骤:
加载 gdt
段变换,和 gdt 一起使得虚拟地址和物理地址相同,避免在切换模式的过程中改变有效内存映射
将 cr0 中的保护允许位(PE, Protect Enable)置1,从而开启保护模式
跳转到32位代码段,使得处理器切换到32位模式
5. 执行32位代码
seta20.2:
# Wait for not busy(8042 input buffer empty).
inb $0x64, %al # 获取状态寄存器值,存入 al 中
testb $0x2, %al # 比较首位是否为1
jnz seta20.2 # 如果为0,跳转到 seta20.2
movb $0xdf, %al # 0xdf -> port 0x60
outb %al, $0x60 # 0xdf = 11011111, means set P2's
A20 bit(the 1 bit) to 1
# Switch from real to protected mode, using a bootstrap GDT
# and segment translation that makes virtual addresses
# identical to physical addresses, so that the
# effective memory map does not change during the switch.
lgdt gdtdesc # 加载 gdt
movl %cr0, %eax # 加载 cr0 到 eax
orl $CR0_PE_ON, %eax # 将 eax 的第0位置0
movl %eax, %cr0 # 使 cr0 的第0位为0
# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
ljmp $PROT_MODE_CSEG, $protcseg
.code32 # Assemble for 32-bit mode
protcseg:
# Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG, %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment
# Set up the stack pointer and call into C.
# The stack region is from 0--start(0x7c00)
movl $0x0, %ebp
movl $start, %esp # start 是 0x7c00
剩余18页未读,继续阅读
love彤彤
- 粉丝: 32
- 资源: 311
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0