首页 > 其他分享 >自己动手从零写桌面操作系统GrapeOS系列教程——12.QEMU+GDB调试

自己动手从零写桌面操作系统GrapeOS系列教程——12.QEMU+GDB调试

时间:2023-03-13 21:57:44浏览次数:51  
标签:截图 12 命令 GrapeOS 桌面操作系统 GDB 寄存器 QEMU 调试

学习操作系统原理最好的方法是自己写一个简单的操作系统。


写程序不免需要调试,写不同的程序调试方式也不同。如果做应用软件开发,相应的程序调试方式是建立在有操作系统支持的基础上的。而我们现在是要开发操作系统,如何调试操作系统的程序呢?如果操作系统程序直接跑在真机上或虚拟机上(比如VirtualBox)是很难调试的,所以我们在开发阶段操作系统程序主要在虚拟机QEMU上跑,因为QEMU支持调试。当然很多事情都是有利也有弊的,QEMU虽然支持调试,但它的运行效率比VitrualBox要低,所以我们最终的GrapeOS程序是跑在VirtalBox上的。QEMU需要结合GDB才能实现调试,下面我们一起来学习一下。

一、QEMU调试模式

在Windows的cmd命令行中输入如下一行命令:

qemu-system-i386 d:\GrapeOS\VMShare\GrapeOS.img -S -s

上面这行命令比之前多了两个参数,“-S”表示让CPU在将要执行第一条指令前暂停,“-s”表示让QEMU打开自带的GDB服务端功能,且网络端口号是1234。截图如下:

执行上面的命令后,会弹出QEMU的窗口:

从上图中可以看到QEMU窗口中间显示一行文字“Guest has not initialized the display(yet).”,此时QEMU已进入调试模式。当QEMU进入调试模式后,就在等待GDB客户端来连接它。当GDB客户端连接上QEMU的GDB服务端就可以调试了。就像我们用PowerShell连接到CentOS就可以在PowerShell中操纵CentOS一样,此时PowerShell是客户端,CentOS是服务端。下面我们来介绍GDB客户端。

二、GDB调试

GDB分为服务端和客户端,单说GDB,一般是指GDB客户端。GDB是Linux中的一个调试软件,所以我们准备在CentOS中使用它。首先我们通过PowerShell登录CentOS。

1.安装GDB

首次使用GDB可能需要安装一下:

yum install gdb

2.启动GDB

敲命令gdb就运行了,如下图:

3.GDB连接到QEMU

在GDB中输入如下命令连接QEMU:

target remote 192.168.10.102:1234

上面这行命令中的IP地址“192.168.10.102”是我的Windows的IP地址,你需要替换成你的Windows的IP地址。截图如下:

如上截图所示,我们已经通过GDB连接到QEMU了。图中倒数第二行的十六进制数“0x0000fff0”表示CPU将要执行的指令地址。还记得前面介绍的实模式下1M内存的布局吗?这个地址在BIOS中,是CPU执行的第一条指令所在的地址。

4.设置断点

设置断点是调试必备的一个功能,比如我们在0x7c00处设置个断点:

b *0x7c00

这样就设置好了一个断点。可以用同样的方式设置多个断点。

5.继续运行

这个命令简单,只有一个字母“c”,然后回车即可让CPU继续运行,当遇到断点时会自动暂停。截图如下:

6.查看寄存器

查看所有寄存器的命令是i r,截图如下:

从上图中可以看到此时CPU中很多寄存器的值,有朋友可能会有个疑问,以前学的寄存器是“ax、bx、cx……”这些,上面截图中怎么是“eax、ebx、ecx……”呢?原因是当年8086CPU的寄存器都是16位的,也就是“ax、bx、cx……”这些,很多讲x86汇编语言的资料都只讲了8086下的情况。而我们现在启动的是32位x86模拟器“qemu-system-i386”,所有通用寄存器多了一个字母“e”表示扩展,从16位扩展成了32位。这些32位通用寄存器中的低16位就是原来的16位寄存器,比如eax的低16位还是ax,ah和al仍然表示ax的高8位和低8位,其它寄存器也一样。这就是兼容,能让旧程序在新CPU上运行。之前的16位寄存器中只有段寄存器没有扩展,还是16位的,而且还增加了2个,分别是fs和gs。增加的这2个段寄存器作用和es基本一样,之所以增加是怕在复杂的程序中出现段寄存器不够用的情况。当数据比较多的时候GDB一般只输出一部分,此时如果按回车键还会显示出其它一些寄存器,但我们用不上,按“q”键退出继续输出即可。

下面来看一下如何查看单个寄存器,比如我们要查看寄存器ax的值,输入命令p $ax,如果想以十六进制显示可以输入命令p /x $ax,截图如下:

7.查看内存

命令格式:x /nfu addr
n表示数量
f表示格式:x(hex), d(decimal), c(char)等。
u表示显示单位:b(byte), h(halfword), w(word), g(giant, 8 bytes)。
下面我们分别演示查看0x7c00开始的8个单字节、8个双字节、8个四字节、8个八字节的内存值。截图如下:

