Kernel and partitions¶
The layer between the metal and the application: U-Boot, the VxWorks kernel, the
address map, and the flash filesystems the unit mounts. This is mostly read from
bousqi/SMEG_PLUS — which reverse-engineered the
upgrade.out updater and the vxWorks.bin image — cross-checked against what this project
has measured directly, and noted where it has not. See Sources and prior art.
Two different base addresses
Addresses here are load addresses in the PowerPC address space, not NAND byte
offsets. The updater's flasher.inf uses flash offsets like 0x720000 for vxWorks.bin
(see Boot and update chain); the kernel then runs at 0x00200000. Do
not mix the two.
Boot¶
Two stages, both in NAND outside any filesystem:
- U-Boot — the first-stage loader, flashed by the updater's
ManageUBootUpdateAndReboot()and reported in System Information asUBoot version(ours shows06.03 Apr 22 2013). Its variables and the FlashFX/TFFS geometry are not documented by this project. - VxWorks 6.7 — the RTOS proper, the image shipped as
BSP/SMEG_PLUS_<256|512>/vxWorks.bin.
The kernel identifies itself on the console as:
VxWorks (for Freescale MPC5121E ADS (Rev 0.1)) version 6.7.
Kernel: WIND version 2.12.
Made on May 26 2017, 13:23:36.
Boot line:
usb(0,0)host:vxWorks h=192.168.10.2 e=192.168.10.1 u=5121 pw=5121 f=0x0 tn=DB600
(read, bousqi/SMEG_PLUS.) The usb(0,0)host:… boot line is the interesting part: the
kernel's default boot device is USB, over a host/network device, which is consistent
with the USB device classes below. The u=/pw= are a built-in login, not a credential of
yours, and h=192.168.10.2 e=192.168.10.1 is a hard-coded link-local pair.
Address map¶
| address | what |
|---|---|
0x00010000 |
space reserved for loading ELF files |
0x00200000 |
vxWorks.bin — the kernel (image base) |
0x01000000 |
f_BigQuick.bin's inflated application image |
0x04c00000 |
the browser / "Post" image, a separate loadable process |
(read.) The first two are bousqi's; the application and browser bases are this project's
own (see Architecture). The application and the kernel share one address
space — that is what makes a branch from a patch into a kernel function possible at all,
which patches/diagnostic-logsink.json relies on.
The kernel's own symbol table¶
vxWorks.bin is not an ELF, but it carries a VxWorks symbol table, so kernel functions can
be named even without a linked map. The entries are 20 bytes:
struct s_Symbol {
int unk1;
void *name; /* pointer into the image's string area */
void *address;
int unk2;
int type; /* 0x100 unk, 0x400 func, 0x800 data, 0x1000 ext */
};
The table lives near the end of the image — at 0x00822024 on the analyser's unit, holding
13 853 symbols (read, bousqi/SMEG_PLUS). Read at the 0x00200000 base the name pointers
resolve, which is how this project confirmed the base independently: the application's own
IsAUXSRCAvailable() failure path calls 0x0058c248, and the table names that address
tickGet (see Boot and update chain).
Other structures bousqi located in the image, useful starting points for anyone reading the kernel (read; addresses are per build, do not assume they match another unit):
vxSymTbl 0x00822024 the symbol table above
opcodeTbl 0x007a2bf8
registerTbl 0x007a3540
wifiRegionTbl 0x0081CD6C
partTbl 0x00741250
fpRegs 0x007A2524
fpCtrlRegs 0x007A262C
taskRegs 0x007A263C
Not the same vxWorks as the WRS public one
This is a Wind River-built VxWorks 6.7 for a specific Freescale reference board
(MPC5121E ADS). It is not a generic desktop VxWorks, and the symbol table is the only
map of it this project knows of. tools/elfsyms.py cannot read it — it is not ELF.
Flash partitions¶
The kernel mounts a FlashFX/TrueFFS flash translation layer as a set of named volumes. The layout, as seen from a rooted shell (read, bousqi/SMEG_PLUS — tree dumps in that repo):
| TFFS type | device | on | holds |
|---|---|---|---|
| 7 | /romfs |
internal NAND | debug binaries for audio and scheduler.bin |
| 3 | /ram |
RAM | config files; not readable over telnet |
| 3 | /sdhc:0 |
internal microSD | cartography, cheat-code libraries, TTS |
| 3 | /sdhc:1 |
internal microSD | user guide |
| 3 | /bd0 |
USB mass storage | the stick; this is where SMEG_PLUS_UPG/ lives |
| 3 | /SYSTEM |
internal NAND | the media partition, extracted read-only |
| 3 | /SYSTEM_DATA |
internal NAND | the system_data.bin payload |
| 3 | /SYSTEM_TMP_DATA |
internal NAND | transient update state (e.g. StartUsb.txt) |
| 3 | /USER_DATA |
internal NAND | live user state the car owns — settings, phones, destinations |
| 3 | /USER_DATA_BACKUP |
internal NAND | the backup copy the updater keeps |
| 3 | /EXTENDED_PARTITION |
— | present in the partition table; contents not documented here |
The ones that matter to patching are /SYSTEM (read-only, so edits to the seed do not
reach live state — see What is reachable) and /USER_DATA (the live copy
the car owns; overwriting it is destructive and not recoverable by reflashing). Which of
these are NAND-backed versus a card is a distinction the updater's phases act on directly
(see Boot and update chain).
USB device classes¶
The kernel's USB stack is not a general one. What it supports, as strings in vxWorks.bin
(read, bousqi/SMEG_PLUS):
- CDC-EEM (Ethernet Emulation Model) and CDC-ACM — the serial/network gadget classes.
This is why the boot line is
usb(0,0)host:…and why the community "psakey" USB-key work is a thing at all. - Mass storage, including several volumes on one device — this is the path the updater
uses for
SMEG_PLUS_UPG/. - USB-to-Ethernet adapters (ADM8511/8513/8515, DM9601 families, and the ASIX/davicom clones listed in the kernel) and a few USB 3G modems.
- Not RNDIS, ECM or NCM.
So a host PC cannot simply pretend to be an arbitrary USB device to the unit — it has to present one of the supported classes. See the usb-intruderer notes in Sources and prior art for the prior work of that kind.
The VxWorks shell¶
The kernel runs a shell on its serial console (and the CDC-EEM path), where the commands are direct symbol lookups, not a fixed command table — which means every public function in the image is callable by name. Names this project has used or seen used (read):
d <addr>— dump memory as words with an ASCII gutter. Comparing a dump with the file at the same offset is how the load base was confirmed.lkup "<name>"— list symbols matching a name, with their address and type (text/data). Redundant forvxWorks.bin, which embeds its own symbols.regsShow,memShow,ti/task,devs,iosDrvShow,ifconfig,route,ping.
Reaching that shell needs physical access (UART) or a supported USB gadget; it is not a remote path and is out of scope here. It is mentioned because it is how several of the kernel facts above were established, not as a recommended workflow.
Open questions¶
- U-Boot: version, variable set, and how its NAND region is laid out. The updater's
ManageUBootUpdateAndReboot()is named but its internals have not been read. - What lives in
/EXTENDED_PARTITION. - Whether the TFFS partition table (
partTbl) is fixed or shifted between 256 MB and 512 MB boards. - The VxWorks
r2(TOC) value. bousqi could not pin it down (0x007A5F80lands in a compressed picture); the sharedEABITOC is a candidate but was not confirmed. This matters only for someone doing full-kernel decompilation, not for application patching.