如何用GDB进行调试和QEMU引导程序/ BIOS时跨过中断调用? [英] How to step over interrupt calls when debugging a bootloader/bios with gdb and QEMU?

查看:270
本文介绍了如何用GDB进行调试和QEMU引导程序/ BIOS时跨过中断调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关教育目的,我从 mikeos.berlios.de/适应了这个引导程序写你自己的os.html 改写地址0x7c00专门加载。

For educational purposes, I have adapted this bootloader from mikeos.berlios.de/write-your-own-os.html rewriting it to specifically load at address 0x7c00.

最后code是这样的:

The final code is this:

[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

我可以通过程序步骤,看看寄存器发生变化,正在执行的指令,一起GDB(SI)加强和QEMU检查监督(信息登记,X / I $ EIP等)。

I can step through the program and see the registers changing, along with the instruction being executed, stepping with gdb (si) and inspecting with QEMU monitor (info registers, x /i $eip, etc).

在我进入INT 10H(BIOS的打印程序),事情就变得有点怪。如果我在一次踩500的指令,我可以看到印在屏幕上的字符I(我的第一文本字符串的字符的)。于是,我再次重新启动并加强400步(SI 400),然后我也一步一个脚印的时间,看看其具体的步骤I得到了印。它从来没有发生过。其实我踩200步,一招一式没有动静。当我走到100步一次(SI 100)我得到了我在屏幕上打印一次。

After I get into int 10h (the BIOS printing routine), things get a little strange. If I step 500 instructions at once, I can see the character "I" (the first of char of my text string) printed on the screen. So I restarted again and stepped 400 steps (si 400) and then I did one step at a time to see in which exact step "I" got printed. It never happened. I actually stepped 200 steps one by one and nothing happened. As soon as I stepped 100 steps at once (si 100) I got "I" printed on the screen again.

所以,我不知道是否有一个时机的问题(一些系统中断帮倒忙,因为我做的一步步调试)。还有什么会这样?

So, I wonder if there is a timing issue (some system interrupt gets in the way as I do a step by step debug). What else could this be?

不管怎样,有没有跳过整个BIOS中断等功能,只是回去继续加强引导程序code的一种方式?正如彼得Quiring 的意见建议,我尝试使用下一个。这并没有工作。

Anyway, is there a way of skipping the whole BIOS interrupt and other functions and just go back and keep stepping the bootloader code? As suggested by Peter Quiring in the comments, I tried using next. This did not work.

(gdb) next 
Cannot find bounds of current function

所以,我想nexti,它只是表现为SI。

So I tried nexti and it just behaves as si.

谢谢!

推荐答案

这其实是一种变通适合我的目的。我所做的就是设置断点,这样我就可以用继续关于广东发展银行与SI一起,并按照被打印在屏幕上的消息,一次一个字符。下面是步骤。

This is actually a work around that fits my purposes. What I did was setting breakpoints so I can use "continue" on gdb along with "si" and follow the message being printed on the screen, one character at a time. Here are the steps.

在第一次运行时,我做我的步骤引导程序,所以我其实可以检查其中指令存储在内存中的位置。

In the first run, I do step my bootloader, so I can actually check the memory positions where the instructions are stored.

Linux shell中:

Linux shell:

# qemu-system-i386 -fda loader.img -boot a -s -S -monitor stdio
QEMU 1.5.0 monitor - type 'help' for more information
(qemu) 

其他Linux的shell(有些线路已经苏pressed [...]):

Other Linux shell (some lines have been supressed [...]):

# gdb
GNU gdb (GDB) 7.6.1-ubuntu
[...]
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x0000fff0 in ?? ()
(gdb) set architecture i8086
[...]
(gdb) br *0x7c00
Ponto de parada 1 at 0x7c00
(gdb) c
Continuando.
Breakpoint 1, 0x00007c00 in ?? ()
(gdb) si
0x00007c03 in ?? ()

在我运行QEMU监控终端,我觉得对GDB每次SI后执行此命令的说明地址:

In the terminal I am running QEMU monitor, I find the address of the instructions executing this command after every si on gdb:

(qemu) x /i $eip
0x00007c03:  add    $0x120,%ax

对于这些新的QEMU,X显示寄存器的内容,/我把它翻译成指令和$ EIP是指令指针寄存器。通过重复这些步骤,我发现地址为LODSB和INT 10H说明:

For those new to QEMU, x display the contents of a register, /i translates it into an instruction and $eip is the instruction point register. By repeating these steps, I find out the addresses for the lodsb and int 10h instructions:

0x00007c29:  lods   %ds:(%si),%al 
0x00007c2e:  int    $0x10 

因此​​,在GDB我刚刚设置的断点这些aditional的位置:

So, on gdb I just set the breakpoints for these aditional positions:

(gdb) br *0x7c29
Ponto de parada 2 at 0x7c29
(gdb) br *0x7c2e
Ponto de parada 3 at 0x7c2e

现在我可以使用gdb的继续(c)和STEPI(SI)的组合,并通过对整个BIOS的东西跳过。

Now I can use a combination of "continue" (c) and stepi (si) on gdb and skip through the whole BIOS stuff.

有可能是更好的方式来做到这一点。但是,对于我的教学目的,这种方法效果很好。

There is probably better ways to do this. However, for my pedagogical purposes, this method works quite well.

这篇关于如何用GDB进行调试和QEMU引导程序/ BIOS时跨过中断调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