-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathuRenovate.sh
executable file
·241 lines (223 loc) · 7.49 KB
/
uRenovate.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
!/bin/bash
set -euo pipefail
#set -x
warning="This application is designed to modify the EFI partition and \
bootloader of your system. Running this program can result in \
corruption of the operating system and loss of data. \
Are you sure you want to continue? (yes/no): "
edk2_dir="$(pwd)/edk2/" # Default location to look for EFI binaries
install="true" # Default action is to install
uninstall="false"
offline="false" # Run in offline mode. Set to true by kickstart script
demo="false" # Enable auto-uninstall and extra breakpoints
## check command line options
while getopts ":uo" o; do
case "${o}" in
u) uninstall="true"
install="false"
;;
o) offline="true"
;;
*) echo 'This script will install a microcode update program to the EFI boot partition.'
echo
echo 'usage'
echo 'uRenovate.sh [-o] [-u]'
exit 0
;;
esac
done
shift $((OPTIND-1))
## Display warning, get confirmation
read -p "$warning" -r
echo
if [[ ! $REPLY =~ ^[Yy] ]]
then
exit 0
fi
## You're letting this script modify your bootloader
if [[ $EUID -ne 0 ]]; then
echo "ERROR: This script must be run as root"
exit 1
fi
## Install microcode tools and latest firmware
if [ $offline == "false" ]; then
if [ -e /etc/redhat-release ]; then
yum -y install iucode-tool efivar microcode_ctl
elif [ -e /etc/debian_version ]; then
apt update
apt -y install iucode-tool efivar intel-microcode amd64-microcode
else
echo "Unsupported distro"
exit 1
fi
fi
## find a microcode file for this system to fix Spectre
set +e
bundle=$(iucode_tool --date-after=2018-03-20 -S -l /lib/firmware/intel-ucode/ | grep sig | sed 's#^ 0\(.*\)/...: sig.*#\1#')
set -e
if [ "$bundle" == "" ]; then
echo "ERROR: Could not find a microcode patch for this system that fixes Spectre."
if [ "$offline" == "true" ]; then
echo " Try running in online mode to download the latest updates."
fi
exit 1
fi
## Get the location of the microcode patch file to copy to the EFI partition
set +e
ucode=$(iucode_tool -l /lib/firmware/intel-ucode/ | grep "microcode bundle $bundle" | cut -d " " -f 4)
set -e
if [ -e $ucode ]; then
echo "Found microcode file for this system at: $ucode"
else
echo "ERROR: Could not find file for microcode bundle $bundle"
exit 1
fi
## try to find EFI boot partition
set +e
guesses=$(lsblk -i -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE | grep "part.*fat" | grep -v "initramfs.live" | wc -l)
set -e
if [ $guesses -eq 1 ]; then
part=$(lsblk -i -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE | grep "part.*fat" | grep -v "initramfs.live" | cut -d " " -f 1 | sed 's/|-//')
echo "Found an EFI partition: $part"
elif [ $guesses -eq 0 ]; then
echo "Could not find an EFI partition, exiting."
exit 1
else
echo "Support for multiple EFI partitions not implemented."
exit 1
fi
## mount EFI boot partition so it can be modified
if [ -e /mnt/efi ]; then
if [ -d /mnt/efi ]; then
echo "Unmounting whatever was on /mnt/efi/"
set +e
umount /mnt/efi
set -e
else
echo "Cound not create mount point"
exit 1
fi
else
mkdir -p /mnt/efi
fi
drive=$(echo $part | grep -o "[[:alpha:]]*")
partnum=$(echo $part | grep -o "[[:digit:]]*$")
echo "Mounting EFI partition on $drive (partition number $partnum) at /mnt/efi/"
mount $(find /dev -name $part) /mnt/efi/
set +e
testboot=$(efibootmgr | grep -i "MicroRenovator")
set -e
if [ "$testboot" != "" ]; then
echo "WARNING: Microrenovator has already been installed, canceling instalation."
install="false"
fi
## Look for Windows bootloader entry in EFI boot options
set +e
testboot=$(efibootmgr -v | grep -i "Boot.*Windows" | grep -io "File.*efi" | awk -F'\' '{print $NF}')
set -e
if [ "$testboot" == "" ]; then
echo "ERROR: No Windows bootloader found in EFI boot options."
exit 1
fi
## Look for bootloader file in EFI partition
bootloader=$(find /mnt/efi/ -iname "$testboot")
if [ "$bootloader" != "" ]; then
echo "Bootloader found at: $bootloader"
bootpath=$(dirname "${bootloader}")
shortbootpath=$(echo "$bootpath" | sed 's#^/mnt/efi##' | tr '/' '\\')
bootname=$(basename "${bootloader}")
else
echo "ERROR: Could not find Windows EFI bootloader file. "
exit 1
fi
## Uload needs to run from the default EFI boot directory
## Can only handle standard EFI boot configuration, so exit if it's not found
if [ ! -d /mnt/efi/EFI/BOOT/ ]; then
echo "ERROR: couldn't find /EFI/BOOT/ directory"
exit 1
fi
## Check for previous installation of Micro Renovator
if [ -e /mnt/efi/EFI/BOOT/Shell.efi ]; then
if [ "$install" == "true" ]; then
echo "WARNING: Shell.efi has already been installed, canceling instalation."
fi
install="false"
elif [ -e /mnt/efi/EFI/BOOT/Uload.efi ]; then
echo "ERROR: found /mnt/efi/EFI/BOOT/Uload.efi on system without MicroRenovator boot entry."
echo "ERROR: Previous installion corrupted. Manual cleanup needed before proceeding."
exit 1
elif [ -e /mnt/efi/EFI/BOOT/ucode.pdb ]; then
echo "ERROR: found /mnt/efi/EFI/BOOT/ucode.pdb without Uload.efi updater."
echo "ERROR: Previous installion corrupted. Manual cleanup needed before proceeding."
exit 1
fi
## Install/Uninstall Uload.efi
if [ "$install" == "true" ]; then
echo "Installing UEFI shell."
cp $edk2_dir/Build/Shell/RELEASE_GCC5/X64/Shell.efi /mnt/efi/EFI/BOOT/
echo "Installing microcode loader."
cp $edk2_dir/Build/Uload/RELEASE_GCC5/X64/Uload.efi /mnt/efi/EFI/BOOT/
cp $ucode /mnt/efi/EFI/BOOT/ucode.pdb
if [ "$demo" == "true" ]; then
cat <<EOF > /mnt/efi/EFI/BOOT/startup.nsh
echo -off
Uload.efi
pause
echo "Now running $shortbootpath\\$bootname"
$shortbootpath\\$bootname
EOF
else
cat <<EOF > /mnt/efi/EFI/BOOT/startup.nsh
echo -off
Uload.efi
echo "Now running $shortbootpath\\$bootname"
$shortbootpath\\$bootname
EOF
fi
efibootmgr -c -d /dev/$drive -p $partnum -L MicroRenovator -l "\EFI\BOOT\Shell.efi"
echo
echo "-------------------------------------"
echo "| Microcode Renovation complete |"
echo "| To uninstall, run uRenovate.sh -u |"
echo "-------------------------------------"
elif [ "$uninstall" == "true" ] || [ "$demo" == "true" ]; then
set +e
testboot=$(efibootmgr | grep -i "MicroRenovator" | grep -io "Boot0...")
set -e
if [ "$testboot" == "" ]; then
echo "WARNING: Can't find Microrenovator EFI Boot entry to remove."
else
efibootmgr -b $(echo $testboot | sed 's/Boot0*//') -B
fi
if [ -e /mnt/efi/EFI/BOOT/Shell.efi ]; then
echo "Removing Shell.efi"
rm /mnt/efi/EFI/BOOT/Shell.efi
else
echo "WARNING: Shell.efi not found, unable to remove."
fi
if [ -e /mnt/efi/EFI/BOOT/Uload.efi ]; then
echo "Removing microcode loader."
rm /mnt/efi/EFI/BOOT/Uload.efi
else
echo "WARNING: Uload.efi not found, unable to remove."
fi
if [ -e /mnt/efi/EFI/BOOT/ucode.pdb ]; then
echo "Removing microcode patch file."
rm /mnt/efi/EFI/BOOT/ucode.pdb
else
echo "WARNING: ucode.pdb not found, unable to remove."
fi
if [ -e /mnt/efi/EFI/BOOT/startup.nsh ]; then
echo "Removing EFI startup script."
rm /mnt/efi/EFI/BOOT/startup.nsh
else
echo "WARNING: startup.nsh not found, unable to remove."
fi
echo
echo "-----------------------------------------"
echo "| Microcode Renovation complete |"
echo "| Microcode loader has been uninstalled |"
echo "-----------------------------------------"
else
echo "Microcode loader already installed on this system. No action taken."
fi