在qemu+gdb的调试环境中,gdb的b命令生效地址必须是虚拟机的物理地址,但是OS中运行的程序大部分都是以虚拟地址出现的,所以计算出真实的物理地址才能下断点。
MIT6.828的LAB1中的内核代码中,内核段基址为0x10000000(可由kern/entry.S中的mygdt标号下的数据计算得到),这样如果一个虚拟地址是0xF010013A(kern/init.c中i386_init()函数入口),那么它的物理地址就是0x0010013A,要在这个地方设置断点才有效。同理由于gdb调试的时候引入符号文件可以看到源码,而在kernel中调试时候看到的源码也都是基于虚拟地址的,所以用源码行号或者函数作为断点同样不会起效。
bochs在这点上就做的比较友好,它可以设置三种地址类型的断点,虚拟地址(vb),线性地址(lb),物理地址(pb|b)。在调试kernel的前期,没有开启分页,所以线性地址等同于物理地址,如果想根据源码的虚拟地址来设置断点调试,就使用vb命令来设置。格式如下:
vb seg:offset
例如段选择符为8,偏移为0xF010013A(i386_init()函数入口)的断点就使用命令:
vb 8:0xF010013A
注意:bochs有个不好的地方就是:不能看源代码。虽然有载入符号文件的功能,但是这个符号文件仅仅是虚拟地址和标号名的符号表,而且我还不知道在什么地方可以用到这些符号,如果哪位同志对这里比较熟悉的话,还麻烦指点一下。
——————————————————————————
晚上,弄了下FB小同学的BadAppleOS,他在windows下编译的。移植到Linux下来编译还出现不少问题,最主要的是符号问题,在编译的过程中汇编中的符号丢失,看了下是section的问题,他定义了一个section,我放到.text下就ok。然后改写一些代码,把它移植到vx5的映像中去,用vx的的引导代码,就不需要grub。