Note: This article is largely thanks to David Chidell’s post.

I ran into an issue this weekend where my spare APs were on the wrong IOS version and needed to be updated; this quick post goes over how to flash an IOS image onto a Cisco Access Point.

In order to flash an AP, you need a couple of things: a TFTP server, an ethernet connection between the server and the AP to be flashed, and the IOS image to flash with. For TFTP Servers, Tftpd64 for Windows is pretty great and so is TftpServer for macOS. IOS images are distributed as .tar files and can be downloaded from Cisco Support.

Step 0: Booting into ROMMON

The first step towards flashing an AP is to get the device into ROMMON (recovery mode). An easy way to do this is is to boot the AP with the MODE button held down until the status LED turns red. Once booted into ROMMON, the serial window should display a shell prompt like so:

...
Boot into AP recovery mode
button is pressed, wait for button to be released...
button pressed for 21 seconds
process_config_recovery: set IP address and config to default 10.0.0.1
process_config_recovery: image recovery
image_recovery: Download default IOS tar image tftp://255.255.255.255/ap1g1-k9w7-tar.default

examining image...
%Error opening tftp://255.255.255.255/ap1g1-k9w7-tar.default (connection timed out)
ap: 

Step 1: Setup Networking

Now that we can configure the Access Point, we need to enable networking so that it can communicate with the TFTP Server. We can do this by issuing the following commands:

ap: set IP_ADDR 10.0.0.3
ap: set DEFAULT_ROUTER 10.0.0.1
ap: set NETMASK 255.255.255.0
ap: ether_init

The above commands will set the AP’s IP address to 10.0.0.3/24. Even with the ether_init command, and ethernet being configured, the AP will probably not respond to pings at this stage; which is normal. To make this guide easier, we’re going to use the following network setup:

Device Address
Server 10.0.0.2
AP 10.0.0.3
Switch 10.0.0.4

Optional Step: Formatting flash:

If you’re starting from scratch with a deployment, you can easily wipe the flash: contents with the following command:

ap: format flash:
Are you sure you want to format "flash:" (all data will be lost) (y/n)?y
mifs[0]: 0 files, 1 directories
mifs[0]: Total bytes     :  131334144
mifs[0]: Bytes used      :       4096
mifs[0]: Bytes available :  131330048
mifs[0]: mifs fsck took 0 seconds.
Filesystem "flash:" formatted

This is unnecessary if you’re just updating the device as it will result in current configuration being destroyed. If you’re just updating the device, you may need to clear space in flash: by deleting old images before beginning the upgrade process.

If you’re having issues with modifying flash, you may need to run flash_init before any format operations or deletions.

Step 2: Install the Image

After networking is setup and the TFTP Server is running, it’s time to actually install the images. In order to install an image on IOS, we only need to extract the .tar file into flash:. To do this, run the below command to install the ap1g1-k9w7-tar.153-3.JBB4.tar image:

ap: tar -xtract tftp://10.0.0.2/ap1g1-k9w7-tar.153-3.JBB4.tar flash:
extracting info (285 bytes)
ap1g1-k9w7-mx.153-3.JBB4/ (directory) 0 (bytes)
ap1g1-k9w7-mx.153-3.JBB4/html/ (directory) 0 (bytes)
ap1g1-k9w7-mx.153-3.JBB4/html/level/ (directory) 0 (bytes)
ap1g1-k9w7-mx.153-3.JBB4/html/level/1/ (directory) 0 (bytes)
extracting ap1g1-k9w7-mx.153-3.JBB4/html/level/1/appsui.js (563 bytes)
...

Note: You’re probably not installing the ap1g1-k9w7-tar.153-3.JBB4.tar image, so you should update the command accordingly

Once the tar process completes, you should now be able to boot into the new image. If you formatted flash, then booting is as simple as running:

ap: boot

If you upgraded the image, you need to specify which image to boot:

ap: boot flash:ap1g1-k9w7-mx.153-3.JBB4/ap1g1-k9w7-mx.153-3.JBB4

If everything goes well, you should boot into the new image. If you upgraded to a new image, and you have multiple images installed, then a reload will cause the AP to no longer boot to the new image. You can fix this by setting the boot image with the below command:

ap# config t
ap(config)# boot system flash:ap1g1-k9w7-mx.153-3.JBB4/ap1g1-k9w7-mx.153-3.JBB4
ap(config)# end
ap# write