poniedziałek, 22 lutego 2016

EDKII and QEMU - remote debugging with gdb

While working with UEFI debugger can be very helpful. I was using EDKII project to write my UEFI applications and I was testing it with QEMU. I added my application information file to the OvmfPkg module information and this let me to running my program using existing script.
To build OvmfPkg and run QEMU run (in the OvmfPkg folder):
 ./build.sh -A IA32 qemu -s -monitor stdio -debugcon file:debug.log -global isa-debugcon.iobase=0x402  
After start debug.log file will be created where you can read output from UEFI.
We need to know where your application will be loaded (memory address). Run your application in QEMU:
 Shell> fs0:  
 fs0:\> MyApp.efi  
Open debug.log file (in the EDKII directory), and find line with name of your loaded application. You should get something like this:
 Loading driver at 0x00006B75000 EntryPoint=0x00006B75220 MyApp.efi  
And this is our address:
 EntryPoint=0x00006B75220  
Now open second terminal, open directory with your application's debugging symbols and efi file (for me: Build/OvmfIa32/DEBUG_GCC48/IA32/MyApp.debug) and run gdb:
 gdb --tui  
We need to know where particular sections are located. Load efi file and enter info files:
 (gdb) file MyApp.efi  
 Reading symbols from MyApp.efi...(no debugging symbols found)...done.  
 (gdb) info files  
 Symbols from ".../edk2/Build/OvmfIa32/DEBUG_GCC48/IA32/MyApp.efi".  
 Local exec file:  
     `.../Build/OvmfIa32/DEBUG_GCC48/IA32/MyApp.efi', file type pei-i386.  
     Entry point: 0x220  
     0x00000220 - 0x00003a40 is .text  
     0x00003a40 - 0x00004320 is .data  
     0x00004320 - 0x00004520 is .reloc  
We need to calculate our addresses for text and data section. Application is loaded under 0x00006B75220 (entry point) and we know text and data offsets.
text = 0x06B75220
data = 0x06B75220 + 0x00003a40 = 0x06B78C60

Now unload efi file:
 (gdb) file  
 No executable file now.  
 No symbol file now.  
Load symbols:
 (gdb) add-symbol-file MyApp.debug 0x06B75220 -s .data 0x06B78C60
add symbol table from file "MyApp.debug" at
        .text_addr = 0x6b75220
        .data_addr = 0x6b78c60
(y or n) y
Reading symbols from MyApp.debug...done.
You can add some breakpoints, for example:
 break UefiMain  
And attach debugger to the QEMU:
 target remote localhost:1234  
And run QEMU:
 ./build.sh -A IA32 qemu -s -monitor stdio -debugcon file:debug.log -global isa-debugcon.iobase=0x402  
Machine will be paused, type "continue", load your application. Done!



Links:
http://osdevnotes.blogspot.com/2011/05/using-gdb-to-debug-uefi.html
http://wiki.osdev.org/Debugging_UEFI_applications_with_GDB
http://comments.gmane.org/gmane.comp.bios.tianocore.devel/6777

1 komentarz: