User Tools

Site Tools


Upgrading OpenWrt firmware via LuCI and CLI

An OpenWrt upgrade will replace the entire current OpenWrt installation with a new version. This includes the Linux kernel, the SquashFS partition and the JFFS2 partition.

The common upgrade paths below will automatically preserve much of the OpenWrt OS configuration by saving and then restoring configuration files in specific common locations (including /etc/config). This will preserve things like OpenWrt network settings, WiFi settings, the device hostname, and so on.

The first part of the upgrade process is to prepare for the upgrade. This includes documenting programs and settings that will need to be re-installed or restored after the upgrade, locating and downloading the correct OpenWrt upgrade image for your hardware.

Next is the actual upgrade. There are two common upgrade paths to actually perform the upgrade. One uses the LuCI web interface “Flash new firmware image” command and one uses the command-line sysupgrade command. You can use either approach.

After the OS upgrade, there are usually some additional configuration steps required to re-install additional packages not part of the base OpenWrt install, to configure new OpenWrt functionality or to update configuration files to reflect new settings or updated packages. Please see the section below with more details.

Preparing for an OpenWrt upgrade

How the OpenWrt OS upgrade works

Both the LuCI and sysupgrade upgrade procedures work by saving specified configuration files, wiping the entire file system, installing the new version of OpenWrt and then restoring back the saved configuration files. This means that any parts of the file system that are not specifically saved will be lost.

In particular, any manually installed software packages you may have installed after the initial OpenWrt installation have to be reinstalled after an OpenWrt upgrade. That way everything will match, e.g. the updated Linux kernel and any installed kernel modules.

Any configuration files or data files placed in locations not specifically listed as being preserved below will also be lost in an OpenWrt upgrade. Be sure to check any files you have added or customized from a default OpenWrt install to back up these items before an upgrade.

See this howto about extroot procedure.

Identifying customizations

List user-installed packages identified in the opkg package database

From ''master'' in Early 2019

sysupgrade has been enhanced on the master branch to be able to capture a list of installed packages. These enhancements are not present in 18.06.02, but may be included in v19, when it is available. When available, the -k option will save a list. The relevant code is, as of February 1st, 2019:

# Format: pkg-name<TAB>{rom,overlay,unkown}
# rom is used for pkgs in /rom, even if updated later
find /usr/lib/opkg/info -name "*.control" \( \
        \( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
        \( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
        \( -exec echo {} unknown \; \) \
        \) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}

Either INSTALLED_PACKAGES must be defined, or the output can sent to the terminal by removing > ${INSTALLED_PACKAGES} or, for example, filtered for “overlay” (user-installed) by replacing > ${INSTALLED_PACKAGES} with | fgrep overlay

Other options

This script is from forum member gsenna and was originally posted in the forum discussion “Default packages attitude 12.09rc2 tplink 1043nd” at

# Save the script
cat << "EOF" > /tmp/
echo >&2 User-installed packages are the following:
sed -ne '/^Package:[[:blank:]]*/ {
/user installed/ {
}' /usr/lib/opkg/status
# Run the script
sh /tmp/

Note that the script may list several packages that are part of the default OpenWrt install and will have their changed configuration files automatically backed up and restored. In addition, packages installed as dependences of other packages may show here. It is only important to note the names of packages that you directly installed manually. Any dependencies of these packages will automatically be reinstalled when the primary package is reinstalled.

An alternative script, that uses awk instead of sed/grep and is much shorter (provided by user valentijn):

# Save the script
cat << "EOF" > /tmp/listuserpackages.awk
/^Package:/{PKG= $2}
/^Status: .*user installed/{print PKG}
# Run the script
awk -f /tmp/listuserpackages.awk /usr/lib/opkg/status

This script will only output a list of user (and default) installed packages.

List all packages associated with any user-modified file

This is an alternative to the script above. This command will list all packages related to any file in the whole file system that has changed from the default OpenWrt default version.

Note that the script may list several packages that are part of the default OpenWrt install and will have their changed configuration files automatically backed up and restored. In addition, packages installed as dependences of other packages may show here. It is only important to note the names of packages that you directly installed manually. Any dependencies of these packages will automatically be reinstalled when the primary package is reinstalled.

# OpenWrt 14.07 "Barrier Breaker" or earlier
find /overlay/ | while read FILE; do opkg search "${FILE#/overlay}"; done | sed -e "s/\s.*//" | sort -u
# OpenWrt 15.05 or later
find /overlay/upper/ | while read FILE; do opkg search "${FILE#/overlay/upper}"; done | sed -e "s/\s.*//" | sort -u

Configure your backup

Follow: Backup and restore

Based on the list of user-installed packages customize your backup configuration to save the files not included in the default list. Verify your backup configuration and ensure that all OpenWrt configurations and user data are going to be preserved.

Legacy: LuCI flash_keep section of /etc/config/luci

LuCI has a separate set of settings for configuration files to be preserved, however it appears to be obsolete since OpenWrt 14.07 and should be ignored.

uci show luci.flash_keep

Identifying the OpenWrt upgrade image

  • Only the “…-sysupgrade.bin” version of the OpenWrt download image should be used for OpenWrt upgrades. The “…-factory.bin” file is for switching from the vendor-default firmware to OpenWrt and is not used for OpenWrt-to-OpenWrt upgrades.
  • Locate the correct “…-sysupgrade.bin” upgrade file for your particular device hardware in the OpenWrt download area

OpenWrt on x86

:!: For x86 systems there is no “sysupgrade” image, just be sure to use the new firmware image has the same family of filesystem (if the current firmware uses squashfs then the new will use squashfs as well and if the current has ext the new will use ext filesystem. Note that an upgrade from ext2 [10.03.1] to ext4 [12.09] seems not working. Tested 10.03.1 squashfs to 12.09 squashfs, working ; 10.03.1 squashfs to 12.09 ext4 failed; 10.03.1 ext2 to 12.09 ext4 failed)

Downloading the OpenWrt upgrade image

For LuCI-based upgrades

  • Download the desired upgrade file to your PC using a web browser
  • Proceed to the LuCI upgrade procedure, below

For sysupgrade-based upgrades

  • Download the desired upgrade file to the local /tmp RAM drive on your OpenWrt system. The /tmp directory is stored in RAM (using tmpfs), not in the permanent flash storage.
# example downloading the OpenWrt 15.05 upgrade image for a TP-LINK TL-WR1043ND ver. 1.x router
cd /tmp
# check the integrity of the image file
# via md5sums
# via sha256sums
# the desired result is that the downloaded firmware filename is listed with "OK" afterwards
# via md5sums
md5sum -c md5sums 2> /dev/null | grep OK
# via sha256sums
sha256sum -c sha256sums 2> /dev/null | grep OK
  • Proceed to the “Ensure desired configuration files will be saved” section, above
Troubleshooting: /tmp is too small to hold the downloaded file

If your device's /tmp filesystem is not large enough to store the OpenWrt upgrade image, this section provides tips to temporarily free up RAM.

First check memory usage with the free or top or cat /proc/meminfo commands; proceed if you have as much free RAM as the image is in size plus an some additional MiB of free memory.

root@openwrt:/$ free total used free shared buffers Mem: 29540 18124 11416 0 1248 -/+ buffers: 16876 12664 Swap: 0 0 0

In this example there are precisely 11416 KiB of RAM unused. All the rest 32768 - 11416 = 21352 KiB are used somehow and a portion of it can and will be made available by the kernel, if it be needed, the problem is, we do not know how much exactly that is. Make sure enough is available. Free space in /tmp also counts towards free memory. Therefore with:

root@openwrt:/$ free Mem: 13388 12636 752 0 1292 Swap: 0 0 0 Total: 13388 12636 752
root@openwrt:/$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 2304 2304 0 100% /rom tmpfs 6696 60 6636 1% /tmp tmpfs 512 0 512 0% /dev /dev/mtdblock3 576 288 288 50% /overlay mini_fo:/overlay 2304 2304 0 100% /

One has actually 752+6636 KiB of free memory available.

  • quickest and safest way to free up, some RAM is to delete the opkg packages file:
rm -r /tmp/opkg-lists/
  • drop caches:
sync && echo 3 > /proc/sys/vm/drop_caches
  • prevent wireless drivers to be loaded at next boot and then reboot:
rm /etc/modules.d/*80211*
rm /etc/modules.d/*ath9k*
rm /etc/modules.d/b43*

The wireless drivers, usually take up quite some amount of RAM and are not required (unless you are connected via wireless of course ;-)), so an easy way to free up some RAM is to delete the symlinks in etc/modules.d so these are not loaded into memory at the next reboot.

OpenWrt Upgrade procedure

Web interface

  1. Navigate to LuCI → System → Backup / Flash Firmware → Actions: Flash new firmware image.
  2. Click Choose File button to select firmware image.
  3. Click Flash image… to upload firmware image.
  4. Verify firmware image checksum and proceed.
  5. Wait until the router comes back online.

Command-line interface

OpenWrt provides sysupgrade utility for firmware upgrade procedure.

Verify firmware image checksum. Verify the router has enough free RAM. Upload the firmware from local PC. Flash the firmware.

# Check the free RAM 
# Upload firmware
scp firmware_image.bin root@openwrt.lan:/tmp
# Flash firmware
sysupgrade -v /tmp/firmware_image.bin

If sysupgrade is not available.

# Flash firmware
mtd -r write /tmp/firmware_image.bin firmware

If free RAM is limited.

# Upload and flash firmware
cat firmware_image.bin | ssh root@openwrt.lan mtd write - firmware
  • The sysupgrade verbose-option should give some output similar to this. The list of configuration files saved will change depending on what packages you have installed and which files you have configured to be saved, as per above.
Saving config files...
killall: watchdog: no process killed
Sending TERM to remaining processes ... ubusd askfirst logd logread netifd odhcpd snmpd uhttpd ntpd dnsmasq
Sending KILL to remaining processes ... askfirst
Switching to ramdisk...
Performing system upgrade...
Unlocking firmware ...

Writing from <stdin> to firmware ...  [w]
Appending jffs2 data from /tmp/sysupgrade.tgz to firmware...TRX header not found
Error fixing up TRX header
Upgrade completed
Rebooting system...

Note: The “TRX header not found” and “Error fixing up TRX header” errors are not a problem as per OpenWrt developer jow's post at

  • Wait until the router comes back online
  • After the automatic reboot, the system should come up the same configuration settings as before: the same network IP addresses, same SSH password, etc.
  • Proceed to the “Additional configuration after an OpenWrt upgrade” section, below


  • In case it does not, try a cold reset (= interrupt the electrical current to the device, wait a couple of seconds and then connect it again).
For unknown reasons such a cold reset has often been reported to be necessary after a sysupgrade. This is very very bad in case you performed this remotely!


Verify the new OS version

  • In LuCI, go to Status > Overview to verify you are running the new OpenWrt release
  • In SSH, the login banner has the release information

Check for any upgradable packages

Blindly upgrading packages (manually or via script) can lead you into all sorts of trouble.
Inform yourself before doing any upgrades, if it is safe to upgrade. Avoid upgrading core packages, build a new image instead.

If you do chose to upgrade packages, especially with a script: You have been warned. Don't complain on the forum and be ready to deal with the consequences yourself, such as manual dependency resolution and additional free space consumption, potentially leading to ABI-conflicts and soft-bricking.

See upgrade_packages for more information.

After the initial update, it is good to check for any updated packages released after the base OS firmware image was built.

  • List any available upgradable packages
opkg update
opkg list-upgradable
  • Upgrade any packages listed (if any were listed) – more than one package can be included
    • Note: on a device with only 4MB of NVRAM, these updates may not fit – check free space on / first with “df -h /” and ensure there is at least 600KB or so free
opkg list-upgradable | sed -e "s/\s.*//" | while read PKG_NAME; do opkg upgrade "${PKG_NAME}"; done
  • Verify no more packages can be upgraded; the command should display no output now
opkg list-upgradable

Reinstall user-installed packages

After a successful upgrade, you will need to reinstall all previously installed packages. You made a list of these above. Package configuration files should have been preserved due to steps above, but not the actual packages themselves.

  • For example:
opkg update
opkg install snmpd-static

Configure user-installed packages

The new package installations will have installed new, default versions of package configuration files. As your existing configuration files were already in place, opkg would have displayed a warning about this and saved the new configuration file versions under …-opkg filenames.

The new package-provided configuration files should be compared with your older customized files to merge in any new options or changes of syntax in these files.

The diffutils program is helpful for this.

For example:

# install diffutils
opkg install diffutils
# locate all -opkg files
find /etc -name *-opkg
# compare old customized /etc/config/snmpd with new generic file /etc/config/snmpd-opkg
diff /etc/config/snmpd /etc/config/snmpd-opkg
# merge in any needed changes to the active version of the configuration file
vi /etc/config/snmpd
# and clean up by removing the package manager-version of the configuration file
rm /etc/config/snmpd-opkg
# or if the new version provided by the package maintainer should just replace the old config file then just swap it in
mv /etc/config/snmpd-opkg /etc/config/snmpd
# Apply new configuration
service snmpd restart
docs/guide-user/installation/generic.sysupgrade.txt · Last modified: 2019/04/07 02:07 by vgaetera