After several hours of Googling and trying, I have finally successfully setup the environment for debugging GRUB2 under QEMU with GDB. The following are the steps I have taken.
1. Get the latest GRUB2 from GNU GRUB website, which is currently grub-2.00.tar.xz.
2. Compile GRUB2 with the following commands:
./configure --prefix=/home/coryxie/grub/install make make install
3. Create the GRUB2 CDROM image using the following shell script:
#!/bin/sh echo Creating bootable CD image... mkdir -p bin mkdir -p boot #cp /boot/grub2/grub.cfg boot/grub.cfg cp /boot/vmlinuz-3.3.4-5.fc17.x86_64 bin/kernel grub2-mkimage --format=i386-pc --prefix="(cd)" --directory=/home/coryxie/grub/install/lib/grub/i386-pc --output=bin/core.img \ --config="boot/grub.cfg" loadenv biosdisk part_msdos part_gpt fat ntfs \ ext2 ntfscomp iso9660 loopback search linux boot minicmd cat cpuid chain \ halt help ls reboot echo test configfile normal sleep memdisk tar font \ gfxterm gettext true vbe vga video_bochs video_cirrus multiboot multiboot2 cat /home/coryxie/grub/install/lib/grub/i386-pc/cdboot.img bin/core.img > bin/grub.img genisoimage -graft-points -input-charset utf8 -A "grub2" -quiet -R -b \ boot/grub/grub.img -no-emul-boot -boot-load-size 4 -boot-info-table \ -o bootcd.iso \ boot/kernel=bin/kernel \ boot/grub/grub.cfg=boot/grub.cfg \ boot/grub/grub.img=bin/grub.img
The boot/grub.cfg file in the above script has the following contents:
set default=5 set timeout=5 menuentry "OS" { multiboot /boot/kernel boot }
5. Install qemu-system-* as "sudo yum install qemu-system-*"
6. Start QEMU with the GRUB2 CDROM image as below, make it waiting for GDB connection at startup:
qemu-system-x86_64 -cdrom bootcd.iso -s -S
7. In another shell prompt, change current directory to the GRUB2 build directory, then change to grub-core directory, and start GDB as below:
[coryxie@localhost grub-core]$ gdb -x gdb_grub GNU gdb (GDB) Fedora (7.4.50.20120120-42.fc17) Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. 0x0000fff0 in mem_regions () Breakpoint 1 at 0xb569: file kern/dl.c, line 56. (gdb) b grub_cmd_ls Function "grub_cmd_ls" not defined. (gdb) b grub_main Breakpoint 2 at 0xcb08: file kern/main.c, line 209. (gdb) c Breakpoint 2, grub_main () at kern/main.c:209 209 { (gdb) info registers eax 0x0 0 ecx 0x0 0 edx 0xe0ffffff -520093697 ebx 0x1725e4 1517028 esp 0x7fff0 0x7fff0 ebp 0x7fff0 0x7fff0 esi 0x9025 36901 edi 0x17618 95768 eip 0xcb08 0xcb08 <grub_main> eflags 0x46 [ PF ZF ] cs 0x8 8 ss 0x10 16 ds 0x10 16 es 0x10 16 fs 0x10 16 gs 0x10 16 (gdb) c add symbol table from file "extcmd.module" at .text_addr = 0x7ffba20 .rodata_addr = 0x7ffc204 .rodata.str1.1_addr = 0x7ffc24c .module_license_addr = 0x7ffc388 add symbol table from file "loadenv.module" at .text_addr = 0x7ffa2d0 .rodata_addr = 0x7ffac44 .rodata.str1.1_addr = 0x7ffac74 .module_license_addr = 0x7ffae50 .bss_addr = 0x7ffae60 add symbol table from file "biosdisk.module" at .text_addr = 0x7ff8e90 .rodata.str1.1_addr = 0x7ff97d0 .data_addr = 0x7ff9930 .module_license_addr = 0x7ff9950 .bss_addr = 0x7ff9960 add symbol table from file "part_msdos.module" at .text_addr = 0x7ff8620 .rodata.str1.1_addr = 0x7ff89e1 .data_addr = 0x7ff8a8c .module_license_addr = 0x7ff8a9c add symbol table from file "part_gpt.module" at .text_addr = 0x7ff7da0 .rodata_addr = 0x7ff80a8 .rodata.str1.1_addr = 0x7ff80b8 .data_addr = 0x7ff8148 .module_license_addr = 0x7ff8160 add symbol table from file "fat.module" at .text_addr = 0x7ff6830 .rodata.str1.1_addr = 0x7ff7546 .data_addr = 0x7ff75dc .module_license_addr = 0x7ff7604 .bss_addr = 0x7ff7614 add symbol table from file "fshelp.module" at .text_addr = 0x7ff5dd0 .rodata.str1.1_addr = 0x7ff634e .module_license_addr = 0x7ff63e0 add symbol table from file "ntfs.module" at .text_addr = 0x7ff35e0 .rodata.str1.1_addr = 0x7ff506a .data_addr = 0x7ff52a0 .module_license_addr = 0x7ff52c8 .bss_addr = 0x7ff52d8 add symbol table from file "ext2.module" at .text_addr = 0x7ff2040 .rodata.str1.1_addr = 0x7ff2c49 .data_addr = 0x7ff2d18 .module_license_addr = 0x7ff2d40 .bss_addr = 0x7ff2d50 add symbol table from file "ntfscomp.module" at .text_addr = 0x7ff1390 .rodata.str1.1_addr = 0x7ff1b55 .module_license_addr = 0x7ff1bdc add symbol table from file "iso9660.module" at .text_addr = 0x7fef270 .rodata_addr = 0x7ff08b8 .rodata.str1.1_addr = 0x7ff08dc .data_addr = 0x7ff09ac .module_license_addr = 0x7ff09d4 .bss_addr = 0x7ff09e4 add symbol table from file "loopback.module" at .text_addr = 0x7fee870 .rodata_addr = 0x7feeb34 .rodata.str1.1_addr = 0x7feeb64 .data_addr = 0x7feec1c .module_license_addr = 0x7feec3c .bss_addr = 0x7feec4c add symbol table from file "search_label.module" at .text_addr = 0x7fedc30 .rodata.str1.1_addr = 0x7fee09a .module_license_addr = 0x7fee158 .bss_addr = 0x7fee168 add symbol table from file "search_fs_file.module" at .text_addr = 0x7fecf70 .rodata.str1.1_addr = 0x7fed3d8 .module_license_addr = 0x7fed498 .bss_addr = 0x7fed4a8 add symbol table from file "search_fs_uuid.module" at .text_addr = 0x7fec2d0 .rodata.str1.1_addr = 0x7fec7a9 .module_license_addr = 0x7fec864 .bss_addr = 0x7fec874 add symbol table from file "search.module" at .text_addr = 0x7feb4b0 .rodata_addr = 0x7feb6a8 .rodata.str1.1_addr = 0x7feb7c8 .module_license_addr = 0x7febc60 .bss_addr = 0x7febc70 add symbol table from file "boot.module" at .text_addr = 0x7feab70 .rodata.str1.1_addr = 0x7feadd7 .data_addr = 0x7feae20 .module_license_addr = 0x7feae24 .bss_addr = 0x7feae34 add symbol table from file "mmap.module" at .text_addr = 0x7fe86c0 .rodata.str1.1_addr = 0x7fe98da .data_addr = 0x7fe9b18 .module_license_addr = 0x7fe9b1c .bss_addr = 0x7fe9b2c add symbol table from file "relocator.module" at .text_addr = 0x7fe44c0 .rodata_addr = 0x7fe6328 .rodata.str1.1_addr = 0x7fe63b8 .data_addr = 0x7fe66f0 .module_license_addr = 0x7fe66f8 .bss_addr = 0x7fe6708 add symbol table from file "video.module" at .text_addr = 0x7fe0450 .rodata_addr = 0x7fe1084 .rodata.str1.1_addr = 0x7fe1524 .module_license_addr = 0x7fe1ba0 .bss_addr = 0x7fe1bc0 add symbol table from file "video_fb.module" at .text_addr = 0x7fdab80 .rodata.str1.1_addr = 0x7fde1c0 .data_addr = 0x7fde1f4 .module_license_addr = 0x7fde234 .bss_addr = 0x7fde244 ---Type <return> to continue, or q <return> to quit--- add symbol table from file "vbe.module" at .text_addr = 0x7fd6d30 .rodata_addr = 0x7fd7ef8 .rodata.str1.1_addr = 0x7fd7f18 .data_addr = 0x7fd8078 .module_license_addr = 0x7fd80f8 .bss_addr = 0x7fd8108 add symbol table from file "gettext.module" at .text_addr = 0x7fd5620 .rodata.str1.1_addr = 0x7fd5dc2 .module_license_addr = 0x7fd5ebc .bss_addr = 0x7fd5ecc add symbol table from file "crypto.module" at .text_addr = 0x7fd43d0 .rodata.str1.1_addr = 0x7fd4bdf .module_license_addr = 0x7fd4bf0 .bss_addr = 0x7fd4c00 add symbol table from file "terminal.module" at .text_addr = 0x7fd2ba0 .rodata.str1.1_addr = 0x7fd31f2 .module_license_addr = 0x7fd3368 .bss_addr = 0x7fd3378 add symbol table from file "normal.module" at .text_addr = 0x7fb9c00 .text.unlikely_addr = 0x7fc5f97 .rodata_addr = 0x7fc6030 .rodata.str1.1_addr = 0x7fc8010 .data_addr = 0x7fc91f8 .module_license_addr = 0x7fcbcc0 .bss_addr = 0x7fcbcd0 add symbol table from file "linux.module" at .text_addr = 0x7fb2870 .rodata_addr = 0x7fb3b98 .rodata.str1.1_addr = 0x7fb3b9d .data_addr = 0x7fb3fa0 .module_license_addr = 0x7fb4258 .bss_addr = 0x7fb4268 add symbol table from file "minicmd.module" at .text_addr = 0x7fb1a00 .rodata.str1.1_addr = 0x7fb1dcc .module_license_addr = 0x7fb1f14 .bss_addr = 0x7fb1f24 add symbol table from file "cat.module" at .text_addr = 0x7fb10f0 .rodata_addr = 0x7fb12b0 .rodata.str1.1_addr = 0x7fb12e0 .module_license_addr = 0x7fb134c .bss_addr = 0x7fb135c add symbol table from file "cpuid.module" at .text_addr = 0x7fb0b90 .rodata_addr = 0x7fb0c3c .rodata.str1.1_addr = 0x7fb0c6c .module_license_addr = 0x7fb0cd4 .bss_addr = 0x7fb0ce4 add symbol table from file "chain.module" at .text_addr = 0x7fafd90 .rodata.str1.1_addr = 0x7fb019a .module_license_addr = 0x7fb0244 .bss_addr = 0x7fb0254 add symbol table from file "acpi.module" at .text_addr = 0x7fad680 .rodata_addr = 0x7fae6c0 .rodata.str1.1_addr = 0x7fae7c8 .module_license_addr = 0x7faecdc .bss_addr = 0x7faecec add symbol table from file "halt.module" at .text_addr = 0x7fac4d0 .rodata_addr = 0x7facb48 .rodata.str1.1_addr = 0x7facb78 .module_license_addr = 0x7facd14 .bss_addr = 0x7facd24 add symbol table from file "help.module" at .text_addr = 0x7faba70 .rodata.str1.1_addr = 0x7fabd40 .module_license_addr = 0x7fabd88 .bss_addr = 0x7fabd98 add symbol table from file "ls.module" at .text_addr = 0x7faaa20 .rodata_addr = 0x7faaf60 .rodata.str1.1_addr = 0x7faafc5 .module_license_addr = 0x7fab10c .bss_addr = 0x7fab11c add symbol table from file "reboot.module" at .text_addr = 0x7faa3d0 .rodata.str1.1_addr = 0x7faa4dc .module_license_addr = 0x7faa4f8 .bss_addr = 0x7faa508 add symbol table from file "echo.module" at .text_addr = 0x7fa9c00 .rodata_addr = 0x7fa9d84 .rodata.str1.1_addr = 0x7fa9dcc .module_license_addr = 0x7fa9e4c .bss_addr = 0x7fa9e5c add symbol table from file "test.module" at .text_addr = 0x7fa8900 .rodata.str1.1_addr = 0x7fa9289 .module_license_addr = 0x7fa9324 .bss_addr = 0x7fa9334 add symbol table from file "configfile.module" at .text_addr = 0x7fa80a0 .rodata.str1.1_addr = 0x7fa822b .module_license_addr = 0x7fa8324 .bss_addr = 0x7fa8334 add symbol table from file "sleep.module" at .text_addr = 0x7fa7820 .rodata_addr = 0x7fa7944 .rodata.str1.1_addr = 0x7fa798c .module_license_addr = 0x7fa7a30 .bss_addr = 0x7fa7a40 add symbol table from file "memdisk.module" at .text_addr = 0x7fa70c0 .rodata.str1.1_addr = 0x7fa7267 .data_addr = 0x7fa72d8 .module_license_addr = 0x7fa72f8 .bss_addr = 0x7fa7308 add symbol table from file "tar.module" at .text_addr = 0x7fa5d90 .rodata.str1.1_addr = 0x7fa688d .data_addr = 0x7fa6920 .module_license_addr = 0x7fa6948 .bss_addr = 0x7fa6958 add symbol table from file "bufio.module" at .text_addr = 0x7fa5610 .rodata.str1.1_addr = 0x7fa599a .data_addr = 0x7fa59a0 .module_license_addr = 0x7fa59c8 ---Type <return> to continue, or q <return> to quit--- add symbol table from file "font.module" at .text_addr = 0x7fa2f30 .rodata.str1.1_addr = 0x7fa4511 .data_addr = 0x7fa47d0 .module_license_addr = 0x7fa47e0 .bss_addr = 0x7fa47f0 add symbol table from file "bitmap.module" at .text_addr = 0x7fa1fb0 .rodata.str1.1_addr = 0x7fa22f9 .module_license_addr = 0x7fa2350 .bss_addr = 0x7fa2360 add symbol table from file "bitmap_scale.module" at .text_addr = 0x7fa11b0 .rodata.str1.1_addr = 0x7fa1740 .module_license_addr = 0x7fa18d0 add symbol table from file "gfxterm.module" at .text_addr = 0x7f9e2e0 .rodata_addr = 0x7f9f5f4 .rodata.str1.1_addr = 0x7f9f624 .data_addr = 0x7f9f740 .module_license_addr = 0x7f9f788 .bss_addr = 0x7f9f798 add symbol table from file "true.module" at .text_addr = 0x7f9dca0 .rodata.str1.1_addr = 0x7f9dd1a .module_license_addr = 0x7f9dd5c .bss_addr = 0x7f9dd6c add symbol table from file "vga.module" at .text_addr = 0x7f9cac0 .rodata.str1.1_addr = 0x7f9cff9 .data_addr = 0x7f9d06c .module_license_addr = 0x7f9d0e4 .bss_addr = 0x7f9d0f4 add symbol table from file "pci.module" at .text_addr = 0x7f9c5e0 .module_license_addr = 0x7f9c790 add symbol table from file "video_bochs.module" at .text_addr = 0x7f928c0 .rodata.str1.1_addr = 0x7f93017 .data_addr = 0x7f93120 .module_license_addr = 0x7f93198 .bss_addr = 0x7f931a8 add symbol table from file "video_cirrus.module" at .text_addr = 0x7f88fc0 .rodata_addr = 0x7f897c8 .rodata.str1.1_addr = 0x7f897ee .data_addr = 0x7f89938 .module_license_addr = 0x7f899b0 .bss_addr = 0x7f899c0 add symbol table from file "lsapm.module" at .text_addr = 0x7f88790 .rodata.str1.1_addr = 0x7f88999 .module_license_addr = 0x7f88b4c .bss_addr = 0x7f88b5c add symbol table from file "datetime.module" at .text_addr = 0x7f88270 .module_license_addr = 0x7f884d0 add symbol table from file "priority_queue.module" at .text_addr = 0x7f87c70 .module_license_addr = 0x7f87e5c add symbol table from file "net.module" at .text_addr = 0x7f78020 .rodata_addr = 0x7f7e950 .rodata.str1.1_addr = 0x7f7e9bc .data_addr = 0x7f7f5a8 .module_license_addr = 0x7f7f5e0 .bss_addr = 0x7f7f5f0 add symbol table from file "multiboot.module" at .text_addr = 0x7f73270 .rodata.str1.1_addr = 0x7f7496f .module_license_addr = 0x7f74cf0 .bss_addr = 0x7f74d00 add symbol table from file "multiboot2.module" at .text_addr = 0x7f6fb50 .rodata_addr = 0x7f71380 .rodata.str1.1_addr = 0x7f71398 .module_license_addr = 0x7f71704 .bss_addr = 0x7f71714 ^C Program received signal SIGINT, Interrupt. grub_bios_interrupt () at kern/i386/pc/../int.S:49 49 pushf (gdb) b grub_cmd_ls Breakpoint 3 at 0x7faacd5: file commands/ls.c, line 274. (gdb) c Breakpoint 3, grub_cmd_ls (ctxt=0x7fe68, argc=0, args=0x0) at commands/ls.c:274 274 { (gdb) where #0 grub_cmd_ls (ctxt=0x7fe68, argc=0, args=0x0) at commands/ls.c:274 #1 0x07ffba87 in grub_extcmd_dispatcher (cmd=<optimized out>, argc=0, args=0x7f4e9d4, script=0x0) at commands/extcmd.c:54 #2 0x07ffbac0 in grub_extcmd_dispatch (cmd=<optimized out>, argc=<optimized out>, args=<optimized out>) at commands/extcmd.c:67 #3 0x07fc3609 in grub_script_execute_cmdline (cmd=<optimized out>) at script/execute.c:927 #4 0x07fc23e8 in grub_script_execute_cmd (cmd=cmd@entry=0x7f4c764) at script/execute.c:753 #5 0x07fc31d3 in grub_script_execute_cmdlist (list=<optimized out>) at script/execute.c:972 #6 0x07fc23e8 in grub_script_execute_cmd (cmd=<optimized out>) at script/execute.c:753 #7 0x07fc3389 in grub_script_execute (script=script@entry=0x7f4ea30) at script/execute.c:1084 #8 0x07fc1e15 in grub_normal_parse_line (line=<optimized out>, getline=getline@entry=0x7fb9c8b <grub_normal_read_line>) at script/main.c:35 #9 0x07fba1c2 in grub_cmdline_run (nested=nested@entry=0) at normal/main.c:466 #10 0x07fba1eb in grub_enter_normal_mode ( config=config@entry=0x7f4f010 "(cd)/grub.cfg") at normal/main.c:320 #11 0x07fba234 in grub_cmd_normal (cmd=<optimized out>, argc=<optimized out>, argv=<optimized out>) at normal/main.c:345 ---Type <return> to continue, or q <return> to quit--- #12 grub_cmd_normal (cmd=<optimized out>, argc=<optimized out>, argv=<optimized out>) at normal/main.c:328 #13 0x0000cdc4 in grub_command_execute (name=<optimized out>, argc=<optimized out>, argv=<optimized out>) at ../include/grub/command.h:120 #14 grub_load_normal_mode () at kern/main.c:203 #15 grub_main () at kern/main.c:234 #16 0x00009041 in L_cont () at kern/i386/pc/startup.S:124 #17 0x00000000 in ?? () (gdb)
8. Do any GDB enabled debugging as you wish, for example, in the above debug session, I tried to set a breakpoint at the "ls" command entry point "grub_cmd_ls", then "c" to continue, and on the QEMU GRUB2 interface, issue "ls", then the GDB triggered the breakpoint and stopped, so I can issue any more debugging commands. Like below:
(gdb) info registers eax 0x7fe68 523880 ecx 0x0 0 edx 0x0 0 ebx 0x7faa940 133867840 esp 0x7fe40 0x7fe40 ebp 0x7fe8c 0x7fe8c esi 0x7f4ea00 133491200 edi 0x7f4e9d4 133491156 eip 0x7faacd5 0x7faacd5 <grub_cmd_ls> eflags 0x200002 [ ID ] cs 0x8 8 ss 0x10 16 ds 0x10 16 es 0x10 16 fs 0x10 16 gs 0x10 16 (gdb)
And the QEMU GRUB2 interface looks like something below: