最近头大之至,一直想用bochs调试,结果她的魅力远胜于想象。网上流传很多bochs的调试大多盲目转载且内容大为英文 帮助的翻译,下面是我在一大师的博客上转帖过来的,关于用bochs进行调试的步骤和实践过程中使用的例子。
注:1.大师博客:http://www.cnblogs.com/smwikipedia/
2.本文中所使用的bochs的版本为v2.1.1,否则有些命令不兼容
正文----------------------------------------------------------------------------------------------- ------------------------------
----------------------------------------------------------------------------------------------- -----------------------------------
Bochs具有非常强大的操作系统内核调试功能。这也是本文选择Bochs作为首选实验环境的主要原因之一。有关Bochs调试功能的说明参见前面14.2节,这里基于Linux 0.11内核来说明Windows环境下Bochs系统调试操作的基本方法。
14.8.1 运行Bochs调试程序
我们假设Bochs系统已被安装在目录“C:\Program Files\Bochs-2.1.1\”中,并且Linux 0.11系统的Bochs配置文件名称是bochsrc-hd.bxrc。现在在包含内核Image文件的目录下建立一个简单的批处理文件run.bat,其内容如下:
"C:\Program Files\Bochs-2.1.1\bochsdbg" -q -f bochsrc-hd.bxrc
其中bochsdbg是Bochs系统的调试执行程序。运行该批处理命令即可进入调试环境。此时Bochs的主显示窗口空白,而控制窗口将显示以下类似内容:
C:\Documents and Settings\john1\桌面\Linux-0.11>"C:\Program Files\Bochs-2.1.1\bo
chsdbg" -q -f bochsrc-hd.bxrc
========================================================================
Bochs x86 Emulator 2.1.1
February 08, 2004
========================================================================
00000000000i[ ] reading configuration from bochsrc-hd.bxrc
00000000000i[ ] installing win32 module as the Bochs GUI
00000000000i[ ] Warning: no rc file specified.
00000000000i[ ] using log file bochsout.txt
Next at t=0
(0) context not implemented because BX_HAVE_HASH_MAP=0
[0x000ffff0] f000:fff0 (unk. ctxt): jmp f000:e05b ; ea5be000f0
<bochs:1>
此时Bochs调试系统已经准备好开始运行,CPU执行指针已指向ROM BIOS中地址0x000fffff0处的指令处。其中'<bochs:1>'是命令输入提示符,其中的数字表示当前的命令序列号。在命令提示符'<bochs:1>'后面键入'help'命令,可以列出调试系统的基本命令。若要了解某个命令的具体使用方法,可以键入'help'命令并且后面跟随一个用单引号括住的具体命令,例如:“help 'vbreak'”,如下面所示。
<bochs:1> help
help - show list of debugger commands
help 'command'- show short command description
-*- Debugger control -*-
help, q|quit|exit, set, instrument, show, trace-on, trace-off,
record, playback, load-symbols, slist
-*- Execution control -*-
c|cont, s|step|stepi, p|n|next, modebp
-*- Breakpoint management -*-
v|vbreak, lb|lbreak, pb|pbreak|b|break, sb, sba, blist,
bpe, bpd, d|del|delete
-*- CPU and memory contents -*-
x, xp, u|disas|disassemble, r|reg|registers, setpmem, crc, info, dump_cpu,
set_cpu, ptime, print-stack, watch, unwatch, ?|calc
<bochs:2> help 'vbreak'
help vbreak
vbreak seg:off - set a virtual address instruction breakpoint
<bochs:3>
为了让Bochs直接模拟执行到Linux的引导启动程序开始处,我们可以先使用断点命令在0x7c00处设置一个断点,然后让系统连续运行到0x7c00处停下来。执行的命令序列如下:
<bochs:3> vbreak 0x0000:0x7c00
<bochs:4> c
(0) Breakpoint 1, 0x7c00 (0x0:0x7c00)
Next at t=4409138
(0) [0x00007c00] 0000:7c00 (unk. ctxt): mov ax, 0x7c0 ; b8c007
<bochs:5>
此时,CPU执行到boot.s程序开始处的第1条指令处,Bochs主窗口将显示出“Boot From floppy...”等一些信息。现在,我们可以利用单步执行命令's'或'n'(不跟踪进入子程序)来跟踪调试程序了。在调试时可以使用Bochs的断点设置命令、反汇编命令、信息显示命令等来辅助我们的调试操作。下面是一些常用命令的示例:
<bochs:8> u /10 # 反汇编从当前地址开始的10条指令。
00007c00: ( ): mov ax, 0x7c0 ; b8c007
00007c03: ( ): mov ds, ax ; 8ed8
00007c05: ( ): mov ax, 0x9000 ; b80090
00007c08: ( ): mov es, ax ; 8ec0
00007c0a: ( ): mov cx, 0x100 ; b90001
00007c0d: ( ): sub si, si ; 29f6
00007c0f: ( ): sub di, di ; 29ff
00007c11: ( ): rep movs word ptr [di], word ptr [si] ; f3a5
00007c13: ( ): jmp 9000:0018 ; ea18000090
00007c18: ( ): mov ax, cs ; 8cc8
<bochs:9> info r # 查看当前CPU寄存器的内容
eax 0xaa55 43605
ecx 0x110001 1114113
edx 0x0 0
ebx 0x0 0
esp 0xfffe 0xfffe
ebp 0x0 0x0
esi 0x0 0
edi 0xffe4 65508
eip 0x7c00 0x7c00
eflags 0x282 642
cs 0x0 0
ss 0x0 0
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
<bochs:10> print-stack # 显示当前堆栈的内容
0000fffe [0000fffe] 0000
00010000 [00010000] 0000
00010002 [00010002] 0000
00010004 [00010004] 0000
00010006 [00010006] 0000
00010008 [00010008] 0000
0001000a [0001000a] 0000
...
<bochs:11> dump_cpu # 显示CPU中的所有寄存器和状态值。
eax:0xaa55
ebx:0x0
ecx:0x110001
edx:0x0
ebp:0x0
esi:0x0
edi:0xffe4
esp:0xfffe
eflags:0x282
eip:0x7c00
cs:s=0x0, dl=0xffff, dh=0x9b00, valid=1
ss:s=0x0, dl=0xffff, dh=0x9300, valid=7
ds:s=0x0, dl=0xffff, dh=0x9300, valid=1
es:s=0x0, dl=0xffff, dh=0x9300, valid=1
fs:s=0x0, dl=0xffff, dh=0x9300, valid=1
gs:s=0x0, dl=0xffff, dh=0x9300, valid=1
ldtr:s=0x0, dl=0x0, dh=0x0, valid=0
tr:s=0x0, dl=0x0, dh=0x0, valid=0
gdtr:base=0x0, limit=0x0
idtr:base=0x0, limit=0x3ff
dr0:0x0
dr1:0x0
dr2:0x0
dr3:0x0
dr6:0xffff0ff0
dr7:0x400
tr3:0x0
tr4:0x0
tr5:0x0
tr6:0x0
tr7:0x0
cr0:0x60000010
cr1:0x0
cr2:0x0
cr3:0x0
cr4:0x0
inhibit_mask:0
done
<bochs:12>
由于Linux 0.11内核的32位代码是从绝对物理地址0处开始存放的,因此若想直接执行到32位代码开始处,即head.s程序开始处,我们可以在线性地址0x0000处设置一个断点并运行命令'c'执行到那个位置处。
另外,当直接在命令提示符下打回车键时会重复执行上一个命令;按向上方向键会显示上一命令。其他命令的使用方法请参考'help'命令。
14.8.2 定位内核中的变量或数据结构
在编译内核时会产生一个system.map文件。该文件列出了内核Image (bootimage)文件中全局变量和各个模块中的局部变量的偏移地址位置。在内核编译完成后可以使用前面介绍的文件导出方法把system.map文件抽取到主机环境(windows)中。有关system.map文件的详细功能和作用请参见2.10.3节。system.map样例文件中的部分内容见如下所示。利用这个文件,我们可以在Bochs调试系统中快速地定位某个变量或跳转到指定的函数代码处。
...
Global symbols:
_dup: 0x16e2c
_nmi: 0x8e08
_bmap: 0xc364
_iput: 0xc3b4
_blk_dev_init: 0x10ed0
_open: 0x16dbc
_do_execve: 0xe3d4
_con_init: 0x15ccc
_put_super: 0xd394
_sys_setgid: 0x9b54
_sys_umask: 0x9f54
_con_write: 0x14f64
_show_task: 0x6a54
_buffer_init: 0xd1ec
_sys_settimeofday: 0x9f4c
_sys_getgroups: 0x9edc
...
同样,由于Linux 0.11内核的32位代码是从绝对物理地址0处开始存放的,system.map中全局变量的偏移位置值就是CPU中线性地址位置,因此我们可以直接在感兴趣的变量或函数名位置处设置断点,并让程序连续执行到指定的位置处。例如若我们想调试函数buffer_init(),那么从system.map文件中可以知道它位于0xd1ec处。此时我们可以在该处设置一个线性地址断点,并执行命令'c'让CPU执行到这个指定的函数开始处,见如下所示。
<bochs:12> lb 0xd1ec # 设置线性地址断点。
<bochs:13> c # 连续执行。
(0) Breakpoint 2, 0xd1ec in ?? ()
Next at t=16689666
(0) [0x0000d1ec] 0008:0000d1ec (unk. ctxt): push ebx ; 53
<bochs:14> n # 执行下一指令。
Next at t=16689667
(0) [0x0000d1ed] 0008:0000d1ed (unk. ctxt): mov eax, dword ptr ss:[esp+0x8] ; 8b442408
<bochs:15> n # 执行下一指令。
Next at t=16689668
(0) [0x0000d1f1] 0008:0000d1f1 (unk. ctxt): mov edx, dword ptr [ds:0x19958] ; 8b1558990100
<bochs:16>
程序调试是一种技能,需要多练习才能熟能生巧。上面介绍的一些基本命令需要组合在一起使用才能灵活地观察到内核代码执行的整体环境情况。
分享到:
相关推荐
本文主要讲述了在 Ubuntu 18.04 环境下编译 Linux 0.11 内核,并在 Bochs 2.6.9 中进行调试运行的过程。文章涵盖了编译 Linux 0.11 内核源代码、Bochs 2.6.9 下的调试运行、问题定位和解决方法等方面的知识点。 一...
使用 Bochs 调试 MBR Bochs 是一种轻便的开源 IA-32(x86)电脑模拟器,可以运行在多种平台上,模拟英特尔 x86 CPU、...通过使用 Bochs,我们可以轻松地调试 MBR 程序,并且可以在 Bochs 仿真环境中运行多种操作系统。
操作系统开发是一项复杂而精细的工作,通常需要借助特定的工具来模拟硬件环境,以便在软件层面进行测试和调试。Bochs就是这样一个工具,它是一个高度可移植的x86模拟器,能够运行在多种操作系统上,如Linux、Windows...
总的来说,"bochs2.6.8(带调试界面)"是一个适合开发者、研究人员和学习者使用的强大工具,它允许用户在不依赖真实硬件的情况下运行和调试x86系统,提供了丰富的功能和详尽的文档支持,能够极大地提升工作效率和学习...
同时,Bochs模拟器提供了一个安全的环境,可以在不影响实际系统的情况下进行实验和调试。对于那些想要学习操作系统开发或对Linux内核感兴趣的初学者来说,这是一个很好的起点。通过亲自编译和运行Linux 0.11内核,你...
### Linux 0.11 Bochs 调试详解...通过在Bochs上运行Linux 0.11,不仅可以帮助我们更好地理解Linux内核的基础结构和工作原理,还可以提高我们在内核级别的调试技能。希望以上内容对学习Linux内核开发的初学者有所帮助。
《Linux 0.00 完全注释与Bochs调试环境详解》 在IT行业中,深入理解操作系统底层的工作原理是提升技术素养的关键步骤之一。Linux作为一款开源、免费的操作系统,其源代码可供广大开发者研究学习。"Linux 0.00 完全...
同时,通过Bochs模拟器,你可以模拟不同的硬件环境,观察MINIX在不同条件下的表现,增强对操作系统适应性的理解。 总之,MINIX系统结合Bochs模拟器,为学习和实践操作系统知识提供了一个强大的平台,有助于提升对...
Bochs是一款开源、跨平台的x86模拟器,它可以在包括Windows和Linux在内的多种操作系统上运行。...无论你是想在Windows还是Linux环境下工作,Bochs都能提供必要的支持,帮助你深入了解和操控计算机系统。
bochs of windows 使用时,需更改start.bat中的BXSHARE 大家可以到http://bochs.sourceforge.net上去下载最新的版本,我这是直接压缩后的,给自己用的
由于Bochs是通过软件模拟硬件,所以对于没有操作系统环境下的程序,Bochs可以进行单步跟踪,查看寄存器内容和机器状态,这对于理解计算机启动过程和保护模式转换有极大的帮助。此外,Bochs在使用时,能够像真实机器...
### wrk源码分析之WinDbg+Bochs调试 #### 概述 本文主要针对Windows内核(WRK)的源码分析方法,重点介绍了如何利用WinDbg结合Bochs进行内核级别的调试。WinDbg是一款由微软提供的强大调试工具,能够支持对Windows...
在Linux环境下,Bochs是一款流行的开源x86模拟器,它可以模拟从早期的8088处理器到现代的多核CPU。它不仅适用于软件开发者进行跨平台移植和调试,也常用于教学和研究。以下是在Ubuntu 14.04上安装和使用Bochs的详细...
用Bochs调试NTLDR, 详细介绍了Bochs的用法,以及如何调试NTLDR
Bochs是一款开源、跨平台的x86架构模拟器,其版本为2.6.11,这使得用户能够在不支持或没有实际...尽管Bochs可能比现代的快速模拟器(如QEMU或VirtualBox)慢,但它的全面性和可调试性使其在特定场合下具有独特的优势。
在调试操作系统时,Bochs提供了一种强大的调试环境。它支持断点设置、单步执行、内存查看和修改、寄存器监控等功能。这些工具可以帮助开发者定位和修复代码中的问题,尤其是在处理复杂的硬件交互时。此外,Bochs还...
通过Bochs,开发者可以在个人计算机上模拟一个完整的计算机系统,包括CPU、内存、硬盘、网络接口等硬件组件,从而在不实际部署到硬件上的情况下调试和测试自己的操作系统。 Bochs的强大之处在于它的高度可配置性和...
Bochs调试器是一款开源的、跨平台的x86架构模拟器,它允许用户在非x86系统上运行x86操作系统和应用程序。这款工具主要用于软件开发、教学、研究和系统测试,尤其是对操作系统内核和硬件交互的调试工作。Bochs提供了...
总的来说,Bochs 2.4.2是一个强大且灵活的工具,对于想要在Linux环境下研究或调试x86操作系统的用户来说,它是一个不可或缺的资源。通过模拟真实的硬件环境,它为开发者提供了无风险的试验场,可以在不影响实际系统...