2

bochs可以调试os,这个功能不一般,所以在学习过程中做一个简单的记录。

涉及到的工具有:

  1. bochs 调试器和pc仿真器

  2. nasm 汇编器,汇编源代码为机器码

  3. dd 写入img文件

假设一个bootsect,它可以打印hello到显示器,我们以此为案例学习bochs调试。代码是这样的(1.asm):


    mov ah, 0x0e ; tty mode
    mov al, 'H'
    int 0x10
    mov al, 'e'
    int 0x10
    mov al, 'l'
    int 0x10
    int 0x10 ; 'l' is still on al, remember?
    mov al, 'o'
    int 0x10
    
    jmp $ ; jump to current address = infinite loop
    
    ; padding and magic number
    times 510 - ($-$$) db 0
    dw 0xaa55 
    

首先编译代码:

    nasm -f bin -o 1.bin 1.asm

然后写入映像文件:

    dd if=1.bin of=1.img   bs=512 count=1 conv=notrunc 

配置bochs文件(bochsrc.bxrc):

    
    # 第一步,首先设置Bochs在运行过程中能够使用的内存,本例为32MB。
    # 关键字为:megs
    megs: 32
    # 第二步,设置对应真实机器的BIOS和VGA BIOS.
    # 对应两个关键字为:romimage 和 vgaromimage
    romimage: file=$BXSHARE/BIOS-bochs-latest
    vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest  
    # 第三步,设置Bochs所使用的磁盘,软盘的关键字为floppy。
    # 若只有一个软盘,则使用floppya即可,若有多个,则为floppya,floppyb...
    floppya: 1_44=1.img, status=inserted
    # 第四步,选择启动盘符。
    boot: floppy
    # 第五步,设置日志文件的输出。
    log: bochsout.txt
    # 第六步,开启或关闭某些功能。
    # 下面是关闭鼠标,并打开键盘。
    mouse: enabled=0

特别留意,设置floppya的时候,填写img文件名称,这里是1.img。

然后启动bochs.exe,可以看到仿真器屏幕上显示:

  hello

此时环境设置完毕。现在需要调试的话,启动的不是bochs,而是bochsdbg.exe。启动后,随机进入等待状态,可是尝试单步执行,使用s命令。然而看到的都是不懂的指令,也和我们的代码无关,因为刚刚进来的时候执行的代码是bios指令。我们的指令被加载在0x7c00处,可以通过b指令设置断点,使用c指令执行到断点:

b 0x7c00
c

系统回应:

    (0) [0x000000007c00] 0000:7c00 (unk. ctxt): mov ah, 0x0e              ; b40e   

确实是我们的第一个指令。使用u指令反汇编到:

 u 0x7c00 0x7c16

响应:

00007c00: (                    ): mov ah, 0x0e              ; b40e
00007c02: (                    ): mov al, 0x48              ; b048
00007c04: (                    ): int 0x10                  ; cd10
00007c06: (                    ): mov al, 0x65              ; b065
00007c08: (                    ): int 0x10                  ; cd10
00007c0a: (                    ): mov al, 0x6c              ; b06c
00007c0c: (                    ): int 0x10                  ; cd10
00007c0e: (                    ): int 0x10                  ; cd10
00007c10: (                    ): mov al, 0x6f              ; b06f
00007c12: (                    ): int 0x10                  ; cd10
00007c14: (                    ): jmp .-2                   ; ebfe

再次设置断点,并执行到此处:

b 0x7c10
c

回应:

显示为hell。

在c,执行完毕。


Reco
4.6k 声望541 粉丝

敢作敢为


引用和评论

0 条评论