4

我正在尝试逐步完成本教程中显示的简单引导加载程序:http: //mikeos.berlios.de/write-your-own-os.html - 所以我可以使用 Qemu 监视器检查通用寄存器以用于教育目的。

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

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

我还阅读了(在 qemu 中使用 gdb 调试引导加载程序)在从 HEAD 编译 gdb 后调试 Freedos 引导时工作正常。我没有重新编译 gdb,而是尝试调试 Freedos 引导 -它有效!

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

我尝试过的其他事情(都没有奏效):

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

这是我的 qemu 命令行:

qemu-system-i386 -fda disquete.img -boot a -s -S -monitor stdio

这是我在 gdb 中的命令序列:

(gdb) 目标远程 localhost:1234 (gdb) 设置架构 i8086 (gdb) br *0x7c0

然后我点击“c”,它就一直通过断点。

版本:

$ unname -a

Linux Brod 3.8.0-30-generic #44-Ubuntu SMP Thu Aug 22 20:52:24 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

$ gdb --版本

GNU gdb (GDB) 7.5.91.20130417-cvs-ubuntu

$ qemu--版本

QEMU 仿真器版本 1.4.0 (Debian 1.4.0+dfsg-1expubuntu4),版权所有 (c) 2003-2008 Fabrice Bellard

由于我能够逐步完成 Freedos 引导,我确实相信我的设置很好,而且我一定是在对本文开头提到的引导加载程序教程的引导过程的一些概念性误解中失败了。

欢迎所有帮助!

4

2 回答 2

3

由于硬件虚拟化,可能需要使用硬件断点:

(gdb) hbreak *0x7c00

还要注意 gdb 中的正确架构,即使使用 64 位 CPU(或 kvm):引导加载程序需要(gdb) set architecture i8086,因为 CPU 仍处于实模式。

于 2015-01-24T05:05:24.950 回答
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

现在我可以单步执行程序并查看寄存器的变化。

于 2014-06-25T12:57:18.317 回答