2013-10-10 30 views
2

我正在尝试浏览本教程中显示的简单引导程序:http://mikeos.berlios.de/write-your-own-os.html - 因此我可以使用Qemu监视器来检查通用寄存器以用于教育目的。gdb忽略Qemu引导程序中的断点

尽管我能够连接Qemu和gdb,并且在引导加载程序(0x7c0)的开头设置了断点,但在gdb上点击“c”后,代码只会一直运行直到结束。

我读过kvm可能会“混淆”gbd与虚拟内存地址,所以我禁用了它。这没有奏效。

我也读过(Debugging bootloader with gdb in qemu)从HEAD编译gdb后调试Freedos启动时的工作。我没有重新编译gdb,而是尝试调试Freedos启动 - 它工作正常!

所以,我相信我的问题实际上是让教程的引导程序逐步执行。

我想其他的事情(他们没有工作):

使用几十个“SI”插入断点 尝试不同的断点地址 使用上QEMU的-singlestep键之前

这里是我的QEMU命令行:

QEMU系统-I386 -FDA disquete.img -boot一个-s -S -monitor标准输入输出

这里是内部GDB我的命令序列:

(GDB)目标远程本地主机:1234 (GDB)集架构i8086 (GDB)BR * 0x7c0

然后我打了 “C”,它只是通过断点一路。

版本:

$ UNAME -a

Linux的布罗德3.8.0-30泛型#44,Ubuntu的SMP周四8月22日20时52分24秒UTC 2013 x86_64的x86_64的x86_64的GNU/Linux的

$ GDB --version

GNU GDB(GDB)7.5.91.20130417-CVS-ubuntu的

$ QEMU --version

QEMU仿真器版本1.4.0(Debian的1.4.0 + DFSG-1expubuntu4)版权所有(C)2003-2008法布里斯·贝拉

正如我能够逐步通过FreeDOS的引导,我相信我的设置是罚款而且我必须在对本文开头提到的bootloader教程启动过程的一些概念性误解中失败。

欢迎所有帮助!

+0

请注意,自举程序在'0x7c00'(一个零)。这是否更好? – Jester

+0

我实际上已经尝试在http://mikeos.berlios.de/write-your-own-os.html上重写代码(它实际上在0x7c0上工作得很好),所以它会在0x7c00上加载,与Freedos的地址相同。然后Qemu一直在等待软盘,没有任何反应。另一种方法(我相信)只是忘记我现在正在使用的引导加载程序,并尝试使用这个wikibooks页面(http://en.wikibooks.org/wiki/X86_Assembly/Bootloaders)。然而,我很好奇为什么我不能让Qemu停止在0x7c0地址......我会这样做,并在接下来的几周内报告我的结果。谢谢! –

+1

还要记住,在实模式下,0x7c00可以使用'0x7c0'偏移量'0'来寻址,但调试器对此并不知情,需要物理地址。 – Jester

回答

0

我实际上能够调试我从mikeos.berlios.de/write-your-own-os.html中取出的示例引导程序,将其重写为专门加载到0x7c00。我的信息(比这里的贡献等)来源为:

http://en.wikibooks.org/wiki/X86_Assembly/Bootloaders http://viralpatel.net/taj/tutorial/hello_world_bootloader.php

最后的代码是这样的:

[BITS 16]   ; Tells nasm to build 16 bits code 
[ORG 0x7C00]  ; The address the code will start 

start: 
    mov ax, 0  ; Reserves 4Kbytes after the bootloader 
    add ax, 288 ; (4096 + 512)/ 16 bytes per paragraph 
    mov ss, ax 
    mov sp, 4096 
mov ax, 0 ; Sets the data segment 
    mov ds, ax 
    mov si, texto ; Sets the text position 
    call imprime ; Calls the printing routine 
jmp $  ; Infinite loop 
    texto db 'It works! :-D', 0 
imprime:   ; Prints the text on screen 
    mov ah, 0Eh  ; int 10h - printing function 
.repeat: 
    lodsb   ; Grabs one char 
    cmp al, 0 
    je .done  ; If char is zero, ends 
    int 10h   ; Else prints char 
jmp .repeat 
.done: 
ret 
times 510-($-$$) db 0 ; Fills the remaining boot sector with 0s 
dw 0xAA55    ; Standard boot signature 

现在我可以通过程序步骤,看看寄存器改变。

2

由于硬件虚拟化的,它可能有必要使用硬件断点:

(gdb) hbreak *0x7c00

另外注意在gdb正确的体系结构,即使使用的是64位的CPU(或KVM)时:由于CPU仍处于实模式,引导程序需要(gdb) set architecture i8086