]> git.ipfire.org Git - people/ms/firmware-update.git/blame - src/firmware-update.in
Pass any extra command line arguments
[people/ms/firmware-update.git] / src / firmware-update.in
CommitLineData
82068881
MT
1#!/bin/bash
2###############################################################################
3# #
4# firmware-update - IPFire Firmware Update Tool #
5# Copyright (C) 2019 IPFire Development Team #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
96f10173
MT
22shopt -s nullglob
23
af9ef5f2
MT
24PACKAGE_NAME="@PACKAGE_NAME@"
25PACKAGE_VERSION="@PACKAGE_VERSION@"
26
96f10173
MT
27FIRMWARE_DIR="@firmwaredir@"
28
06d931fa
MT
29get_consent() {
30 local firmware="${1}"
31
32 cat <<EOF
33
34You are going to flash the firmware on device. This is a dangerous operation
35that might potentially damage your device.
36
37Please do NOT TURN OFF the system while the update is in progress and do
38not abort the process.
39
40 Firmware file: ${firmware}
41
42EOF
43
44 local answer
45 while [ -t 0 -a -t 1 -a -t 2 ]; do
46 # Wait for user to type y
47 printf "Do you want to proceed? [y/n] "
48 read -r answer
49
50 case "${answer}" in
51 y|Y)
52 return 0
53 ;;
54 n|N)
55 echo "Aborting."
56 return 1
57 ;;
58 esac
59 done
60}
61
f2b32736
MT
62read_dmi() {
63 local what="${1}"
64
65 # Return an error when what is empty
66 [ -z "${what}" ] && return 2
67
68 local file="/sys/class/dmi/id/${what}"
69
70 # Read file
71 if [ -r "${file}" ]; then
72 printf "%s" "$(<${file})"
73 return 0
74 fi
75
76 # File could not be read
77 return 1
78}
79
96f10173
MT
80board_vendor() {
81 read_dmi "board_vendor"
82}
83
84board_name() {
85 read_dmi "board_name"
f2b32736
MT
86}
87
88board_version() {
89 read_dmi "board_version"
90}
91
92board_serial() {
93 read_dmi "board_serial"
94}
95
96bios_version() {
97 read_dmi "bios_version"
98}
99
100bios_date() {
101 read_dmi "bios_date"
102}
103
96f10173
MT
104do_flashrom() {
105 echo "Flashing process is starting now..."
106 echo "PLEASE DO NOT TURN OFF THE SYSTEM WHILE FLASHING!"
107
108 if ! flashrom "$@"; then
109 echo "Error: Flashing the firmware was not successful" >&2
110 return 1
111 fi
112
113 echo "Flashing was successful! Please reboot."
114 return 0
115}
116
117find_firmware() {
118 local path="${FIRMWARE_DIR}/${1}"
119
120 # Expand globbing
121 local files=( ${path} )
122
123 # Return file with highest order
124 local file="${files[-1]}"
125
126 # Check if we can read the file
127 if [ ! -r "${file}" ]; then
128 echo "Error: Cannot read firmware file: ${file}" >&2
129 return 1
130 fi
131
132 echo "${file}"
133 return 0
134}
135
136# Returns true if a is greater than b
137version_is_gt() {
138 local a="${1}"
139 local b="${2}"
140
141 # Check if a == b
142 [ "${a}" = "${b}" ] && return 1
143
144 # Sort by version
145 local sorted=( $(printf "${a}\n${b}\n" | sort -Vr) )
146
147 # If a comes first in the sorted order, it is largest
148 [ "${a}" = "${sorted[0]}" ] && return 0
149
150 # Otherwise b is greater than a
151 return 1
152}
153
154update_pcengines_apu() {
155 local board="${1}"
156 local running_version="${2}"
157 shift 2
158
159 # Find a new firmware file
160 local firmware="$(find_firmware "pcengines/apu/${board}_*.rom")"
161 if [ -z "${firmware}" ]; then
162 echo "Error: No firmware found" >&2
163 return 1
164 fi
165
166 # Get basename and remove suffix
167 local new_version="$(basename "${firmware%.rom}")"
168 new_version="${new_version#*_}"
169
170 # Check if we actually have a new version
171 if ! version_is_gt "${new_version}" "${running_version}"; then
172 echo "We have ${new_version} and this board is already on ${running_version}"
173 echo "No new firmware available. Aborting."
174 return 1
175 fi
176
06d931fa
MT
177 echo "New firmware version available: ${new_version}"
178
96f10173 179 # Perform update
06d931fa
MT
180 if get_consent "${firmware}"; then
181 do_flashrom -p "internal" -w "${firmware}"
182 fi
96f10173
MT
183}
184
185do_update() {
186 local vendor="$(board_vendor)"
187 local board="$(board_name)"
188 local bios_version="$(bios_version)"
189
190 # Check if we could read the BIOS version
191 if [ -z "${bios_version}" ]; then
192 echo "Error: Could not detect BIOS version" >&2
193 return 1
194 fi
195
196 echo "Detected ${vendor} ${board} running BIOS version ${bios_version}"
197
198 case "${vendor},${board}" in
199 "PC Engines",apu*)
200 update_pcengines_apu "${board}" "${bios_version}" "$@"
201 ;;
202
203 *)
204 echo "Unkown vendor: ${vendor}" >&2
205 echo "Support for this vendor might not have been implement, yet" >&2
206 return 1
207 ;;
208 esac
209}
210
af9ef5f2
MT
211main() {
212 local action="${1}"
213 shift
214
215 case "${action}" in
f2b32736 216 info)
96f10173
MT
217 printf "%-12s: %s %s\n" "Board" \
218 "$(board_vendor)" "$(board_name)"
f2b32736
MT
219 printf "%-12s: %s\n" "HW Version" "$(board_version)"
220 printf "%-12s: %s\n" "Serial" "$(board_serial)"
221 printf "%-12s: %s (%s)\n" "BIOS Version" \
222 "$(bios_version)" "$(bios_date)"
223 return 0
224 ;;
225
96f10173 226 update)
92302596 227 do_update "$@"
96f10173
MT
228 ;;
229
af9ef5f2
MT
230 version)
231 echo "${PACKAGE_NAME}: Version ${PACKAGE_VERSION}"
232 return 0
233 ;;
babb073d
MT
234
235 "")
236 echo "No command given" >&2
237 return 2
238 ;;
239
240 *)
241 echo "Invalid command: ${action}" >&2
242 return 2
243 ;;
af9ef5f2
MT
244 esac
245}
246
247# Call main
babb073d 248main "$@" || exit ${?}