Debugging with gdb&qemu, breakpoints fail on virtual address
Posted: Wed Jul 03, 2013 4:27 am
I managed to setup virtual address for kernel via GDT on i386, however I found that GDB does not work properly when I debug it with QEMU.
Here is the skeleton of my source code:
https://github.com/korepwx/pcore/tree/b ... 972c3bf0e2
Bootloader does never setup a virtual memory address space. It simply load kernel into memory. My kernel.ld is like this (tools/kernel.ld):
And, in bootmain.c, it loads the kernel into 0x100000 (and later call the routine) by doing this (boot/bootmain.c):
When kern_entry (arch/i386/init/entry.S) is called, it soon sets up GDT for virtual address:
And the kern_init routine (kern/init/init.cc):
Everything works fine until I try to make GDB break at kern_init. GDB indeeds loads in symbol table, and tell me kern_init is at 0xC0100030. But GDB cannot break at 0xC0100030. What's more, if I tell GDB to stop at 0x100030, it works but can never recover from breakpoint.
Could anyone help me to figure out what's wrong with my code?
BTW, I'm using Qemu 1.4.0.
Here is the skeleton of my source code:
https://github.com/korepwx/pcore/tree/b ... 972c3bf0e2
Bootloader does never setup a virtual memory address space. It simply load kernel into memory. My kernel.ld is like this (tools/kernel.ld):
Code: Select all
ENTRY(kern_entry)
SECTIONS {
/* Load the kernel at this address: "." means the current address */
. = 0xC0100000;
Code: Select all
for (; ph < eph; ph++) {
readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset);
}
((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF)) ();
Code: Select all
.text
.globl kern_entry
kern_entry:
# reload temperate gdt (second time) to remap all physical memory
# virtual_addr 0~4G=linear_addr&physical_addr -KERNBASE~4G-KERNBASE
lgdt REALLOC(__gdtdesc)
movl $KERNEL_DS, %eax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
ljmp $KERNEL_CS, $relocated
...
.align 4
__gdt:
SEG_NULL
SEG_ASM(STA_X | STA_R, - KERNBASE, 0xFFFFFFFF) # code segment
SEG_ASM(STA_W, - KERNBASE, 0xFFFFFFFF) # data segment
Code: Select all
extern "C" {
/**
* @brief The main entry for kernel.
* This method is called by bootloader; @sa boot/bootmain.c
*/
int kern_init(void)
{
return 0;
}
}
Could anyone help me to figure out what's wrong with my code?
BTW, I'm using Qemu 1.4.0.