PostHeaderIcon Extract NXP Microprocessor LPC2134FBD64 Firmware: The Interrupt Map Is the Product

Extraction is often quoted as if the deliverable were a file. Customers who have received a file and nothing else tend to come back with a second, harder question: what does it do.

The answer is in the image, and on this family there is a particular structure that makes it easy to read. The interrupt controller is not a simple priority encoder. It is a vectored unit with sixteen slots, each holding the address of a handler, and the firmware populates those slots at start-up. Enumerating them produces an outline of the product in about twenty minutes.

How the controller is organised

The unit sits at a fixed address above the peripheral space and presents a small register file: an interrupt selector, an enable register, a set of sixteen vector address registers, a default vector address, and a register that reports which handler is currently being serviced.

The mechanism is straightforward. A peripheral raises a request; the controller picks the highest-priority enabled source; it reads the address from the corresponding slot and jumps there. The handler does its work, writes to the read-back register to signal completion, and returns. If no slot is programmed, the default handler runs, which on most firmware is a loop that logs and resets.

Two properties of that design are useful during analysis:

  • every handler has an entry in the slot table, so the table is a complete list of what the firmware responds to
  • the slot table is written once, early, from constants, so it survives in the image as a small block of addresses

Reading the table

The initialisation sequence writes a constant to each slot it cares about. In a disassembly those writes appear as a run of address constants loaded into a register and stored to consecutive addresses. Extracting them gives a list of handler entry points, and the index in the list is the source number.

The indices are the interesting part. A product that programs slots for the UART, the timer and one external interrupt is a product that does three things. A product that programs eleven slots is doing something much more elaborate, and the extra entries usually describe which peripherals matter — the ADC, the PWM block, the watchdog, the real-time clock, the two serial ports.

Observation What it tells you about the product
few slots programmed simple control loop, polling used elsewhere
all sixteen used dense event-driven design, likely a protocol gateway
default handler never reached careful design, or a product that never debugged an unhandled source
a slot pointing at a shared dispatcher software multiplexing above the vector unit
FIQ used at all a hard real-time path exists, and it will be short

The fast interrupt is its own story

The fast interrupt input bypasses the vector unit entirely. It has one address, no priority, and it runs in a mode with its own registers. Firmware uses it for exactly one purpose: a task that cannot tolerate the latency of the vectored path.

When the recovered image programs the fast interrupt vector to something other than a stub, that one fact reorders the priorities of the whole investigation. It means the product has a timing requirement strict enough to justify the complexity, and the handler is where the reason will be found — a shaft encoder, a current loop, a bit-banged protocol, or a watchdog refresh that must not be delayed.

Turning the map into a document

Once the handlers are located, each one can be characterised by what it touches. A handler that reads a data register and writes it to a buffer is a receive path. One that loads a compare register from a table is a waveform generator. One that increments a counter and compares it against a constant is a scheduler tick.

That characterisation, assembled across the sixteen slots, is a description of the product’s real-time structure, and it is the part of the deliverable a customer can check against their own knowledge. Names are lost, but function is not.

Where the map comes from in the data

Two places in a stripped image carry the same information, and either can be used when the other is missing.

The initialisation code writes the slot table, which gives the intended mapping. The handlers themselves end with a write to the read-back register, which confirms the mapping from the other side: a routine that writes the completion register is a handler, regardless of where the table says it belongs.

Cross-checking the two catches the case where a handler was replaced at run time — a diagnostic mode, a firmware update path, a safety fallback. Those replacements are real behaviour and are worth reporting separately.

Why this matters commercially

A customer who needs to maintain an orphaned product does not need the source. They need to know which interrupts exist, what each one does, and how the work is scheduled. That is a maintenance document, and it can be produced from a locked device the moment the array is readable.

The same method applies upward and downward in the family. LPC2114FBD64 code reading covers the instruction-level side, including the constant pools where peripheral addresses hide, and LPC2131FBD64 heximal work shows what the same structure looks like when the budget was too tight for sixteen handlers. On a Cortex-M part the same analysis is easier because the vector table is in memory rather than in a peripheral — see STM32F103CB recovery for the contrast.

A short procedure

Read the image, find the peripheral block containing the controller, locate the initialisation writes, extract sixteen addresses, and disassemble from each. Expect an hour for the first pass and a day for the characterisation, and expect the resulting document to answer questions that the customer did not know how to ask.

That document, not the binary, is what makes the extraction worth commissioning.

Comments are closed.