This instructions covers how to connect via openocd
on linux platform. And assuming you have the STLINKv2 hardware dongle. And that you have wired it up correctly, to the aixun t3a's debugging port.
NOTE:
- Case 1) The swd debugging port should normally only be connected up between your PC and the soldering station. When the target device (the aixun t3a) is fully powered off, and it's mains cable unplugged from the outlet. To avoid having dual powering (both connected), or to avoid grounding / reference issues.
- Case 2) However for live debugging scenarios, or working on firmwares etc. Then you typically would instead disconnect the
+3v3
power pin from the SWD port on the STLINKv2. And just tie the GNDs together. To keep the ground reference only. Then have the target DUT (the mcu in the aixun) being powered independantly by itself. Just being aware that this is more risky or delicate situation than when passively powering from the STLINKv2 in the safer offline fashion, with the t3a powered off, all excpt it's mcu. - However whether or not passively powering the target mcu from the PC (case 1, passive powering the target mcu alone), or having the aixun instead actively switched on and fully powering itself with
+3v3
swd port pin disconnected (case 2, live debugging), the below steps all remains the same:
As of 11-Oct-2022, there is a bug in openocd. It causes segfault when trying to connect to these GD32 mcus over libusb >= v1.0.24
. However a fix for that bug has already been committed into git master branch of openocd. As was first found here, and here and then finally here.
However in future versions of openocd, then that bug fix will have been included. Then it will no longer be necessary to compile from git anymore. Just depends whether or not you are seeing openocd
program segfaulting (or not!) when it's connecting. Anyhow in the meantime... here's how to compile from git:
mkdir ~/.builds/embedded
cd ~/.builds/embedded
git clone https://github.com/openocd-org/openocd.git
cd openocd
./bootstrap
./configure
make
If build was successful, then:
openocd
executable binary should appear located at./src/openocd
./tcl
folder containingscripts
andtargets
various config files etc.
Assuming you are in the openocd git repo downloaded folder (in above example was ~/.builds/embedded/openocd
). And assuming the build was successful then:
# navigate into scripts / config files subtree. (or use `-s` flag to specify directory path)
cd ./tcl
# run git master compiled openocd binary, and override the cpu_id for these GD32 clone chip (exact chip on the aixun t3a was GD32F303RCT6, with 512kb flash)
# use debug flag `-d4` to help debug any issues...
../src/openocd -d4 -f interface/stlink.cfg -c "set CPUTAPID 0x2ba01477" -f target/stm32f1x.cfg -c "init; reset halt"
if successful connection, then run the same cmdline again but without the -d4
debug flah. And command log output should say waiting for connections:
../src/openocd -f interface/stlink.cfg -c "set CPUTAPID 0x2ba01477" -f target/stm32f1x.cfg -c "init; reset halt"
Open On-Chip Debugger 0.12.0-rc1+dev-00943-gdc6cad855 (2022-10-11-21:37)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
0x2ba01477
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 1000 kHz
Info : STLINK V2J29S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.154375
Info : [stm32f1x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections
[stm32f1x.cpu] halted due to breakpoint, current mode: Thread
xPSR: 0x01000000 pc: 0x08000148 msp: 0x200013b8
[stm32f1x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000148 msp: 0x200013b8
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
At this point, you need to leave the openocd program running in the background. Leave the 1st terminal open and running. Then open up a 2nd new terminal, to connect to the openocd server (over telnet protocol typically, otherwise gdb dor debugging)
# Connect to openocd over telnet, for issuing manual commands
telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
>
Now it's possible to query help and run commands, for example:
# Query help for managing the target device's flash memory
flash help
# Get an overview of the flash banks
flash list
# Get a memory map layout for flash bank 0
flash info 0
# Read flash bank 0, and dump it all into a file on your PC
flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.512k.dump.bin
It is recommend to dump the full 512kb flash area. And then manually check on which half of the address range is actually written the firmware code.
Explanation:
The cpu id of 0x2ba01477
does seem to match the chip label markings GD32F303RCT6
. The flash memory size in the specs is listed as being 256kb
in those published product marketing materials. However openocd
program is having trouble to successfully detect and identify the flash size. Perhaps because it's a clone STM32 device, which is slightly different.
> flash list
{name stm32f1x.flash driver stm32f1x base 134217728 size 0 bus_width 0 chip_width 0 target stm32f1x.cpu}
> flash info 0
device id = 0x21040414
STM32 flash size failed, probe inaccurate - assuming 512k flash
flash size = 512 KiB
#0 : stm32f1x at 0x08000000, size 0x00080000, buswidth 0, chipwidth 0
# 0: 0x00000000 (0x1000 4kB) not protected
# 1: 0x00001000 (0x1000 4kB) not protected
The default flash dump command with no extra arguments (as above, in previous section). Will dump the entire 512kb
readable address area. Which is common to all such family of similar devices (which shares this same similar silicon die). They are just branded and afterwards selected or binned to be different part numbers. Depending on either quality checks or product segmentation etc.
Therefore this model (id) of chip is only officially certified to be tested (and assured as fully working) for a smaller 256kb
flash area within this total full 512kb
flash are of these same silicon die. The remainder of the rest of the full extended 512kb
flash are might be good or bad (it is not known). And might vary from sample to sample. Depending on the quality and nature of those product binning process (again not known).
It is recommend to dump the full 512kb flash area. And then manually check on which half of the address range is actually written the firmware code.
When the full accessible 512kb
are of the whole flash area was dumped. We checked the contents of the whole 512kb
area. And found that:
-
Only the 1st half, up to
256kb
addressable area contained any real data or program code for these aizun t3a device. -
This is seen in the hex editor as the hex range from
0000:0000
to0003:FFFF
-
The 2nd half remainder was all
0xFF
left unused. -
This is seen in the hex editor as the hex range from
0004:0000
to0007:FFFF
That all agrees with the official spec of the device (being only a 256kb
flash). However if might be the case that other individual chip samples have in fact a bad flash in the first half of the region instead. Then in that case the program code should be moved over to the 2nd region / offset to become the "good area".
Just we did not observe this in this device here. And it is also it's possible that a fully matured silicon fab process will end up having 0 flash errors. That would be the case if the chips are being artificially binned down. To meed market segmentation / product differentiation criteria. Depending on that fact we recommend to read the full 512kb
flash area. And then manually double check which half has the firmware code.
Openocd command to read the 1st half (256kb
) region of flash only:
flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.first.256k.dump.bin 0 262144
Openocd command to read the 2nd half (256kb
) region of flash only:
flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.last.256k.dump.bin 262144 262144
Openocd command to read the entire flash region fully. Just remove last 2 arguments for bytes offset and bytes length:
flash read_bank 0 aixun-t3a.firmware-v1.26.openocd.flash.bank0.last.256k.dump.bin
- For GDB server, that isn't covered here. But normally is setup in vscode IDE, under PlatformIO extension project environment. So then requires some custom target configruations within vscode / platformio such as
platformio.ini
file. etc. Then to run the vscode IDE integrated debugger. - Another method of program static analysis is to use a decompiler / dissassembler such as Ghidra.
- Binwalk did not seem work here. But is another popular method for examining firmware binaries.
- Other tutorial for STM32 firmware https://medium.com/techmaker/reverse-engineering-stm32-firmware-578d53e79b3