I got a pair of Cisco AIR-LAP1142N-E-K9 access points for free. They are 802.11n access points, so not up to modern speeds, but good enough for Internet of Shit devices. These are enterprise access points that are meant to be deployed in large numbers all across the premises of organizations. As such, they are not meant to be configured individually, nor do they have an interface for that. Their standard mode of operation is that a controller appliance on the wired network manages these devices. For home use that is absolute overkill. However, there is something called “Autonomous Mode”, which allows the AP to be configured individually. This requires flashing a different firmware onto the device. As a helpful post on Cisco’s community knowledge base details, we’re interested in flashing a k9w7 image onto the access point, replacing the k9w8 “lightweight” firmware that is on there.

Scouring the net, I quickly found a post on Reddit, which lays out most of the process. However, diverging from that post, I transferred the image via the serial console instead of via TFTP.

Prerequisites:

  • serial adapter
  • Cisco console cable (serial plug on one end, network plug on the other)
  • a k9w7 firmware image for our model of access point

The last point is a bit trickier than it might seem at first glance, since the device in question has been out of support since 2018. This means that Cisco no longer has the firmware files for download on their website. As far as I can tell, the last firmware release for this device was called c1140-k9w7-tar.153-3.JD17.tar. Feeding that into a search machine of your choice should yield a few helpful results among a larger number of … not so helpful ones.

Equipped with the correct image, all that is needed is screen and sx from the lrszs tool set.

Connect the serial cable to the powered off access point and start the serial console with 9600 baud: screen /dev/<your serial TTY> 9600. Once you connect the switch to a power source (PoE switch, PoE injector or barrel plug), messages should start appearing in the serial console:

using  eeprom values

WRDTR,CLKTR: 0x84000800 0x40000000
RQDC ,RFDC : 0x80000039 0x00000211

ddr init done

IOS Bootloader - Starting system.
Xmodem file system is available.

DDR values used from system serial eeprom.
WRDTR,CLKTR: 0x84000800, 0x40000000
RQDC, RFDC : 0x80000039, 0x00000211

PCIE0: link is up.
PCIE0: VC0 is active
PCIE1: link is up.
PCIE1: VC0 is active
PCIEx: initialization done
flashfs[0]: 49 files, 14 directories
flashfs[0]: 0 orphaned files, 0 orphaned directories
flashfs[0]: Total bytes: 32385024
flashfs[0]: Bytes used: 12531200
flashfs[0]: Bytes available: 19853824
flashfs[0]: flashfs fsck took 21 seconds.
Reading cookie from system serial eeprom...Done
Base Ethernet MAC address: c4:7d:4f:3b:26:75
Waiting for PHY auto negotiation to complete TIMEOUT !
 done
Ethernet speed is 10 Mb - HALF duplex

The system has encountered an error initializing
the Ethernet port.
The system is ignoring the error and continuing to boot.
If you abort the system boot process, the following
commands will re-initialize Ethernet, TFTP, and finish
loading the operating system software:


    ether_init
    tftp_init
    boot

The next line should be that the AP starts loading the firmware from flash, indicated by # symbols crawling across the screen. Hit Esc while it is doing that. And again a few seconds later, when the message Interrupt within 5 seconds to abort boot process. appears:

Loading "flash:/c1140-k9w8-mx.124-23c.JA10/c1140-k9w8-mx.124-23c.JA10"...###############################bad mzip file, unknown zip method

Error loading "flash:/c1140-k9w8-mx.124-23c.JA10/c1140-k9w8-mx.124-23c.JA10"

Interrupt within 5 seconds to abort boot process.
Boot process terminated.

The system is unable to boot automatically.  The BOOT
environment variable needs to be set to a bootable
image.

C1140 Boot Loader (C1140-BOOT-M) Version 12.4(18a)JA3, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Compiled Wed 14-Oct-09 18:59 by prod_rel_team

ap: 

Now we have a prompt. Let’s look at the current state of the flash memory (might look different for you, depending on what firmware is installed)

ap: dir flash:
Directory of flash:/

2    -rwx  271       <date>               env_vars
3    -rwx  88321     <date>               event.log
4    -rwx  0         <date>               config.txt
5    drwx  128       <date>               c1140-rcvk9w8-mx
36   drwx  384       <date>               c1140-k9w8-mx.124-23c.JA7
8    -rwx  6168      <date>               private-multiple-fs
10   drwx  384       <date>               c1140-k9w8-mx.124-23c.JA10

19853824 bytes available (12531200 bytes used)

Okay, now that we know what’s there, let’s get rid of it:

ap: format flash:
Are you sure you want to format "flash:" (all data will be lost) (y/n)?y

It will then proceed without any indication of accepting the command or progress, but after a few minutes you get a summary and a prompt again

flashfs[0]: 0 files, 1 directories
flashfs[0]: 0 orphaned files, 0 orphaned directories
flashfs[0]: Total bytes: 32385024
flashfs[0]: Bytes used: 1024
flashfs[0]: Bytes available: 32384000
flashfs[0]: flashfs fsck took 17 seconds.
Filesystem "flash:" formatted

ap: 

Now it is time to upload the firmware that we want on there. To make the process less slow, let’s increase the baud rate of the console

ap: set BAUD 115200

and change your terminal’s baud rate to match by pressing CTRL+a, then : and enter exec ! stty 115200. To check if it worked enter help. You should get a list of commands from the AP.

