I started to approach this from the other direction, by doing some bottom up reverse engineering of the OS.
We already know that SparrowAPP.out is a statically linked ELF binary containing the field upgradeable 'application' part of the scope firmware. While it is only part of the complete system, it provides some insight into how the whole system is built. Memory segments are from the ELF file:
$ readelf -S SparrowApp.out
There are 12 section headers, starting at offset 0x3c1eec:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 3c1e40 000000 10 0 0 4
[ 1] .shstrtab STRTAB 00000000 3c1e40 000069 00 0 0 4
[ 2] A1 rw PROGBITS 00000000 000034 000040 01 AX 0 0 4
[ 3] Absolute sections NOBITS 00007ff4 000074 000004 01 WA 0 0 1
[ 4] Absolute sections NOBITS 00007ffc 000074 000004 01 WA 0 0 1
[ 5] P2 zi NOBITS 00010000 000074 0004c4 01 WA 0 0 4
[ 6] P3 zi NOBITS 00018000 000074 0011a0 01 WA 0 0 4
[ 7] P4 rw PROGBITS 40000000 000074 3c1dcc 01 AX 0 0 16
[ 8] P5 ui NOBITS 40600000 3c1e40 001900 01 A 0 0 32
[ 9] P6 rw NOBITS 40601900 3c1e40 2b9444 01 WA 0 0 32
[10] P9 zb NOBITS 40b00000 3c1e40 200000 01 WA 0 0 32
[11] P8 ui NOBITS 43ee0000 3c1e40 020000 01 A 0 0 8
(Physical RAM starts at 0x40000000)
At power up the i.MX283's ARM core (ARM926EJ-S, ISA is arm5TE) enters into the bootloader, SparrowBoot.sb, which is loaded into RAM at 0x41000000 (it's about 0x50000 long depending on version). During normal boot, the bootloader opens the NAND flash device as a UFFS filesystem, loads logo.hex and displays it. It then loads /sys/SparrowAPP.out into RAM and passes control to its entry point in segment 7 (P4 rw): 0x40293738 (according to readelf -h). The bootloader remains in RAM, but is not referenced again, so one can copy it from a RAM dump using:
$ dd if=ramdump.bin of=bootloader.bin bs=1 skip=16777216 count=327680
SparrowBoot.sb is a self-contained MQX 3.7.0 instance which contains UFFS and MFS (the native MQX FAT32 library) plus USB host support.
SparrowAPP.out is a separate MQX 3.7.0 instance which contains UFFS, MFS, RTCS (TCP/IP stack), USB host and device stack, TFS (Trivial filesystem, a RAM disk essentially), the GUI toolkit (not identified yet, possibly homegrown). libpng, zlib etc. plus the rest of the scope application code.
SparrowAPP.out was compiled using the IAR ARM compiler (one can tell from the segment names) and so is probably linked against IAR's DLIB and runtime libraries. MQX 3.7.0 does not natively support i.MX parts, so the Board Support Package (BSP) and Processor Support Package (PSP) are, most likely, provided by Embedded Access Inc:
http://embedded-access.com/products/mqx-rtos/However, if one hunts around the NXP site, it is possible to download the MQX 3.7.0 source code (which is fairly ancient) and compile it for the nearest supported ARM part, which turns out to be a Freescale Kinetis K60 (ARM Cortex M4 core). Compiled with symbols and debug info, this can be used to identify large amounts of OS code, with a high degree of confidence. Cortex M4 is thumb only (16-bit) while SparrowAPP.out is mostly/solely arm (32-bit), so the usual signature based analysis tools wouldn't be of any help - I had to do it by hand, which was time consuming, but educational and quite good fun.
I would estimate that I've identified 75-80% of the OS code, as follows:
UFFS (100%)
TFS (100%)
MFS (95+%)
RTCS (90+%)
USB (host 90+%, device ~75%)
BSP (<10%)
PSP (<10%)
MQX (80+%*)
* Difficult to estimate, as it depends on build configuration.
I also found the MQX 3.7.0 source here (not official, but convenient to browse):
https://github.com/gxliu/MQX-3.7.0UFFS source is available here:
https://sourceforge.net/projects/uffs/I identified the version as 1.3.6 (the latest version), using typos and ideosynchrocies in the strings.
TFS is used to serve web content out of RAM, from the built in httpd, which is provided with RTCS. There are also strings for a 'GoAhead' Web server, which I haven't investigated yet. Similarly libpng and zlib are easy to find, but not terribly interesting or helpful.
So, what is the point of this?
Say for example, one is interested in examining how the SCPI service on tcp/5555 works. It is now a fairly easy task to search for function calls to RTCS_socket, choose one with the number 0x15b3 (5555) nearby, then follow the function calls down to the handler routine. The API details for how sockets work in RTCS are well documented. Obviously one can learn a lot about interfacing with the scope hardware from this point.
Knowing more about the filesystem is interesting, particularly calls to uffs_open(), I believe the missing MIRACL crypto API stuff is probably in one of the files in the internal flash, and most likely it is loaded and unloaded on demand. We really need to dump the flash to find out...
I've been working on firmware version 04.03.02.03, as that was current when I started. It doesn't look like anything much changed with later firmware revisions, as far as the OS is concerned. Similarly, the differences between the MQX parts of the earliest bootloader (from the .GEL) and recent ones are minimal, as far as I can tell.
I have to figure out how to share what I've done so far. As it currently stands the data is in a format which is very specific to my workflow. It would be nice to create a symbol table which could be linked back into the existing ELF file, then the free/demo version of IDA could read it directly.
I also want to investigate the DLIB, DLPP, RT and M libraries supplied with IAR. I believe it should be possible to identify any linked functions using signature techniques, but it is not as straight forward as I first assumed. It would be great to identify all the string functions in particular.