title: What does "echo 1 > rom" for PCI devices do, and how can I do it programatically?
body: <p>I am trying to write a program to dump option/expansion ROMs on linux. I already have the necessary PCI port IO to get an expansion ROM's base address out of the PCI configuration data at offset 0x30 and make it enabled, but when I try to access the base in memory I get a segfault. So I am trying to understand what is happening when you do the "echo 1 > rom" from a linux command line, since after that the rom seems plenty accessible (see here for a little more context: <a href="http://etherboot.org/wiki/romdumping" rel="nofollow">http://etherboot.org/wiki/romdumping</a>)</p>
  
  <p>E.g. let's say I do the following:</p>
  
  <p>lspci</p>
  
  <p>
  01:00.0 VGA compatible controller: ATI Technologies Inc RV370 5B60 [Radeon X300 (PCIE)]
  </p>
  
  <p>cd /sys/bus/pci/devices/0000:01:00.0</p>
  
  <p>lspci -x -v -s 01:00.0</p>
  
  <pre><code>01:00.0 VGA compatible controller: ATI Technologies Inc RV370 5B60 [Radeon X300 (PCIE)]
          Subsystem: ATI Technologies Inc Device 0402
          Flags: bus master, fast devsel, latency 0, IRQ 27
          Memory at d0000000 (32-bit, prefetchable) [size=128M]
          I/O ports at dc00 [size=256]
          Memory at dfde0000 (32-bit, non-prefetchable) [size=64K]
          Expansion ROM at dfe00000 [disabled] [size=128K]
          Capabilities: [50] Power Management version 2
          Capabilities: [58] Express Endpoint, MSI 00
          Capabilities: [80] Message Signalled Interrupts: Mask- 64bit+ Queue=0/0 Enable+
          Capabilities: [100] Advanced Error Reporting &lt;?&gt;
          Kernel driver in use: radeon
          Kernel modules: radeonfb, radeon
  00: 02 10 60 5b 07 04 10 00 00 00 00 03 10 00 80 00
  10: 08 00 00 d0 01 dc 00 00 00 00 de df 00 00 00 00
  20: 00 00 00 00 00 00 00 00 00 00 00 00 02 10 02 04
  30: 00 00 e0 df 50 00 00 00 00 00 00 00 0b 01 00 00
  </code></pre>
  
  <p>Note the line that says "Expansion ROM at dfe00000 [disabled] [size=128K]"
  Now per the PCI spec I can see that the bottom bit should be set to 1 to enable the expansion ROM, so I did a read and write back of 0xdfe00001, and then I get</p>
  
  <pre><code>01:00.0 VGA compatible controller: ATI Technologies Inc RV370 5B60 [Radeon X300 (PCIE)]
          Subsystem: ATI Technologies Inc Device 0402
          Flags: bus master, fast devsel, latency 0, IRQ 27
          Memory at d0000000 (32-bit, prefetchable) [size=128M]
          I/O ports at dc00 [size=256]
          Memory at dfde0000 (32-bit, non-prefetchable) [size=64K]
          Expansion ROM at dfe00000 [size=128K]
          Capabilities: [50] Power Management version 2
          Capabilities: [58] Express Endpoint, MSI 00
          Capabilities: [80] Message Signalled Interrupts: Mask- 64bit+ Queue=0/0 Enable+
          Capabilities: [100] Advanced Error Reporting &lt;?&gt;
          Kernel driver in use: radeon
          Kernel modules: radeonfb, radeon
  00: 02 10 60 5b 07 04 10 00 00 00 00 03 10 00 80 00
  10: 08 00 00 d0 01 dc 00 00 00 00 de df 00 00 00 00
  20: 00 00 00 00 00 00 00 00 00 00 00 00 02 10 02 04
  30: 01 00 e0 df 50 00 00 00 00 00 00 00 0b 01 00 00
  </code></pre>
  
  <p>(note the 0x01 at offset 0x30 and the line now saying "Expansion ROM at dfe00000 [size=128K]"). </p>
  
  <p>But I can't access 0xdfe00000. Meanwhile, when O do the "echo 1 > rom" in the command line, it does <em>NOT</em> change the line to remove the "disabled", and really it doesn't make any change at all to the output of lspci. So what is the "echo 1 > rom" doing that I'm not, which makes it subsequently possible to do the "dd if=rom of=/tmp/rom"?</p>
  
  <p>Much appreciated</p>