]>
Commit | Line | Data |
---|---|---|
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 |
22 | shopt -s nullglob |
23 | ||
af9ef5f2 MT |
24 | PACKAGE_NAME="@PACKAGE_NAME@" |
25 | PACKAGE_VERSION="@PACKAGE_VERSION@" | |
26 | ||
96f10173 MT |
27 | FIRMWARE_DIR="@firmwaredir@" |
28 | ||
f2b32736 MT |
29 | read_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 |
47 | board_vendor() { |
48 | read_dmi "board_vendor" | |
49 | } | |
50 | ||
51 | board_name() { | |
52 | read_dmi "board_name" | |
f2b32736 MT |
53 | } |
54 | ||
55 | board_version() { | |
56 | read_dmi "board_version" | |
57 | } | |
58 | ||
59 | board_serial() { | |
60 | read_dmi "board_serial" | |
61 | } | |
62 | ||
63 | bios_version() { | |
64 | read_dmi "bios_version" | |
65 | } | |
66 | ||
67 | bios_date() { | |
68 | read_dmi "bios_date" | |
69 | } | |
70 | ||
96f10173 MT |
71 | do_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 | ||
84 | find_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 | |
104 | version_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 | ||
121 | update_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 | ||
148 | do_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 |
174 | main() { |
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 | 211 | main "$@" || exit ${?} |