rom-parser icon indicating copy to clipboard operation
rom-parser copied to clipboard

cat: rom: Input/output error

Open mgsqz opened this issue 5 years ago • 19 comments

Hi,It's seems didn't work on proxmox 5.4-11 platform: cpu:i7-3820qm chipset:hm77 GPU:NVIDIA Corporation GF108M [GeForce GT 635M]

root@nserver:~# cd /sys/bus/pci/devices/0000:01:00.0/ root@nserver:/sys/bus/pci/devices/0000:01:00.0# echo 1 > rom root@nserver:/sys/bus/pci/devices/0000:01:00.0# cat rom > /tmp/image.rom cat: rom: Input/output error

dmesg: vfio-pci 0000:01:00.0: Invalid PCI ROM header signature: expecting 0xaa55, got 0xffff

what's wrong?

mgsqz avatar Jul 30 '19 13:07 mgsqz

I have run into the same problem (as i have a optimus laptop too by looking at your spec).

Basically, some dgpu in optimus laptop don't have the rom loaded from the gpu directly (afaik most desktop gpu do the reverse here) or just don't have enough permissions to do it, or even because the gpu is still in use (aka most optimus gpu don't support hotswapping); afaik that's all the reason i can think of but i could be wrong. But fortunately, there is still ways to get the rom of the gpu:

  • On windows, the rom is loaded as a .reg file in the registry, so you can get it there (more info here)
  • You can use either vbiosfinder or romparser on the update/dump of your bios (romparser is already included in vbiosfinder btw).which you can usually find on the manufacturer site or if normal dumping tools support your bios already...
  • If the above doesn't work (which would surprise me, but just in case), you can use binwalk on each file from the bios dump until you see something akin to "manufacturer's name" or "gpu vendor" or anything similar.

nordmagnus999 avatar Oct 27 '19 21:10 nordmagnus999

I have some problem with some older cards, especially ATI ones.. On normal desktop PC.

ruthan avatar Apr 10 '20 22:04 ruthan

you can only get the rom file in BIOS boot mode it seems, try boot your system in legacy mode with a linux distro and do that again.

abigchopstick avatar May 14 '20 07:05 abigchopstick

root@pve:/# cd /sys/bus/pci/devices/0000:02:00.0/ root@pve:/sys/bus/pci/devices/0000:02:00.0# echo 1 > rom root@pve:/sys/bus/pci/devices/0000:02:00.0# cat rom > /tmp/image.rom cat: rom: Input/output error root@pve:/sys/bus/pci/devices/0000:02:00.0# echo 0 > rom

My PVE system shows this. What should I do?

sjkhsl avatar Aug 23 '20 15:08 sjkhsl

@sjkhsl, As abigchopstick said, try booting in Legacy mode from USB using another distro. I used Ubuntu Server and successfully dumped my ROM the usual way.

ChrisG661 avatar Aug 29 '20 08:08 ChrisG661

I want to dump the rocketlake rom, is it possible?

KEV936 avatar Feb 19 '22 15:02 KEV936

Try to enable CSM in your host bios/uefi settings. Works for me.

zhaozhao avatar Sep 13 '22 09:09 zhaozhao

Still it would be nice to print some error that CSM is not enable etc..

ruthan avatar Sep 16 '22 11:09 ruthan

There is a workaround:

find /sys/devices -name rom
/sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/0000:66:08.0/0000:67:00.0/0000:68:00.0/0000:69:00.0/rom
/sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/0000:66:10.0/0000:6a:00.0/0000:6b:00.0/0000:6c:00.0/rom
/sys/devices/pci0000:16/0000:16:00.0/0000:17:00.0/0000:18:08.0/0000:19:00.0/0000:1a:10.0/0000:22:00.0/0000:23:00.0/0000:24:00.0/rom
/sys/devices/pci0000:16/0000:16:00.0/0000:17:00.0/0000:18:08.0/0000:19:00.0/0000:1a:04.0/0000:1b:00.0/rom
sudo su
setpci -s 0000:24:00.0 COMMAND=2:2 (manually manipulate the memory enable bit with setpci)
export PATH_TO_ROM=/sys/devices/pci0000:16/0000:16:00.0/0000:17:00.0/0000:18:08.0/0000:19:00.0/0000:1a:10.0/0000:22:00.0/0000:23:00.0/0000:24:00.0/rom
echo 1 > $PATH_TO_ROM
mkdir -p /var/lib/libvirt/vbios/
cat $PATH_TO_ROM > /var/lib/libvirt/vbios/gpu.rom
echo 0 > $PATH_TO_ROM
setpci -s 0000:24:00.0 COMMAND=0:2 (Clear memory enable bit with setpci)
exit

startergo avatar Jan 15 '23 23:01 startergo

Workaround without any comment how Linuxian.. its possible just to create some script etc for normal human beings?

ruthan avatar Jan 20 '23 15:01 ruthan

Workaround without any comment how Linuxian.. its possible just to create some script etc for normal human beings?

Maybe I should just delete my previous comment to prevent normal human beings confusion? :) I will gladly do so. Just let me know.

startergo avatar Jan 20 '23 17:01 startergo

@startergo Hi, I try your workaround, but it doesn't work for me. :(

root@pve:/sys/bus/pci/devices/0000:00:02.0# setpci -s 0000:00:02.0 COMMAND=2:2 
root@pve:/sys/bus/pci/devices/0000:00:02.0# echo 1 > rom
root@pve:/sys/bus/pci/devices/0000:00:02.0# cat rom  > /tmp/image.rom
cat: rom: Input/output error

yjun123 avatar Jul 27 '23 16:07 yjun123

but it doesn't work for me

You need to first find the rom location:

find /sys/devices -name rom

