]> git.ipfire.org Git - people/ms/firmware-update.git/blame - src/firmware-update.in
Implement BIOS update for PC Engines APU
[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
f2b32736
MT
29read_dmi() {
30 local what="${1}"
31
32 # Return an error when what is empty
33 [ -z "${what}" ] && return 2
34
35 local file="/sys/class/dmi/id/${what}"
36
37 # Read file
38 if [ -r "${file}" ]; then
39 printf "%s" "$(<${file})"
40 return 0
41 fi
42
43 # File could not be read
44 return 1
45}
46
96f10173
MT
47board_vendor() {
48 read_dmi "board_vendor"
49}
50
51board_name() {
52 read_dmi "board_name"
f2b32736
MT
53}
54
55board_version() {
56 read_dmi "board_version"
57}
58
59board_serial() {
60 read_dmi "board_serial"
61}
62
63bios_version() {
64 read_dmi "bios_version"
65}
66
67bios_date() {
68 read_dmi "bios_date"
69}
70
96f10173
MT
71do_flashrom() {
72 echo "Flashing process is starting now..."
73 echo "PLEASE DO NOT TURN OFF THE SYSTEM WHILE FLASHING!"
74
75 if ! flashrom "$@"; then
76 echo "Error: Flashing the firmware was not successful" >&2
77 return 1
78 fi
79
80 echo "Flashing was successful! Please reboot."
81 return 0
82}
83
84find_firmware() {
85 local path="${FIRMWARE_DIR}/${1}"
86
87 # Expand globbing
88 local files=( ${path} )
89
90 # Return file with highest order
91 local file="${files[-1]}"
92
93 # Check if we can read the file
94 if [ ! -r "${file}" ]; then
95 echo "Error: Cannot read firmware file: ${file}" >&2
96 return 1
97 fi
98
99 echo "${file}"
100 return 0
101}
102
103# Returns true if a is greater than b
104version_is_gt() {
105 local a="${1}"
106 local b="${2}"
107
108 # Check if a == b
109 [ "${a}" = "${b}" ] && return 1
110
111 # Sort by version
112 local sorted=( $(printf "${a}\n${b}\n" | sort -Vr) )
113
114 # If a comes first in the sorted order, it is largest
115 [ "${a}" = "${sorted[0]}" ] && return 0
116
117 # Otherwise b is greater than a
118 return 1
119}
120
121update_pcengines_apu() {
122 local board="${1}"
123 local running_version="${2}"
124 shift 2
125
126 # Find a new firmware file
127 local firmware="$(find_firmware "pcengines/apu/${board}_*.rom")"
128 if [ -z "${firmware}" ]; then
129 echo "Error: No firmware found" >&2
130 return 1
131 fi
132
133 # Get basename and remove suffix
134 local new_version="$(basename "${firmware%.rom}")"
135 new_version="${new_version#*_}"
136
137 # Check if we actually have a new version
138 if ! version_is_gt "${new_version}" "${running_version}"; then
139 echo "We have ${new_version} and this board is already on ${running_version}"
140 echo "No new firmware available. Aborting."
141 return 1
142 fi
143
144 # Perform update
145 do_flashrom -p "internal" -w "${firmware}"
146}
147
148do_update() {
149 local vendor="$(board_vendor)"
150 local board="$(board_name)"
151 local bios_version="$(bios_version)"
152
153 # Check if we could read the BIOS version
154 if [ -z "${bios_version}" ]; then
155 echo "Error: Could not detect BIOS version" >&2
156 return 1
157 fi
158
159 echo "Detected ${vendor} ${board} running BIOS version ${bios_version}"
160
161 case "${vendor},${board}" in
162 "PC Engines",apu*)
163 update_pcengines_apu "${board}" "${bios_version}" "$@"
164 ;;
165
166 *)
167 echo "Unkown vendor: ${vendor}" >&2
168 echo "Support for this vendor might not have been implement, yet" >&2
169 return 1
170 ;;
171 esac
172}
173
af9ef5f2
MT
174main() {
175 local action="${1}"
176 shift
177
178 case "${action}" in
f2b32736 179 info)
96f10173
MT
180 printf "%-12s: %s %s\n" "Board" \
181 "$(board_vendor)" "$(board_name)"
f2b32736
MT
182 printf "%-12s: %s\n" "HW Version" "$(board_version)"
183 printf "%-12s: %s\n" "Serial" "$(board_serial)"
184 printf "%-12s: %s (%s)\n" "BIOS Version" \
185 "$(bios_version)" "$(bios_date)"
186 return 0
187 ;;
188
96f10173
MT
189 update)
190 do_update
191 ;;
192
af9ef5f2
MT
193 version)
194 echo "${PACKAGE_NAME}: Version ${PACKAGE_VERSION}"
195 return 0
196 ;;
babb073d
MT
197
198 "")
199 echo "No command given" >&2
200 return 2
201 ;;
202
203 *)
204 echo "Invalid command: ${action}" >&2
205 return 2
206 ;;
af9ef5f2
MT
207 esac
208}
209
210# Call main
babb073d 211main "$@" || exit ${?}