[SOLVED]GDB breaks after a far jump in real mode
Posted: Sat Aug 03, 2024 2:58 am
I use Qemu and GDB to develop a OS. I'm on the process of "Use MBR code to load bootloader". To save addressing space, I use a far jump instruction when jump to bootloader from MBR. After that, GDB don't know where is the executing line of source code.
Source code can be found here:
https://github.com/stskyblade/StarOS
Steps to reproduce:
(You need a cross compiler)
After far jmp, I can't use 's' to resume execution. Error message is "Cannot find bounds of current function".
MBR is loaded into memory at address 0x7c00. Bootloader is loaded into memory at address 0x7e00, which is 512 Bytes after MBR.
Before the far jmp instruction, CS:IP is something like 0x0000:0x7cxx.
After it, CS:IP is 0x7c0:0x200. This address is 0x7e00 pointing to bootloader_start.
What I tried:
I guess GDB use the value in IP register and symbol file to find the executing line of code. After far jmp, IP is 0x200, which doesn't exist on symbol file build/mbr.elf. In that file, 0x7e00 points to bootloader_start.
I generate another symbol file using new linker script. (This hasn't been pushed to Github)
In this linker script, I set the start address of .text section from 0x7c00 to 0x00. At this point, 0x200 should point to bootloader_start.
Steps to reproduce:
(You need a cross compiler)
After presss "c", the program was executing but didn't stop on any breakpoint. It should stop on bootloader_start, then line 23, then line 24...
Source code can be found here:
https://github.com/stskyblade/StarOS
Steps to reproduce:
(You need a cross compiler)
Code: Select all
make debug
# run gdb
gdb
(gdb) b mbr.S:26
(gdb) c # breakpoint before far jmp
(gdb) s # execute far jmp
After far jmp, I can't use 's' to resume execution. Error message is "Cannot find bounds of current function".
MBR is loaded into memory at address 0x7c00. Bootloader is loaded into memory at address 0x7e00, which is 512 Bytes after MBR.
Before the far jmp instruction, CS:IP is something like 0x0000:0x7cxx.
After it, CS:IP is 0x7c0:0x200. This address is 0x7e00 pointing to bootloader_start.
What I tried:
I guess GDB use the value in IP register and symbol file to find the executing line of code. After far jmp, IP is 0x200, which doesn't exist on symbol file build/mbr.elf. In that file, 0x7e00 points to bootloader_start.
I generate another symbol file using new linker script. (This hasn't been pushed to Github)
In this linker script, I set the start address of .text section from 0x7c00 to 0x00. At this point, 0x200 should point to bootloader_start.
Steps to reproduce:
(You need a cross compiler)
Code: Select all
make debug
# run gdb
gdb
(gdb) symbol-file build/mbr_debug.elf
(gdb) b bootloader_start
(gdb) bootloader.S:23
(gdb) bootloader.S:24
(gdb) bootloader.S:25
(gdb) c