You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
5.2 KiB
57 lines
5.2 KiB
\subsection{The update mechanism}
|
|
|
|
The update mechanism is split into four main phases: checking for updates, reprogramming the device, calculating and verifying the cryptographic signature of the updated firmware, and - assuming that the update was successful - reconfiguring the boot process to use the new firmware.
|
|
|
|
\subsubsection{Checking for updates}
|
|
In order to inform the IoT devices of the availability of a new firmware version, the update server provides a file for each device type containing meta-information about the latest available firmware version.
|
|
The meta-information file has a simple line oriented ASCII format, which is easy to generate and efficient to parse within the limited constraints of the embedded device.
|
|
It consists of the version identifier and the cryptographic signatures of both of the firmware binaries.
|
|
The version identifier can be an arbitrary string as the content is not interpreted semantically but only compared to the version identifier used during build time.
|
|
The other two lines in the meta-information file provide the hexadecimal representation of the cryptographic signatures, one line for each firmware binary file.
|
|
These meta-information files are provided by the update server using \textit{HTTP 1.1} \cite{HTTP_1.1} under the following path pattern: \texttt{\$\{DEVICE\}.version} (whereas \texttt{\$\{DEVICE\}} gets replaced by the device type name).
|
|
Each device queries the update server regularly for the currently available firmware version.
|
|
It uses the \texttt{UPDATER\_URL} option to identify the update server.
|
|
After the meta-information file has been downloaded successfully, the version identifier is extracted and compared to the version identifier of the running firmware.
|
|
If the version identifiers differ, the update process is initialized.
|
|
In cases where the download fails, the update server or network connection is not available, or any other error occurres, another attempt will be made automatically at the next regular interval.
|
|
In addition to the interval, a special \textit{MQTT} topic shared by all devices is subscribed on device startup: \texttt{\$\{MQTT\_REALM\}/update}.
|
|
Every time a message is received on this topic, a fetch attempt for the meta-information file is triggered and the process restarts.
|
|
This allows faster roll-outs of updates and finer control for manual maintenance.
|
|
|
|
\subsubsection{Reprogramming the device}
|
|
The firmware files provided on the update server are the exact same ones as used to initially flash the chip for the according version.
|
|
Using the same files for flashing and updating allows better debugging by eliminating errors related to the update process itself and eases development and initial installation.
|
|
Figure~\ref{lst:choosing_rom} shows the algorithm used to determine the download address and reconfigure the bootloader.
|
|
The update server provides these files in the exact same way as it provides the meta-information files, but the path pattern differs: the suffixes \texttt{.rom\{0,1\}} are used to provide the firmware image files for the first and second slot respectively.
|
|
For installing a firmware update, the new firmware image file is downloaded using an \textit{HTTP 1.1} \texttt{GET} request.
|
|
|
|
\begin{figure}[htbp]
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
#define URL_ROM(slot) (( URL "/" DEVICE ".rom" slot ))
|
|
|
|
// Select rom slot to flash
|
|
const auto& bootconf = rboot_get_config();
|
|
if (bootconf.current_rom == 0) {
|
|
updater.addItem(bootconf.roms[1], URL_ROM("1"));
|
|
updater.switchToRom(1);
|
|
} else {
|
|
updater.addItem(bootconf.roms[0], URL_ROM("0"));
|
|
updater.switchToRom(0);
|
|
}
|
|
\end{lstlisting}
|
|
\caption{Configuring the updater to download the right firmware image and update the booloader accordingly.}
|
|
\label{lst:choosing_rom}
|
|
\end{figure}
|
|
|
|
\subsubsection{Verifying the cryptographic signature}
|
|
While the image is being downloaded, each chunk received in the download stream is used to update the \textit{SHA256} hash before it is written to the flash.
|
|
When the write has been finished, the next chunk is received and the process continues until all chunks have been processed.
|
|
After downloading the new firmware image has been finished successfully, the calculated hash is checked against the signature of the according firmware image.
|
|
Therefore, the cryptographically signed hash, which was provided in the meta-information file triggering the update, is verified against the \textit{Curve25519} public key stored as a constant in the running firmware.
|
|
Only if the checksum matches the provided signature, the firmware is considered valid and the process is continued.
|
|
|
|
\subsubsection{Reconfiguring the boot process}
|
|
For the bootloader, \textit{rBoot}\cite{rBoot} has been choosen as it is integrated within the \textit{Sming} framework and allows to boot to multiple ROM slots.
|
|
For configuration, an \textit{rBoot} specific structure is placed in the flash at a well-known location directly after the space reserved for the bootloader code.
|
|
This structure contains, among other things, the target offsets for all known ROM slots and the number of the ROM slot to boot on next startup.
|
|
To switch to the updated ROM slot after successful installation, the number ROM slot to boot on startup is changed in the configuration section and the device is restarted.
|