Address spaces¶
Short page, and the one most worth reading before you convert an address.
The image loads twice¶
osos-dec.dfu is not loaded at one base. The first 0xB65C bytes stay in the SRAM window at
0x22000000; everything past that runs from DRAM at 0x08000000.
Two conventions are in use, and mixing them makes cross-references vanish:
- project addresses: what Ghidra shows, what the reports quote, what every
FUN_xxxxxxxxis; - runtime addresses: what a trace, a breakpoint or a profile reports.
For the DRAM half:
The SRAM half has its own conversion, and it is not that one¶
The container's 0x800-byte header is not part of the runtime image: the machine loads
file[0x800:] at 0x22000000. So for the first 0xB65C bytes:
Check any batch of SRAM conversions against a known pair before trusting it:
| project | runtime | what it is |
|---|---|---|
0x22000e14 |
0x22000614 |
the service dispatcher |
0x22004324 |
0x22003b24 |
the idle loop's WFI |
The conversion applies only to an address that came from a trace¶
The dump's own headers, the reports, and every FUN_xxxxxxxx are already project addresses, so
adding 0x800 to one of those is the same mistake mirrored.
It applies to an address obtained from a running machine, and to nothing else (branch targets
included). A bl 0x22007bf4 inside a project-addressed listing is a project target; it inherits the
space of the listing it appears in.
Why it is expensive¶
The wrong answer disassembles cleanly. ARM decodes at any aligned offset, so a conversion error hands
back a real function with a plausible body and no error anywhere - a boot profile once blamed a
mov pc, lr CP15 stub for two thirds of a boot, when the samples were at the idle loop's WFI,
0x800 away. A known pair is what catches it.
One more, about the file itself¶
Search osos-dec.dfu, the decrypted image. The encrypted osos.bin is still in the tree, and
every string and constant search against it silently returns nothing, which looks exactly like the
code being absent rather than the file being encrypted.
Also: option filenames in the firmware are stored shifted left by one bit and un-shifted at
runtime, so strings cannot see them.