Now, with the upped baud rate we upload the new image

ap: copy xmodem: flash:c1140-k9w7-tar.153-3.JD17.tar
Begin the Xmodem or Xmodem-1K transfer now...
CGive your local XMODEM receive command now.

Again CTRL+a, then : and exec !! sx /path/to/wherever/you/saved/c1140-k9w7-tar.153-3.JD17.tar. Note the two exclamation marks. These configure how the new process (sx in this case) gets to interact with the existing processes (screen and stty). Here they make sure both stdin and stdout of sx are connected to the serial connection, allowing those two processes to send data and acknowledge correct receival.

This should start the file transfer. After 15 to 20 minutes, it should be complete. This is where the TFTP route would have been faster. But given that I don’t casually have a TFTP server ready to go and only got two access points to reflash, it probably would have taken me longer to muck around and get a TFTP server up and running.

Anyway, once the firmware is uploaded, we need to extract it:

ap: tar -xtract flash:c1140-k9w7-tar.153-3.JD17.tar flash:

This again takes a little while (around five minutes). Once done, we tell the AP to boot from the image we just extracted:

ap: set BOOT flash:c1140-k9w7-mx.153-3.JD17/c1140-k9w7-mx.153-3.JD17

When booting, the AP will revert back to the default baud rate, so we might as well do that beforehand and set our terminal to match, so that our console doesn’t get garbled in the middle of booting.

ap: set BAUD 9600

as well as CTRL+a, : and exec ! stty 9600.

And then we boot

ap: boot
Loading "flash:c1140-k9w7-mx.153-3.JD17/c1140-k9w7-mx.153-3.JD17"...############

File "flash:c1140-k9w7-mx.153-3.JD17/c1140-k9w7-mx.153-3.JD17" uncompressed and installed, entry point: 0x4000
executing...
enet halted

Secondary Bootloader - Starting system.
FLASH CHIP:  Numonyx P33
Checking for Over Erased blocks
......................................................................................................................................................................................................................................................
Xmodem file system is available.
flashfs[0]: 203 files, 7 directories
flashfs[0]: 0 orphaned files, 0 orphaned directories
flashfs[0]: Total bytes: 32385024
flashfs[0]: Bytes used: 19130880
flashfs[0]: Bytes available: 13254144
flashfs[0]: flashfs fsck took 6 seconds.
Reading cookie from system serial eeprom...Done
Base Ethernet MAC address: c4:7d:4f:3b:26:75

Secondary bootloader Ethernet not enabled, skip ether_init
Boot CMD: 'boot  flash:c1140-k9w7-mx.153-3.JD17/c1140-k9w7-xx.153-3.JD17;flash:/c1140-k9w7-mx.153-3.JD17/c1140-k9w7-xx.153-3.JD17'
Loading "flash:c1140-k9w7-mx.153-3.JD17/c1140-k9w7-xx.153-3.JD17"...####################################
File "flash:c1140-k9w7-mx.153-3.JD17/c1140-k9w7-xx.153-3.JD17" uncompressed and installed, entry point: 0x4000
executing...

[...]

Once it’s booted, Press RETURN to get started! will be written to the terminal, followed by the occasional status message.

[...]
Top Revision Number                  : A0
Product/Model Number                 : AIR-LAP1142N-E-K9



Press RETURN to get started!


*Mar  1 00:00:12.704: %SOAP_FIPS-2-SELF_TEST_IOS_SUCCESS: IOS crypto FIPS self test passed (15)
*Mar  1 00:00:12.706: *** CRASH_LOG = YES

*Mar  1 00:00:15.141: %SOAP_FIPS-2-SELF_TEST_RAD_SUCCESS: RADIO crypto FIPS self test passed on interface Dot11Radio 0 (4)
*Mar  1 00:00:15.317: loading Power Tables from flash:c1140-k9w7-mx.153-3.JD17/T2.bin. Class = E
*Mar  1 00:00:15.317:  record size of 2ss: 404 read_ptr: 2303430
[...]

Following the invitation we press Return and get a prompt. We enter privileged mode (where you can change the configuration of the AP) with the command enable and the default password “Cisco”. I then changed the AP name from the default ap to something more distinguishable and made that change persistent with copy running-config startup-config (otherwise it would revert on the next reboot):

ap#configure
ap(config)#hostname ciscoap1
ciscoap1(config)#
*Mar  1 01:37:17.863: %DOT11-5-EXPECTED_RADIO_RESET: Restarting Radio interface Dot11Radio0 due to hostname change
*Mar  1 01:37:17.863: %DOT11-5-EXPECTED_RADIO_RESET: Restarting Radio interface Dot11Radio1 due to hostname change
ciscoap1(config)#^Z
ciscoap1#
*Mar  1 01:37:53.435: %SYS-5-CONFIG_I: Configured from console by console
ciscoap1#copy running-config startup-config
Destination filename [startup-config]?
Building configuration...
[OK]
ciscoap1#

At this point I connected the AP to my home network, where my router took care of the rest, allowing me to just open my browser and enter ciscoap1 (the name I gave it) in the address bar and do the rest of the configuration there.

This is where I end this tutorial. I have only one bit of information left to convey: Broadcasting the SSID is called “guest mode” in Cisco speak. No idea why, but that confused me more than it should have. So there you go, I hope I saved you some time and pain.