Reverse Engineering PCI Drivers: Difference between revisions

From coreboot
Jump to navigation Jump to search
No edit summary
No edit summary
Line 20: Line 20:


   #define DEVICE_ASSIGNMENT_DEBUG 1  
   #define DEVICE_ASSIGNMENT_DEBUG 1  
This will turn on logging for the important slow_bar_read{b,w,l} and slow_bar_write{b,w,l} functions. You may also want to add d->e_physbase to the prints to get the physical assigned address.
In order to trace the write commands to the ROM space, you will need to add your own functions. Eg:
  static void slow_rom_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  {
      DEBUG(" addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr, val);
  }





Revision as of 02:07, 22 February 2010

(UNDER CONSTRUCTION) by Vikram Ambrose -- Vambrose 01:44, 22 February 2010 (UTC)

This is a short guide demonstrating how I used the PCI Passthrough framework in KVM to reverse engineer atiflash.exe – a video BIOS flashing tool for DOS.

atiflash.exe is a real dos application that flashes the video BIOS on ATi graphics cards. There are numerous ATi video BIOS flashing tools for Windows, but none for Linux as the code for doing this has not been made publicly available by AMD.

This technique allowed me to trace all PCI configuration space and memory mapped i/o (mmio) accesses to the PCI-E device from the closed source flashing tool.

Tools needed:

In order to give the virtual machine direct pci access, the host operating system cannot register a driver for the device. In my case, this simply meant blacklisting the radeon and drm kernel modules.

All the tracing is done from QEMU. Using the special qemu-kvm branch mentioned above, go into qemu-kvm/hw/device-assignments.c and ensure:

 #define DEVICE_ASSIGNMENT_DEBUG 1 

This will turn on logging for the important slow_bar_read{b,w,l} and slow_bar_write{b,w,l} functions. You may also want to add d->e_physbase to the prints to get the physical assigned address.

In order to trace the write commands to the ROM space, you will need to add your own functions. Eg:

 static void slow_rom_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     DEBUG(" addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr, val);
 }


Use lspci to get the location of the PCI device:

 02:00.0 VGA compatible controller: ATI Technologies Inc RV770 [Radeon HD 4870]
 02:00.1 Audio device: ATI Technologies Inc HD48x0 audio


Special thanks go out to Carl-Daniel Hailfinger, Twice#11 and the entire KVM and QEMU team for making this possible.