-
Notifications
You must be signed in to change notification settings - Fork 46
/
dump_vbios.sh
executable file
·371 lines (324 loc) · 11.9 KB
/
dump_vbios.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
#!/bin/bash
# Script to dump GPU vbios from any Unraid GPU
# by SpaceinvaderOne
##### Read the readme for how to use this script #####
##### FILL IN THE VARIABLES BELOW #######################################################################
###################
gpuid="xxxxxx"
###################
#####Name the vbios for example gtx2080ti.rom
### Naming of the vbios is optional .... if you do not rename it here then the script will name it based off the details found about the gpu dumped
###################
vbiosname="gpu vbios.rom"
###################
##### Location to put vbios (change if you dont want to use below location) if location doesnt exist it will be created for you.
###################
vbioslocation="/mnt/user/isos/vbios/"
###################
##### Runs checks on device to see if it is in fact a GPU. Recommended to leave set as "yes"
###################
safety="yes"
###################
########## DO NOT CHANGE BELOW THIS LINE #################################################################
gpuid=$(echo "$gpuid" | sed 's/ *$//')
gpuid=$(echo "$gpuid" | sed 's/^ *//g')
dumpid="0000:$gpuid"
mygpu=$(lspci -s $gpuid)
disconnectid=$(echo "$dumpid" | sed 's?:?\\:?g')
disconnectid2=$(echo "$disconnectid" | sed 's/\(.*\)0/\11/')
vganame=$( lspci | grep -i "$gpuid" )
forcereset="no"
########## Script functions #################################################################
checkgpuiscorrect() {
mygpu=$(lspci -s $gpuid) || { notvalidpci; exit; }
echo "You have selected this device to dump the vbios from"
if grep -i 'VGA compatible controller' <<< "$mygpu" ; then
if grep -i 'Intel' <<< "$mygpu" ; then
echo "This looks like its an integrated INTEL GPU and vbios dump will most likely FAIL"
echo "Please select a dedicated GPU to dump vbios from"
echo "If you really want to try then rerun script changing variable to safety=off"
else
echo
echo "This does look like a valid GPU to me. Continuing ........."
echo
fi
elif grep -i 'Audio Device' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like an AUDIO device"
echo "Maybe you have selected the audio part of your GPU ?"
echo "Please edit the script and make sure to put the id of ONLY the VGA part of your GPU"
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are all the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'USB controller' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a USB controller"
echo "Some GPUs have a USB part to them. Maybe you selected that ?"
echo "Please edit the script and make sure to put the id of ONLY the VGA part of your GPU"
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'Serial bus controller' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a USB type C controller"
echo "Some GPUs have a USB type C part to them. Maybe you selected that ?"
echo "Please edit the script and make sure to put the id of ONLY the VGA part of your GPU"
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'Network controller' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a NETWORK adapter "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'Ethernet controller' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a NETWORK adapter "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'SATA controller' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a SATA controller "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'Non-Volatile memory controller' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a NVME controller "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'PCI bridge' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a PCI bridge "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'Host bridge' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a HOST bridge "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'SMBus' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a SMBus controller "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
elif grep -i 'Encryption controller' <<< "$mygpu" ; then
echo
echo "This doesn't look like a GPU to me. It looks like a Encryption controller "
echo "Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
else
echo "$mygpu"
echo
echo "This doesn't look like a GPU to me. Please correct the id and rerun the script."
echo "If you are 100 % sure this is the VGA part of your GPU then rerun script changing variable to safety=off"
echo
echo "These are the GPUs that I can see in your server"
lspci | grep -i 'vga'
exit
fi
}
notvalidpci() {
echo "That is NOT a valid PCI device. Please correct the id and rerun the script"
echo
echo "These are all the GPUs that I can see in your server. Please choose one of these"
lspci | grep -i 'vga'
}
checklocation() {
# check if vbios location exists and if not create it
echo
echo "Checking if location to put vbios file exists"
if [ ! -d "$vbioslocation" ] ; then
echo "Vbios folder created at "$mountlocation" "
echo
mkdir -vp "$vbioslocation" # make the directory as it doesnt exist
else
echo "Vbios folder "$mountlocation" already exists"
echo
fi
}
buildtempvm() {
cat > /tmp/dumpvbios.xml << EOF
<?xml version='1.0' encoding='UTF-8'?>
<domain type='kvm'>
<name>dumpvbios</name>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<memoryBacking>
<nosharepages/>
</memoryBacking>
<vcpu placement='static'>1</vcpu>
<cputune>
<vcpupin vcpu='0' cpuset='0'/>
</cputune>
<os>
<type arch='x86_64' machine='pc-q35-3.0'>hvm</type>
</os>
<cpu mode='host-passthrough' check='none' >
</cpu>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/local/sbin/qemu</emulator>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x8'/>
</controller>
<hostdev mode='subsystem' type='pci' managed='yes' xvga='yes'>
<driver name='vfio'/>
<source>
<address domain='0x${dumpid:0:4}' bus='0x${dumpid:5:2}' slot='0x${dumpid:8:2}' function='0x${dumpid:11:1}'/>;
</source>
</hostdev>
</devices>
</domain>
EOF
}
isgpuprimary () {
# Check Primary GPU and wether gpu has already been disconnected
# Disconnect GPU and set server to sleep mode then rescan bus
if [ "$forcereset" = "yes" ] ; then
echo "Disconnecting the graphics card"
echo "1" | tee -a /sys/bus/pci/devices/$disconnectid/remove
echo "Entered suspended (sleep) state ......"
echo
echo " PRESS POWER BUTTON ON SERVER TO CONTINUE"
echo
echo -n mem > /sys/power/state
echo "Rescanning pci bus"
echo "1" | tee -a /sys/bus/pci/rescan
echo "Graphics card has now sucessfully been disconnected and reconnected"
echo "It is now ready to begin the dump vbios process"
echo
elif [ "$forcereset" = "no" ] ; then
echo "I will try and dump the vbios without disconnecting and reconnecting the GPU"
echo "This normally only works if the GPU is NOT the Primary or the only GPU"
echo "I will check the vbios at the end. If it seems wrong I will then retry after disconnecting the GPU"
echo
else
echo "forcereset is set as "$forcereset" this is not a recognised option"
echo "Please set forcereset to either yes or no "
exit
fi
}
startstopvm() {
echo "Defining temp vm with gpu attached"
virsh define /tmp/dumpvbios.xml
echo "Starting the temp vm to allow dump"
virsh start dumpvbios
echo "Waiting for a few seconds ....."
echo
sleep 9
echo "Stopping the temp vm "
virsh destroy dumpvbios
echo "Removing the temp vm"
virsh undefine dumpvbios
}
dumpvbios() {
# if no name was given for vbios then make name from vga name from lspci
if [ "$vbiosname" = "gpu vbios.rom" ] ; then
vbiosname=$( echo "$vganame" | awk 'NR > 1 {print $1}' RS='[' FS=']' )
fi
echo
cd /sys/bus/pci/devices/"$dumpid"/
echo 1 > rom
echo
echo "Okay dumping vbios file named "$vbiosname" to the location "$vbioslocation" "
cat rom > "$vbioslocation""$vbiosname" || needtobind
echo 0 > rom
}
needtobind() {
echo
echo "Um.... somethings gone wrong and I couldn't dump the vbios for some reason"
echo "Sometimes when this happens all we need to do to fix this is 'stub' or 'bind to the vfio' the gpu and reboot the server"
echo
echo "This can be done in Unraid 6.8.3 with the use of the vfio config plugin or if you are on Unraid 6.9 or above it can be done"
echo "directly from the gui in Tools/System Devices .....So please do this and run the script again"
echo
exit
}
cleanup() {
if [ -e /tmp/dumpvbios.xml ] ; then
rm /tmp/dumpvbios.xml
fi
}
checkvbios() {
filepath="$vbioslocation""$vbiosname"
if [ -n "$(find "$filepath" -prune -size -2000c)" ]; then
needtobind
elif [ -n "$(find "$filepath" -prune -size -70000c)" ]; then
printf '%s is less than 70kb\n' "$filepath"
echo "This seems too small. Probably the GPU is Primary and needs disconnecting and reconnecting to get proper vbios"
echo
echo "Running again"
forcereset="yes"
buildtempvm
isgpuprimary
startstopvm
dumpvbios
cleanup
if [ -n "$(find "$filepath" -prune -size -70000c)" ]; then
printf '%s is less than 70kb\n' "$filepath"
echo "This seems small but maybe its correct. Please try it. All done !"
exit
fi
echo
echo "vbios seems to be correct. All done :)"
exit
else
echo
echo "vbios seems to be correct. All done :)"
exit
fi
}
########## run functions #################################################################
if [ "$safety" = "no" ] ; then
echo "Safety checks are disabled. Continuing ......"
else
checkgpuiscorrect
fi
checklocation
buildtempvm
isgpuprimary
startstopvm
dumpvbios
checkvbios
exit