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 here
Any insights, or suggestions on how to resolve this issue would be greatly appreciated. Thank you!
Wrong service
You want the 'Disable A20 Gate' service at
int 15h. You have erroneously invoked the video BIOS service interruptint 10h.Missing SP
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