自己动手写操作系统(开篇)
自己动手写操作系统(字符显示)
说明:Intel 8086 或者不同的处理器,开机寄存器数据可能不一样,但是大致原理差不多
了解过计算机启动的同学肯定知道,当计算机启动的时候 BIOS 会加载 MBR 数据 512 字节到 0x7c00 处。
为什么会加载到这个地方了?
这里给出参考链接:
英文参考链接:
https://www.glamenv-septzen.net/en/view/6
中文参考链接:
http://www.ruanyifeng.com/blog/2015/09/0x7c00.html
现在我们简单了解一下,计算机开机加电过程到底是怎么一个样子了?这里以 VirtualBox 6.1.6 虚拟软件为例子:
VirtualBox 6.1.6 下载地址:
https://www.virtualbox.org/wiki/Downloadshttps://download.virtualbox.org/virtualbox/6.1.6/VirtualBox-6.1.6-137129-Win.exe
- 先安装 VirtualBox , 过程省略。
安装virtualbox出现2503、2502的错误提示解决方法: 右键点击 选择 以管理员身份运行
- 打开 VirtualBox 的调试器, 运行 cmd 命令,启动控制台,输入下面的配置命令即可
Microsoft Windows [版本 10.0.18363.418](c) 2019 Microsoft Corporation。保留所有权利。C:甥敳獲Administrator>set vVBOX_MSI_INSTALL_PATH=C:Program FilesOracleVirtualBoxC:甥敳獲Administrator>set VBOX_GUI_DBG_ENABLED=tureC:甥敳獲Administrator>set VBOX_GUI_DBG_AUTO_SHOW=tureC:甥敳獲Administrator>set vVBOX_GUI_DBG_AUTO_SHOW=tureVBOX_GUI_DBG_ENABLED=tureVBOX_MSI_INSTALL_PATH=C:Program FilesOracleVirtualBoxC:甥敳獲Administrator>cd %VBOX_MSI_INSTALL_PATH%C:Program FilesOracleVirtualBox>VirtualBox.exeC:Program FilesOracleVirtualBox>
之后我们就可以看到这样的效果了:
现在我们在:Command 输入 r 回车就可以看到效果:
Welcome to the VirtualBox Debugger!Current VM is 09980000, CPU #0VBoxDbg> reax=00000000 ebx=00000000 ecx=00000000 edx=00000600 esi=00000000 edi=00000000eip=0000fff0 esp=00000000 ebp=00000000 iopl=0 nv up di pl nz na pe nccs=f000 ds=0000 es=0000 fs=0000 gs=0000 ss=0000 eflags=00000002f000:0000fff0 ea 5b e0 00 f0 jmp far 0f000h:0e05bhVBoxDbg>
我们可以清晰的看到: eip = 0000fff0, cs=f000,( 对应的物理内存其实就是 FFFF0) 也就是开机加电的时候 cs 和 ip(eip) 设置为一个固定的值。 在内存 f000:0000fff0 处的内容为 ea 5b e0 00 f0 。, 距离内存最顶端只有 16 字节。8086 有 20 根地址线,所以最大寻找范围为 1M的地址空间。
·
f000:0000fff0 ea 5b e0 00 f0 jmp far 0f000h:0e05bh ; ; 这里对应的是一条跳转指令, 跳转到物理内存为 FE05B 内存处; 这个地址还是 ROM BIOS 内存地址范围。继续执行,直到通过调用; 中断程序最终将 mbr 加载到 0x7c00处; 当然这里其中还干了很多其他的事情,比如搬数据到 0x00000 开始处。; 此时 CS:IP 对应为 F000: E05B ; 注意 jmp 会改变 cs 和 ip 的值
中断向量表:
参考来源:
http://www.bioscentral.com/misc/biosservices.htm
设置断点继续运行,就可以看到对应寄存器的值了
VBoxDbg> ba x 1 7c00Set access breakpoint 0 at 0000000000007c00VBoxDbg> dbgf event: Breakpoint 0! (raw)eax=0000aa55 ebx=00000000 ecx=00000001 edx=00000000 esi=00000000 edi=0000fff0eip=00007c00 esp=00007800 ebp=00000000 iopl=0 nv up ei pl zr na po nccs=0000 ds=0000 es=0000 fs=0000 gs=0000 ss=0000 eflags=002002460000:00007c00 eb 4e jmp +04eh (07c50h)VBoxDbg> u0000:00007c00 eb 4e jmp +04eh (07c50h)0000:00007c02 90 nop0000:00007c03 48 dec ax0000:00007c04 45 inc bp0000:00007c05 4c dec sp0000:00007c06 4c dec sp0000:00007c07 4f dec di0000:00007c08 49 dec cx0000:00007c09 50 push ax0000:00007c0a 4c dec spVBoxDbg>