Then after enabling the memory enable bit with setpci :

echo 1 > "discovered_full_path_to_the_rom"

Just like in the example above.

startergo avatar Jul 28 '23 01:07 startergo

@startergo I post the complete command log output below.

root@pve:~# find /sys/devices -name rom
/sys/devices/pci0000:00/0000:00:02.0/rom
root@pve:~# cd /sys/devices/pci0000:00/0000:00:02.0
root@pve:/sys/devices/pci0000:00/0000:00:02.0# setpci -s 0000:00:02.0 COMMAND=2:2 
root@pve:/sys/devices/pci0000:00/0000:00:02.0# echo 1 > rom 
root@pve:/sys/devices/pci0000:00/0000:00:02.0# cat rom  > /tmp/image.rom
cat: rom: Input/output error

yjun123 avatar Jul 29 '23 03:07 yjun123

cd /sys/devices/pci0000:00/0000:00:02.0

Skip the above command and use absolute path to the ROM for the echo 1 command.

startergo avatar Aug 01 '23 22:08 startergo

cd /sys/devices/pci0000:00/0000:00:02.0

Skip the above command and use absolute path to the ROM for the echo 1 command.

From the results, there doesn't seem to be any difference.

root@pve:~# find /sys/devices -name rom
/sys/devices/pci0000:00/0000:00:02.0/rom
root@pve:~#  setpci -s 0000:00:02.0 COMMAND=2:2
root@pve:~# echo 1 > /sys/devices/pci0000:00/0000:00:02.0/rom
root@pve:~# cat /sys/devices/pci0000:00/0000:00:02.0/rom > /tmp/images.rom
cat: '/sys/devices/pci0000:00/0000:00:02.0/rom': Input/output error

yjun123 avatar Aug 06 '23 13:08 yjun123

root@pve:~# setpci -s 0000:00:02.0 COMMAND=2:2

After this try:

echo 0 > /sys/devices/pci0000:00/0000:00:02.0/power
echo 1 > /sys/devices/pci0000:00/0000:00:02.0/rom
cat /sys/devices/pci0000:00/0000:00:02.0/rom > /tmp/images.rom
echo 1 > /sys/devices/pci0000:00/0000:00:02.0/power

startergo avatar Aug 06 '23 13:08 startergo

echo 0 > /sys/devices/pci0000:00/0000:00:02.0/power

root@pve:~# echo 0 > /sys/devices/pci0000:00/0000:00:02.0/power -bash: /sys/devices/pci0000:00/0000:00:02.0/power: Is a directory

yjun123 avatar Aug 11 '23 14:08 yjun123

Try this script: https://github.com/SpaceinvaderOne/Dump_GPU_vBIOS Adjust the script variables accordingly If it is an Nvidia GPU replace the Nvidia drivers with Nouveau drivers.

NVIDIA VBIOS Step 1: How to extract or obtain your VBIOS
Option 1 (preferred): Pull the rom via nvidia's proprietary tool nvflash (https://www.techpowerup.com/download/nvidia-nvflash/). The download is a zipped binary (not source), simply unzip it, chmod +x, and run it: ./nvflash --save original.rom.
Note1: This tool does not work when the nvidia proprietary driver is bound to the card. It will work with no driver bound, vfio-pci, or in some cases nouveau (sketchy).
Note2: This can also be done with windows both native and virtualized using GPU-z's save vbios button. GPU-z uses nvflash internally
Option 2: Download a rom from Techpowerup's database that matches your PCI ID's and Subsystem ID's. Here is an example with a GT 710:
$ lspci -nnk
(...)
0a:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK208B [GeForce GT 710] [10de:128b] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] GK208B [GeForce GT 710] [1462:8c93]
The ID's are 10de:128b and 1462:8c93. Google techpowerup + these numbers and download a rom that matches. Double check that all ID's match
[10:30 PM]Aiber: NVIDIA VBIOS Step 2: Determining the start of the VBIOS within the ROM file
NVIDIA rom files contain extra data (IFR, other firmware, etc.) at the start of the file. We can obtain the vbios portion of the rom by trimming off the unwanted bits. This must be removed before passing it to a VM.
Use rom-parser (https://github.com/awilliam/rom-parser) and look for the first entry Valid ROM signature found @XXXXh:
$ rom-parser original.rom
Valid ROM signature found @600h, PCIR offset 190h
PCIR: type 0 (x86 PC-AT), vendor: 10de, device: 128b, class: 030000
PCIR: revision 0, vendor revision: 1
Valid ROM signature found @fc00h, PCIR offset 1ch
PCIR: type 3 (EFI), vendor: 10de, device: 128b, class: 030000
PCIR: revision 3, vendor revision: 0
EFI: Signature Valid, Subsystem: Boot, Machine: X64
Last image
The header size is the hexadecimal value @600h which is 1536 bytes in decimal. (edited)
[10:30 PM]Aiber: NVIDIA VBIOS Step 3: Removing the headers
If the value from step 2 is not zero, the extraneous data must be removed, 0x600 bytes in particular this case:
$ dd if=original.rom of=vbios.rom bs=$((0x600)) skip=1
You may verify the result by redoing step 2 on the new file to confirm the rom now starts at @0h (the beginning of the file.)
NVIDIA VBIOS Step 4: Passing a VBIOS to the VM
Libvirt: Under <hostdev> for the GPU video device add <rom file='/path/to/vbios.rom'/> Qemu: -device vfio-pci,host=01:00.0,romfile=/path/to/vbios.rom

AMD also has a linux tool AMDVBFLASH

You can also use GetPciOprom from EFI shell: https://github.com/savvamitrofanov/EdkiiShellTool

startergo avatar Aug 14 '23 09:08 startergo