If you have only the ASW from a Bosch MG1 (AURIX TC298) — no SSW, no boot, no initial state for the A0/A1/A8/A9 SDA base registers — base+offset loads will not resolve to absolute RAM addresses on the first Ghidra pass. The vector table that exists in the file covers part of the calibration area but leaves the rest unaddressed. The working approach on this platform: split the calibration into two blocks and address each one with its own method. The structure of the vector table itself then gives you the offset gap.
This is the text summary. Members at our 19 May 2026 Open Q&A saw Thomas Pirowski walk through the full method live. Reverse-engineering tracks on EDC17, MG1, MED17, and Ghidra are covered in Ghidra Fundamental →. Register free for our next Open Q&A → — live with Thomas, agenda forming.
The question — from Q&A live 2026-05-19
Richard asked (Part 1 of a 3-part question):
“When disassembling a Bosch MG1 (AURIX TC298) read that contains only the ASW — no SSW/boot, so A0/A1 and the per-function A8/A9/A15 base registers are never initialized in the dump — how do you recover those base/SDA register values so base+offset loads/stores resolve to absolute RAM addresses, and how do you apply that in Ghidra?”
The expectation behind the question is that there is one register set the file should reveal. In MG1 the calibration is not laid out that way. Here is the method Thomas walked through at the Q&A.
Why the vector table doesn’t cover everything
The Bosch MG1 is a hybrid platform. Some of the calibration area is structured the way Bosch ECUs traditionally are. Other maps inside the same file follow the Siemens approach — and these are not reached by the Bosch-style vector table.
“If we do not have, let’s say, perfect readout — we will have only a table of vectors which covers some of the maps which are the heritage of the Bosch solution. But some maps which are located in a Bosch ECU but they are the heritage of the Siemens solution — they won’t be covered. So then it will be difficult.” (~15:39–16:11)
That is the working assumption to start from on MG1: the vector table is real, but partial.
Split the calibration into two blocks
The method is to divide the project into two pieces and resolve each one with a different reference scheme.
“You need to just divide the project into two parts. The calibration area should be divided into two parts: one to be addressed directly without using A9, and the second to be addressed by the vector table which exists but won’t cover all the maps.” (~16:11–16:31)
- Block 1 — direct addressing, no A9. The maps the vector table does not cover. This block is addressed directly, without using A9.
- Block 2 — vector-table addressed. The maps the table does cover; A9 is the crucial reference for this block.
Find the boundary of Block 2 — first and last vector
The easiest way to locate where Block 2 starts and ends is to walk the vector table itself.
“Just the easiest way is just to find the first vector and the last vector which is in a vector table — you will find one and then isolate the area of the maps which is covered by the vector. And then separate them as two separated blocks. And then reference their A9 especially — because this is the crucial reference A9 for that second block. And then directly address the first one.” (~16:31–17:00)
The first and last vector entries define the start and end of the Block 2 address range inside the file. Maps outside that range belong to Block 1 — the directly-addressed block where A9 does not apply.
Use the vector table to recover the address offset
Even inside Block 2, one step remains. In most cases — in most flashers — there is a gap between where the maps physically live in the file and where the vector table says they should live.
“There is an offset between the calibration and the location of the calibration in most cases — in most flashers. So you should also try to find — usually — finding the difference between the actual position of the maps and the values of the vector table, especially front and back of the vector table, will give you a chance to understand if the difference, the gap, is like 0x20000, 0x40000 or 0x60000. So you should just rebuild the sizes or just separate it again into separated blocks with proper distances in between.” (~17:01–17:50)
The recovery sequence:
- Pick a map entry from the front of the vector table. Note the address the vector points to.
- Compare to where that same map is actually located inside the dump.
- The difference is the offset — typically a round hex value:
0x20000,0x40000, or0x60000. - Repeat the check at the back of the vector table — front and back together give you the gap.
- Rebuild the sizes, or separate the file again into blocks with the proper distances in between. After that, the vector-table addresses land on the actual map positions.
When AURIX initializes some registers
On the newest Siemens-side AURIX builds, parts of the A-register set arrive pre-initialized in the file.
“In some cases, even with AURIX, if you just check the newest Siemens for example, you will find that A0 and A1 are set, A8 also is set — so it is not a coverage for all the maps in the system from that set, but it is enough to cover that first block where you have the maps not covered by the vector table.” (~17:51–18:25)
If you see A0, A1, A8 already populated in the dump, that population covers Block 1 (the directly-addressed, non-A9 part). It is not enough on its own to resolve every map in the file, but it removes the need to reconstruct A0/A1/A8 from scratch. A9 still remains the reference to resolve for Block 2.
Summary — the working method on MG1 ASW-only
- Accept the file is two blocks, not one. The vector table only covers part of the calibration.
- Find the first and last vector entries. They define the Block 2 boundary.
- Outside that boundary is Block 1 — address it directly, no A9 dependency.
- Inside that boundary is Block 2 — A9 is the crucial reference for it.
- Recover the offset (
0x20000/0x40000/0x60000) by comparing vector entries to actual map positions at the front and back of the table. - If A0, A1, or A8 are pre-set in the file (newer Siemens AURIX), use them for Block 1 — they cover the directly-addressed part, not the vector-covered part.
The MG1 is one of the platforms covered in the Ghidra tracks. The Fundamental course unpacks the TriCore/AURIX register conventions, the vector-table mechanics, and the Bosch-versus-Siemens heritage split on hybrid ECUs. That sits one level above the file-by-file workflow shown here.
Working an MG1 ASW-only dump right now? Post the offset you found between your vector entries and the actual map positions — 0x20000, 0x40000, 0x60000, or something else — and which flasher produced the file.