虽然目前看到的数据都是0,但我们以后写上程序就不一样了。

8.反汇编

有时候需要将机器码反汇编成汇编代码方便查看,下面我们以反汇编0x7c00开始的10个字节为例:

disas 0x7c00,+10

截图如下:

上面截图中显示的汇编代码是GDB默认的AT&T语法,我们可以设置改成Intel语法:

set disassembly-flavor intel

截图如下:

需要说明一下的是这里的反汇编结果是错的。因为它是按照32位模式反汇编的,而我们现在还处在16位实模式中,所以这个反汇编功能只能等后面我们进入32位模式才有用。至于反汇编16位代码我们会在后续教程中介绍其它方法。

9.执行下一条指令

在调试的时候有时需要一条指令一条指令的单步执行,单步执行的命令是si

从上面的截图可以看到,每输入一个si回车,就会执行一条命令。每个si命令下面一行中的十六进制数表示下一条指令的地址,可以看到地址在不断增加,说明的确在执行指令。如果想知道每一步都执行了什么指令,可以用下面这个命令来反汇编下一条要执行的指令:

set disassemble-next-line on

从上面截图中可以看到每一步的指令,但这个反汇编结果也是错的,原因和上面的一样。
顺便介绍个小技巧,如果不输入命令直接回车会重复上一个GDB命令,就像上图中最后两步,什么命令都没有直接回车就表示重复执行si这个GDB命令。

10.退出GDB

本讲最后介绍的指令是退出GDB,非常简单,输入q,然后再输入y即可。 截图如下:

退出GDB后就又回到进入GDB前的Linux命令行环境中了。

三、退出GDB后的问题

如果大家按照上面顺序做实验,退出GDB后,CPU占用率会比较高,和上讲中的情况一样,直接关闭QEMU窗口即可。这个问题我们在下一讲中解决。


本讲视频版地址:https://www.bilibili.com/video/BV18G4y1P7CU/
本教程代码和资料:https://gitee.com/jackchengyujia/grapeos-course
GrapeOS操作系统QQ群:643474045

标签:截图,12,命令,GrapeOS,桌面操作系统,GDB,寄存器,QEMU,调试
From: https://www.cnblogs.com/chengyujia/p/17213019.html

相关文章

  • 2023/03/12(日)多云;うわばきあらい,还没收拾完
    大宝是真能睡,不叫估计还能睡到中午;昨天回来蒸了米饭,结果都没吃晚饭,大宝说今天要吃炒米饭,我说好,又煎了鸡肉串;小宝说想吃烤贝壳,我说你原来在北京怎么不爱吃呀?他说有沙子,不......
  • 转载自 https://blog.csdn.net/m0_52165864/article/details/126218082
    Linux系列之系统监控命令 目录1、top命令的使用1、系统统计信息2、系统进程信息2、free命令使用:内存3、df命令的使用:磁盘4、ps命令的使用5、crontab命令6、查看端口的......
  • 上周热点回顾(3.6-3.12)
    热点随笔:· newbing功能使用 (Mrwhite86)· 我又和redis超时杠上了 (蓝胖子的编程梦)· 巧用CSS变量,实现动画函数复用,制作高级感拉满的网格动画 (ChokCoco)· ......
  • day12(2023.3.12)
    1.数组的声明和创建 2.创建引用类型的数组  3.数组的初始化 4.二种常见的遍历 运行结果: 5.数组的拷贝 6.Arrays类 运行结果: 7.多维数组 运......
  • csp201612-4
    题目:计算机软件能力认证考试系统区间DP为了使霍夫曼编码变成字典序,只需要将挑选顺序改为每次都选择相邻的即可每次合并都是累加合并字母频数*1,等同于霍夫曼编码的一单......
  • csp201612-2
    题目:计算机软件能力认证考试系统#include<bits/stdc++.h>usingnamespacestd;doubleT[10]={0,45,345,1245,7745,13745,22495};doubler[10]={3500,5000,8000,12500,......
  • java学习日记20230312-构造方法
    构造方法/构造器基本语法[修饰符]方法名(形参列表){方法体;}构造器的修饰符可以是默认;构造器没有返回值;方法名和类名字必须一样;参数列表和成员方法一样的规则;构......
  • 2022.3.12周报
    本周总结:刷了洛谷一些字符串蓝题紫题大方向:字符串小专题:后缀自动机、trie树题目完成情况:16 ......
  • 20230312考试总结
    \(0min\)~\(10min\):LH忘设闹钟了,还没起床\(2min\)左右:到了考场\(20min\)~\(40min\):思考第一题,没有看出什么特别的性质,有点无从下手,想着打随机化。\(40min......
  • 短期计划312-323
    Tiny_Web_Server0.5Unity0.3S(0830,8,10,1200)3_bodyesp32+pythonSummarizesomeoldcodesselfintroCsapp_Lab......