用 gdb 和 qemu 调试 grub
因为qemu内置了gdbserver,所以我们可以用gdb调试qemu虚拟机上执行的代码,而且不受客户机系统限制。
以下内容是我调试 grub 0.97 时的一份笔记。
准备
qemu, gdb,以及一份带grub的虚拟机镜像,一份grub源码。
调试过程
启动虚拟机
$ sudo qemu-system-x86_64 -s -S -m -hda test.img
然后使用gdb连接
$ gdb
(gdb) target remote localhost:
(gdb) set architecture i8086
(gdb) break *0x7c00
(gdb) cont
一开始CPU是工作在实模式下,为了gdb显示正常我们把架构设置为i8086
BIOS会把MBR加载到内存0x7c00处,我们在这里下断点,然后执行
查看一下当前的反汇编代码
(gdb) x/4i $pc
=> 0x7c00: jmp 0x7c4a
0x7c02: nop
0x7c03: add %al,(%bx,%si)
0x7c05: add %al,(%bx,%si)
显示的是 att 风格的汇编代码,如果不习惯可以切换成 intel 风格的。
(gdb) set disassembly-flavor intel
(gdb) x/4i $pc
=> 0x7c00: jmp 0x7c4a
0x7c02: nop
0x7c03: add BYTE PTR [bx+si],al
0x7c05: add BYTE PTR [bx+si],al
上来就是一个无条件跳转,我们先执行一步,再查看下代码。
(gdb) ni
(gdb) x/8i $pc
=> 0x7c4a: cli
0x7c4b: nop
0x7c4c: nop
0x7c4d: test dl,0x80
0x7c50: jne 0x7c54
0x7c52: mov dl,0x80
0x7c54: jmp 0x0:0x7c59
0x7c59: xor ax,ax
在gdb里查看汇编代码不够方便,我们试着把MBR提取出来,再用IDA打开。
$ sudo dd if=/dev/sda of=mbr.hex bs= count=
对照一下grub的源码,大致能推断出这个就是stage1的代码。
其他几个常用的gdb命令
单步步入
(gdb) si
查看断点
(gdb) info breakpoints
删除断点
(gdb) delete
grub 启动过程总结
阶段:stage1
数据来源:MBR
内存地址:0x7c00
源码:/stage1/stage1.S
这段代码的作用就是加载MBR之后的1个扇区到0x2000处。
阶段:stage1.5
数据来源:MBR之后的几个扇区
内存地址:0x2000
源码:/stage2/start.S
这段代码的作用是把stage1.5剩余的扇区加载到0x2200,因为stage1只加载了stage1.5的第一个扇区。
源码:/stage2/asm.S
这段代码的作用是初始化部分环境,最后调用 init_bios_info
源码:/stage2/common.c
这段代码的作用是初始化c语音环境,最后调用 cmain
源码:/stage2/stage1_5.c
这段代码的作用是加载stage2到0x8000处,然后跳转到0x8200执行。
阶段:stage2
数据来源:/boot/grub/stage2
内存地址:0x8000
源码:/stage2/stage2.c等
后面就是grub的主要功能,显示菜单,启动客户系统等。
客户机的Linux内核是加载到0x100000内存地址。
用 gdb 和 qemu 调试 grub的更多相关文章
- 使用QEMU调试Linux内核代码
http://blog.chinaunix.net/uid-20729583-id-1884617.html http://www.linuxidc.com/Linux/2014-08/105510. ...
- GDB中汇编调试
GDB中汇编调试 1.输入代码 2.使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,时遇到问题使用-m32指令报错,参考卢肖明同学博客知道这是 ...
- 使用Qemu调试内核
利用Qemu进行内核源码级调试 http://blog.csdn.net/gdt_a20/article/details/7231652 用Qemu调试Linux内核 http://blog.chin ...
- GDB + gdbserver 远程调试android native code
原文地址:GDB + gdbserver 远程调试android native code 作者:tq08g2z 以调试模拟器中的native library code为例. Host: ubuntuT ...
- 利用GDB进行多线程调试
一.多线程调试 多线程调试重要就是下面几个命令: info thread 查看当前进程的线程. thread <ID> 切换调试的线程为指定ID的线程. break file.c:100 ...
- 3、利用GDB进行程序调试
本文将用一个实际例子讲解如何通过GDB进行程序调试. 首先,我们需要理解的是GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,其产生和调试的目的是让调试者知道,程序在执行时内部发生了什么 ...
- Lua中如何实现类似gdb的断点调试--01最小实现
说到Lua代码调试,最常用的方法应该就是加一堆print进行打印.print大法虽好,但其缺点也是显而易见的.比如效率低下,需要修改原有函数内部代码,在每个需要的地方添加print语句,运行一次只能获 ...
- ucore lab1练习2 qemu+gdb 不能协作调试的问题make lab1-mon
本练习是qemu结合gdb调试,但是我做实验的时候并不能像视频输入make lab1-mon那样顺利调试,期间有各种error,后来我找到原因,请看解决方法. 请先把ucore_lab文件删除,以下全 ...
- 手把手教你使用eclipse+qemu+gdb来单步调试ARM内核【学习笔记】
平台信息:linux4.0 平台:qemu 作者:庄泽彬 说明:笨叔叔的Linux视频的笔记 一.编译linux源码 export CROSS_COMPILE=arm-linux-gnueabi- e ...
随机推荐
- 集合_java集合框架
转载自http://blog.csdn.net/zsw101259/article/details/7570033 Java集合框架图 简化图: Java平台提供了一个全新的集合框架.“集合框架”主要 ...
- code1174 靶形数独
主要是优化搜索顺序 从选择较少的点开始,可以大大提高效率 在search(x,y)找点的时候,对于一个空点(x y),设置一个评分score: score=min{ 横线x上能填的数字个数,竖线y上. ...
- NPOI读写Excel sheet操作
QueryInfo dataInfo = new QueryInfo(); dataInfo.CustomSQL = $@" select t1.name name,t1.url url f ...
- C# 基础连接已经关闭: 发送时发生错误
在程序中获取某个https网址的源码,GetRespose()时 出现了“基础连接已经关闭: 发送时发生错误.”的错误提示. 翻了论坛后,有个仁兄说: //.net 4 ...
- typeof()和instanceof的用法区别
typeof() typeof() 是一个一元运算,放在一个运算数之前,运算数可以是任意类型.它返回值是一个字符串,该字符串说明运算数的类型.,typeof一般只能返回如下几个结果:number,bo ...
- mysql链接错误:2003 can't connect to mysql server on 10038
出现这个错误原因是端口号不是3306. 打开D:\Program Files\MySQL\MySQL Server 5.5 \my.ini文件,当然还有其他的.ini的文件: [client] ...
- CodeForces 342C Cupboard and Balloons (几何问题)
题意:给定一个 r 和 h,r 是上面那个半球的半径,h 是下面那个圆柱的高度,然后有一些半径为 r/2的气球,问你最多能放几个. 析:根据题意,很容易知道,先从下面往上放,两个两个的放,放到不能放的 ...
- delphi Table切换控件顺序问题
delphi Table切换控件顺序问题 Tagorder的值就是确定Table键切换顺序的 以上做法只能解决同一类型的多个控件(如Edit1,edit2....)显示顺序问题 假如有不同类型的控件如 ...
- [LeetCode 题解]: palindromes
Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could negativ ...
- [转载].NET商业软件源码保护
列举工作以来遇到的各种类型的软件所采用的代码保护技术,只讲原理不涉及技术细节实现,以避免产生法律问题.有些朋友说直接把代码放在Github开源下载,开源可以促进技术交流与进步,然而值钱的代码都积压在硬 ...