The Boot ROM

The Cisco Boot ROM firmware contains startup diagnostic code (ROM monitor, or ROMmon) as well as the boot loader for the Cisco Internetworking Operating System, or IOS for short.

During early boot, the code in the boot ROM performs a Power-on Self Test (POST) and, if all tests are passed, boot into IOS from the flash.

The Boot ROM CLI

In order to gain access to the monitor in the Boot ROM, send a break sequence to the device early on in the boot process. This can be done with a C-a f (Ctrl+a f) in Minicom, for example.

Recently boot ROMs have had an undocumented priv command. This command then can be used to gain access to several additional commands, including a debugger, disassembler and additional hardware tests. To use this command, a secret password is required, known only to Cisco representatives. However, in recent times this has been cracked and the password for many models of Cisco routers can be calculated using the tool at http://ers.pp.ru/cisco/priv.html.

Environment variables

Boot ROM maintains certain system configuration parameters in environment variables. For example, the $MONRC can contain a starup command sequence, $PS1 contains the command prompt, and so forth. As well, the BootROM supports basic command aliasing. Both the environment variables and the alias table are stored in NVRAM so that their values persist, even when power is off.

The Boot ROM API

The Boot ROM API provides some simple APIs for IOS (for example, putchar and version information commands). Unlike many other firmwares in the world of MIPS, the syscall opcode is used to call these firmware APIs. Note that register a0 must contain the syscall number.

A sample "Hello, world!" program can be found here.

Binary Format

IOS executables are shipped in a raw binary format (known as a .bin file to many). For MIPS-based devices, this is just conventional MIPS Big-Endian ELF, however Cisco does play a dirty trick in using a non-standard e_machine value in the ELF header. This seems to be based on the router model. For example, the Cisco 3600 routers have an e_machine value of 0x1e.

In order to alter the e_machine value, a recent version of objcopy can be used with the switch --alt-machine-code 0x1e (in this example for a Cisco 3600 series machine).

As well, there are limitations placed on the binary format due to the behaviour of the software in the Boot ROM. Boot ROM cannot load multiple ELF program headers. Thus, to work around this problem, toolchains must be built with --target=mips-elf.

Finally, all symbol tables must be removed.

Boot sequence

The Boot ROM can load and execute a block of executable code (such as IOS) from various internal locations: the internal FLASH module(s), a PCMCIA Linear Flash card and (unofficially) TFTP. More recent models also support PCMCIA IDE, CompactFlash and USB flash. Also the Boot ROM supports compressed images (.gz) with embedded helper and text files that contain a command sequence (like a shell script). Nowadays IOS distributions are compressed with ZIP and have a built-in ELF ZIP decompressor "piggybacked" on top, since ZIP provides better compression.

To boot from the PCMCIA ATA or CompactFlash the media should be formatted on the CISCO router with format disk0: command. This command creates a FAT structure with second bootloader (MONLIB) resides in the hidden FAT area. More inforamtion may be found in the ATA Monlib Enhancements article.