"Cannot find bounds of current function" error in GDB while debugging bootloader code

87 Views Asked by At

I'm currently learning bootloader development and debugging with GDB to observe memory changes when the A20 line is disabled in real mode. Since QEMU automatically enables the A20 line, I'm attempting to disable it using the int 15 interrupt. I have a bootloader (boot.S) that I'm trying to debug using GDB.

I've set up my debugging environment in .gdbinit followed by make debug to launch GDB. However, when I try to step through my code, I encounter the error "Cannot find bounds of current function". This particularly occurs after executing the int instruction at line number 18 (boot.S).

I know I am doing something wrong here(my assembly code skills are still developing), but I don't know what it is :(

boot.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

Makefile

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

I launched qemu using the command make debug in one terminal and then started the gdb in another terminal using the command make gdb. I have attached the screenshot of gdb output hereenter image description here

Any insights, or suggestions on how to resolve this issue would be greatly appreciated. Thank you!

1

There are 1 best solutions below

3
Sep Roland On

Wrong service

movw $0x2400, %ax
int $0x10

You want the 'Disable A20 Gate' service at int 15h. You have erroneously invoked the video BIOS service interrupt int 10h.

Missing SP

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

If you're going to change the SS segment register, then also setup the SP stack pointer. Suppose SS:SP was valid before and SP held a small number, then omitting initializing SP (like you are doing) would make SS:SP point to within the Interrupt Vector Table. Any further use of the stack (through int, ...) would begin destroying interrupt vectors!

Solution

cld
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss       <<<<< To be kept close together
movw $0x7C00, %sp   <<<<<  and in this particular order!

movw $0x2400, %ax
int  $0x15