LAB1_Part1 PC Bootstarp
前言
记录一下自己的学习过程
实验内容翻译:
https://gitee.com/cherrydance/mit6.828.git
练习1
熟悉6.828参考页面上提供的汇编语言材料。你现在不需要阅读它们,但当你阅读和编写x86汇编代码时,几乎肯定会参考其中的一些材料。
我们建议阅读Brennan’s Guide to Inline Assembly中的"语法"部分。它对我们在JOS中将使用的GNU汇编器的AT&T汇编语法进行了很好(而且相当简洁)的描述。
练习1相当于课前预习,直接去读让我感觉十分枯燥,因此跳过了这部分等实践遇到问题再返回来读更有效果。
练习2
使用GDB的si(Step Instruction)命令进一步跟踪ROM BIOS的几条指令,并尝试猜测它可能在做什么。你可以查看Phil Storrs的I/O端口描述,以及6.828参考资料页面上的其他材料。不需要弄清楚所有的细节,只需了解BIOS的一般思路即可。
1. [f000:fff0] 0xffff0: ljmp $0xf000,$0xe05b
#跳转到0xfe05b
2. [f000:e05b] 0xfe05b: cmpl $0x0,%cs:0x6ac8
3. [f000:e062] 0xfe062: jne 0xfd2e1
#内存地址%cs:0x6ac8处的值与立即数0x0进行比较
#判断内存地址%cs:0x6ac8是否为0,不为0则跳转到0xfd2e1
4. [f000:e066] 0xfe066: xor %dx,%dx
#可知未发生跳转,此命令异或将通用寄存器%dx清零
5. [f000:e068] 0xfe068: mov %dx,%ss
#设置堆栈段寄存器%ss
6. [f000:e06a] 0xfe06a: mov $0x7000,%esp
#设置堆栈指针寄存器
7. [f000:e070] 0xfe070: mov $0xf34c2,%edx
#将立即数0xf34c2移动到通用数据寄存器%edx
8. [f000:e076] 0xfe076: jmp 0xfd15c
#跳转到0xfd15c
9. [f000:d15c] 0xfd15c: mov %eax,%ecx
#将%eax的值复制到%ecx
10.[f000:d15f] 0xfd15f: cli
#禁止外部中断
11.[f000:d160] 0xfd160: cld
#清除方向标志位
12.[f000:d161] 0xfd161: mov $0x8f,%eax
#将立即数0x8f存入%eax
13.[f000:d167] 0xfd167: out %al,$0x70
#使用info registers al得到al的值0x8f
#即1000 1111,即禁用非屏蔽中断且设置索引0xf
14.[f000:d169] 0xfd169: in $0x71,%al
#读取端口的值,al寄存器为0
#三条指令的作用似乎就是禁用非屏蔽中断
15.[f000:d16b] 0xfd16b: in $0x92,%al
#读取92端口的原本状态
16.[f000:d16d] 0xfd16d: or $0x2,%al
#al |= 0x2
17.[f000:d16f] 0xfd16f: out %al,$0x92
#三条指令的作用是使能A20地址线
18.[f000:d171] 0xfd171: lidtw %cs:0x6ab8
#将%cs:0x6ab8处的数据读取到中断向量表寄存器IDTR
19.[f000:d177] 0xfd177: lgdtw %cs:0x6a74
#将%cs:0x6a74处的数据读取到全局描述符表格寄存器
20.[f000:d17d] 0xfd17d: mov %cr0,%eax
21.[f000:d180] 0xfd180: or $0x1,%eax
22.[f000:d184] 0xfd184: mov %eax,%cr0
#将%cr0寄存器的0位设置为1进入保护模式
23.[f000:d187] 0xfd187: ljmpl $0x8,$0xfd18f
24. 0xfd18f: mov $0x10,%eax
25. 0xfd194: mov %eax,%ds
70 71 92端口的具体作用可以看https://bochs.sourceforge.io/techspec/PORTS.LST
半知半解,还需要继续学习!
有错误欢迎各位指出!