用Bochs学习Minix(3)-调试启动过程
2007-11-08 00:56
896 查看
/boot文件是一个实模式的可执行文件,运行地址是0x10000,使用反汇编工具打开boot文件,可以看到boothead.s的第一条指令被编译在0x1000:0030处。前面已经指出,这就是从bootblock.s跳转到的位置。这条指令是一个跳转:
jmp 1002:0015
它实际上就是跳转到下面一行:
mov ax, 1000 //指令地址:0x10035
…
接下来可以看到代码一直运行到boothead.s中调用boot函数的汇编代码:
…
jmp no_ext
adj_ext:
add 14(di), bx ! Add ext mem above 16M to mem below 16M
no_ext:
! Time to switch to a higher level language (not much higher)
call _boot //调用boot函数
结合/boot文件的反汇编代码,可以判定boot函数的地址为0x1267a。
启动Bochs,然后在调试窗口设置断点后运行:
<bochs:1>pb 0x10124 //设置物理地址断点
<bochs:2>c
运行一段时间后,Bochs停在了0x10124处。接下来单步运行进入boot函数:
<bochs:3>s
<bochs:4>u /10 //列出反汇编代码
0001267a :( ): push bp
0001267b :( ): mov bp, sp
0001267d :( ): call .+0xe6cb
00012680 :( ): call .+0xeccc
…
从列出的反汇编代码可以看出execute函数的调用应该在0x1002:266a这一行,所以设置断点:
<bochs:5>pb 0x1268a
不过遗憾的是系统并没有在预料的地方停下来,而是一直运行下去了,看来一定是因为某种原因使断点失效了。经过测试发现,汇编语句在第一个call语句(initialize函数)就没有返回,这是什么原因呢?其实只要看一看initialize函数的代码就可以发现,这个函数把启动程序拷贝到了low memory(640k)的远端(far end),也就是接近640k的地方。所以整个启动代码的基地址在这个函数中的某一句之后就全部改变了,看来要想完全跟踪启动代码还要费一番功夫。
<bochs:6>pb 0x1267d //在initialize函数处设置断点
<bochs:7>s //进入函数
<bochs:8>u /20
使拷贝到新地址的启动程序运行的是initialize函数中调用的第二个过程relocate,它位于boothead.s中。所以可以先找到后面的第二个call指令(即relocate函数)进入,这个汇编函数最后返回的地址就是新定位的地址了。
<bochs:8>pb 0x10e13 //在relocate的入口设置断点(下一条指令的地址是0x10e16)
<bochs:9>c
<bochs:10>s //进入relocate
<bochs:11>u /20
<bochs:12>pb 0x10251 //在relocate返回点设置断点
<bochs:13>c
<bochs:14>s
可以看间,返回的新地址是0x93606,boot的代码在机器上被重新定位到了0x93606-0x10e16=0x827f0处。
现在我们可以重新设置execute函数的断点。它应该位于0x94e7a,所以输入以下内容:
<bochs:14>pb 0x94e7a
再运行可以发现,Bochs果然停在了预料的位置,看来前面的分析过程没有问题。接下来就可以进一步跟踪Minix的启动过程了。
jmp 1002:0015
它实际上就是跳转到下面一行:
mov ax, 1000 //指令地址:0x10035
…
接下来可以看到代码一直运行到boothead.s中调用boot函数的汇编代码:
…
jmp no_ext
adj_ext:
add 14(di), bx ! Add ext mem above 16M to mem below 16M
no_ext:
! Time to switch to a higher level language (not much higher)
call _boot //调用boot函数
结合/boot文件的反汇编代码,可以判定boot函数的地址为0x1267a。
启动Bochs,然后在调试窗口设置断点后运行:
<bochs:1>pb 0x10124 //设置物理地址断点
<bochs:2>c
运行一段时间后,Bochs停在了0x10124处。接下来单步运行进入boot函数:
<bochs:3>s
<bochs:4>u /10 //列出反汇编代码
0001267a :( ): push bp
0001267b :( ): mov bp, sp
0001267d :( ): call .+0xe6cb
00012680 :( ): call .+0xeccc
…
从列出的反汇编代码可以看出execute函数的调用应该在0x1002:266a这一行,所以设置断点:
<bochs:5>pb 0x1268a
不过遗憾的是系统并没有在预料的地方停下来,而是一直运行下去了,看来一定是因为某种原因使断点失效了。经过测试发现,汇编语句在第一个call语句(initialize函数)就没有返回,这是什么原因呢?其实只要看一看initialize函数的代码就可以发现,这个函数把启动程序拷贝到了low memory(640k)的远端(far end),也就是接近640k的地方。所以整个启动代码的基地址在这个函数中的某一句之后就全部改变了,看来要想完全跟踪启动代码还要费一番功夫。
<bochs:6>pb 0x1267d //在initialize函数处设置断点
<bochs:7>s //进入函数
<bochs:8>u /20
使拷贝到新地址的启动程序运行的是initialize函数中调用的第二个过程relocate,它位于boothead.s中。所以可以先找到后面的第二个call指令(即relocate函数)进入,这个汇编函数最后返回的地址就是新定位的地址了。
<bochs:8>pb 0x10e13 //在relocate的入口设置断点(下一条指令的地址是0x10e16)
<bochs:9>c
<bochs:10>s //进入relocate
<bochs:11>u /20
<bochs:12>pb 0x10251 //在relocate返回点设置断点
<bochs:13>c
<bochs:14>s
可以看间,返回的新地址是0x93606,boot的代码在机器上被重新定位到了0x93606-0x10e16=0x827f0处。
现在我们可以重新设置execute函数的断点。它应该位于0x94e7a,所以输入以下内容:
<bochs:14>pb 0x94e7a
再运行可以发现,Bochs果然停在了预料的位置,看来前面的分析过程没有问题。接下来就可以进一步跟踪Minix的启动过程了。
相关文章推荐
- 用Bochs学习Minix(2)-启动过程分析
- Windows操作系统学习之——启动引导过程调试(一)
- 利用Bochs调试linux的启动过程
- 利用Bochs调试linux0.11启动过程
- 利用Bochs调试linux的启动过程
- androoid framework学习之 - RILd启动过程和如何接收framwork层的消息流程(二)
- 学习笔记--- U-BOOT从启动到引导内核过程分析
- 学习笔记3-跟踪分析Linux内核的启动过程
- Windows XP \Windows 2003启动过程的学习及故障分析处理(六A)
- [软件调试学习笔记]WinDbg演示IA-32 CPU下的Windows 分页机制下的地址转换过程
- RobotFrameWork调试过程中启动很多chromedriver,结束*driverserver的方法
- 【MySQL学习笔记】MySQL 启动过程
- Android开发学习笔记4--安卓程序安装与启动过程剖析
- coco2dx-2.2.2 win32启动过程(opengl 和 窗口大小初始化部分) - 学习笔记 1
- c++--SDI的启动和关闭的调试跟踪的过程摘抄
- Pixhawk学习笔记(5)——PX4FLOW光流传感器调试过程记录
- 伟东山学习--1--内核makefile,启动过程.
- Linux学习-Linux启动过程
- Elasticsearch2.4学习(四)------源码分析之启动过程
- node.js学习第2天,启动 调试