Updating the Firmware of Linux-Based Devices

This tutorial provides a general description of updating Linux-based firmware and illustrates it with some specific implementations. First, consider the sections of the memory system (Figure 1) and parts of memory that should be updated while transferring software to a new version.

Typically, a Linux-based system has the following structure of volatile memory. The first section is filled with a Linux kernel loader, which in turn can be executed in several stages. For example, a small-size bootloader is copied to the CPU internal memory, performs initialization of external memory and copies the second-level loader to the external RAM. The second-level loader (for example, U-Boot) copies the Linux kernel to RAM and hands over control to it. Finally, the system launches custom applications stored in the last section of the Flash memory. So obviously, it's necessary to update the memory sections with user applications and the OS kernel.

Figure 1. Sections of the Flash Memory of a Linux-Based Device

Events for starting the update process include:

  • System launch (in this case, the update application is built in to the bootloader or runs at the OS initialization).
  • Connection of external media (USB or SD card) during the operation.
  • Detection of a newer version of the software on the update server.
  • User operations.

You can copy update files though plug media or receive them over the network (in case the system is fitted with an Ethernet port or a Wi-Fi module). Usually, this procedure uses the TFTP protocol widely supported by various loaders. If you perform the update process using a program in the OS, you can copy the necessary files from the server using the wget application or the libcurl library.

An important part of the update process is checking the version of the received files and their integrity. You can do this using such algorithms as MD5, CRC32 and so forth. I also advise checking the compatibility of the new firmware with the device (PCB revision).

Option 1: if you have ROM capacity sufficient for storing the old and new firmware (Figure 2), the system implements the option with the possibility of going back to the previous version of the software in case of upgrade process failure. Memory is overwritten using flash_eraseall (for erasing the memory) and nandwrite (for writing images to the NAND memory), which are included in the mtd-utils package.

When update files are received and checked, you can start the process of writing them to the system ROM. You can implement various software update options, depending on ROM capacity.

Figure 2. Sections of the Flash Memory of a Device with the Possibility of Restoring the Old Firmware

The next step is to set the U-Boot bootloader environment variables for loading the new firmware. U-Boot environment variables can be read and written from Linux using such commands as fw_printenv and fw_setenv (the source code is included in the U-Boot distribution). In addition to the typical parameters necessary to run the operating system (the location of the kernel image in the ROM, the name of the section containing the root filesystem and so on), environment variables can store the failed boot count and restore the system to the previous software after reaching a certain threshold (Figure 3).

Figure 3. Software Update Algorithm with the Possibility of Restoring to the Previous Firmware

Option 2: for a small ROM capacity, the Linux kernel and applications, as well as the necessary libraries, should be copied to RAM. After that, you can erase and rewrite Flash memory. Obviously, this option does not allow the system to restore to the previous firmware in the event of an update process failure.

The U-Boot loader implements a built-in function of checking the integrity of the loaded Linux kernel image (controlled by the verify variable), which helps check its integrity even before the OS starts and (using hush scripts) identify alternative sources for booting the software (old firmware or TFTP, http://www.denx.de/wiki/DULG/CommandLineParsing).

Let's consider various implementations of a software update mechanism in several open-source projects, such as OpenWrt, Openmoko and OpenInkpot.


In a project for creating free software for OpenWrt network routers, you can update the firmware from various sources, a Web interface or TFTP.

The simplest way is a Web page update. You simply visit a device setup page (Software Update Section) and copy the new software using a special HTML form.

The second way is to update the software through TFTP. This method is well suited for those who have created their own firmware image. If problems arise, you will be able to go back to the old firmware (via TFTP). The procedure is as follows: after the device is turned on, a bootloader is launched, which performs initialization of the system, as well as checks and loads the executable code. If the firmware fails an integrity check, the loader will be considered damaged, and it automatically will go into loader mode until the firmware is loaded over the network. You then can download the new firmware from the PC via TFTP.

You can load the software from the TFTP server manually, if necessary. You need to connect to the CFE (Common Firmware Environment) console through a serial port and interrupt the standard device initialization process. After that, you need to configure the network, copy the new firmware from the TFTP server and write it to the device's Flash memory.


A project for creating free firmware for Openmoko smartphones (http://wiki.openmoko.org/wiki/USB_DFU) is an example of updating the device's software via USB. The update mechanism corresponds to the USB Device Class Specification for Device Firmware Upgrade. The purpose of this specification is to provide a multipurpose mechanism for updating the software of a device fitted with USB--for example, a mechanism independent of the manufacturer and specific hardware platform. This allows you to use a single program in the operating system to install the software on different devices, using appropriate firmware images. In addition to writing the new firmware, the USB Device Class Specification describes the procedure for reading the current firmware on the PC.

Under the Openmoko project, DFU is part of a modified version of the U-Boot bootloader. The project also involves the development of the DFU-Util utility, which helps send and write software to the internal NAND memory of the device and writes the program to its random-access memory. You can use the latter function to debug low-level code (such as kernel code) without rewriting the Flash memory. Moreover, DFU-Util allows reading NAND memory content to help create a firmware backup.


The OpenInkpot project uses an SD memory card to update the software of an e-book. You should download the new software into the SD card root directory as an .oifw file. When power is supplied, the modified U-Boot bootloader checks the firmware on the card and verifies its integrity using CRC32. If an update is possible, you must confirm the operation of overwriting the Flash memory of the device. Then the system updates the kernel and the root filesystem or fully re-installs the software, including the initial bootloader.


As you can see, there are different ways of updating Linux software by fitting your devices with support for multiple update options and choosing the simplest and most reliable one.


--- Software Engineer at Promwad, http://www.promwad.com


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Kernel Problem

Batik's picture

I understand so much about linux os, it's just that it is hard for me matter problem kernel it self, which means there is no understanding to me. Please be explained .. thank you for the information :)

Understanding the Linux Kernel

Viktar Palstsiuk's picture

I would like to recommend the book "Understanding the Linux Kernel" (http://ceata.org/~tct/resurse/utlk.pdf)

Software Engineer at Promwad, http://www.promwad.com

Reply to comment | Linux Journal

continue reading this's picture

Hey there! This is kind of off topic but I need some
advice from an established blog. Is it tough to
set up your own blog? I'm not very techincal but I can figure things out pretty quick. I'm thinking
about making my own but I'm not sure where to start. Do you have any points or suggestions? Thank you

thanks for sharing

mac repairs's picture

Where is the mac address usually located on a desktop motherboard without a parallel port?

Reply to comment | Linux Journal

digital photography basics's picture

Wonderful blog! I found it while surfing around on Yahoo News.

Do you have any tips on how to get listed in Yahoo News? I've been trying for a while but I never seem to get there! Appreciate it

Usually LAN subsystem of ATX

Viktar Palstsiuk's picture

Usually LAN subsystem of ATX motherboard includes configurable EEPROM IC that contains the MAC address.

Software Engineer at Promwad, http://www.promwad.com

Cheap Lululemon

Anonymous's picture

> Typically, a Linux-based

Anonymous's picture

> Typically, a Linux-based system has the following structure of volatile memory.
where it says volatile, I believe should say "non-volatile"

Reply to comment | Linux Journal

hvac repair turlock ca's picture

When winter comes around, they switch onto heating mode.
But even though it's a legitimate worry, it doesn't mean that you should avoid
enlisting pro help. Another advantage of portable air
conditioners is the energy efficiency that they provide.

> Typically, a Linux-based

Viktar Palstsiuk's picture

Thank you for your comment. You are right. I will correct the text.

Software Engineer at Promwad, http://www.promwad.com