调试引导加载程序代码时 GDB 中出现“无法找到当前函数的边界”错误

问题描述 投票:0回答:1

我目前正在学习引导加载程序开发和使用GDB进行调试,以观察在实模式下禁用A20线时的内存变化。由于 QEMU 自动启用 A20 线,我尝试使用

int 15
中断来禁用它。我有一个引导加载程序 (boot.S),我正在尝试使用 GDB 进行调试。

我已经在

.gdbinit
中设置了调试环境,然后在
make debug
中启动了 GDB。但是,当我尝试单步执行代码时,遇到错误“找不到当前函数的边界”。这种情况在执行第 18 行 (boot.S) 的
int
指令后尤其会发生。

我知道我在这里做错了(我的汇编代码技能仍在发展),但我不知道它是什么:(

启动.S

BOOT_SIGNATURE = 0xAA55
A20_TEST_VALUE = 0x3773

ES_EDGE_ADDR   = 0xFFFF
ES_OFFSET_ADDR = 0x0010

.code16
.global start
start:
    xorw %ax, %ax
    cli
    cld
    movw %ax, %ds
    movw %ax, %ss
    movw %ax, %es

movw $0x2400, %ax
int $0x10

call check_a20_status
jmp .

check_a20_status:
    xorw %ax, %ax
    movw %ax, %ds
    movw %ax, %es
    movw %ax, %cx
    movw $ES_EDGE_ADDR, %ax
    movw $ES_OFFSET_ADDR, %bx
    movw %ax, %es
    movw $A20_TEST_VALUE, %es:(%bx)
    movw %ds:0x0, %ax

    ret

signature_padding:
    .space 510 - (. - start)
    .word  BOOT_SIGNATURE

生成文件

CC = gcc
CFLAGS = -nostartfiles -nostdlib -m32 -e start -g
LFLAGS = -Wl,-Ttext=0x7c00 -Wl,--build-id=none -Wl,--oformat=binary
BOOT_BIN = -o boot.bin
BOOT_SRC = boot.S
GDB_PORT=3773

obj:
    gcc -nostartfiles -nostdlib -m32 -e start -g -Wl,-Ttext=0x7c00 -o boot.out boot.S
    
image: obj
    $(CC) $(CFLAGS) $(LFLAGS) $(BOOT_BIN) $(BOOT_SRC)
    
debug: image
    qemu-system-i386 -drive file=boot.bin,format=raw -nographic -serial mon:stdio -gdb tcp::$(GDB_PORT) -S
    
gdb:
    gdb -n -x .gdbinit

clean:
    rm -rf *.bin *.out      

.gdbinit

set architecture i8086
target remote localhost:3773
symbol-file boot.out

我在一个终端中使用命令

make debug
启动了 qemu,然后使用命令
make gdb
在另一个终端中启动了 gdb。我在这里附上了 gdb 输出的屏幕截图

任何有关如何解决此问题的见解或建议将不胜感激。谢谢!

assembly x86 bootloader osdev gnu-assembler
1个回答
0
投票

服务错误

movw $0x2400, %ax
int $0x10

您需要在

int 15h
处使用“禁用 A20 登机口”服务。您错误地调用了视频 BIOS 服务中断
int 10h

缺少SP

xorw %ax, %ax
cli
cld
movw %ax, %ds
movw %ax, %ss
movw %ax, %es

如果要更改 SS 段寄存器,则还要设置 SP 堆栈指针。假设 SS:SP 之前有效并且 SP 包含一个小数字,那么省略初始化 SP(就像您所做的那样)将使 SS:SP 指向中断向量表内。任何进一步使用堆栈(通过

int
,...)都将开始破坏中断向量!

解决方案

cli
cld
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $0x7C00, %sp

movw $0x2400, %ax
int $0x15
© www.soinside.com 2019 - 2024. All rights reserved.