Unbricking PM3 Easy
I got a Proxmark3 Easy recently.

The firt thing I did when I got it was to flash the latest firmware on it. So I went on the Iceman repository, cloned it, skimmed throught the doc, checked that ModemManager was not installed on my laptop, built the firmware, flashed it, got a warning telling me to update the bootloader, flashed the bootloader, bricked the card.
Yep, the card stopped appearing in /dev/tty* (it previously appeared as /dev/ttyACM0). JTAG time!
What happened?
I’m not sure what happened, but I believe that the problem was that I compiled the firwmare for the wrong platform. This forum post explains that firmware for the Proxmark3 Easy must be compiled for the platform PM3GENERIC and not the default PM3RDV4.
Any wait, I started by fixing that.
Compiling the firwmare, the right way
Let restart from the begining:
git clone https://github.com/RfidResearchGroup/proxmark3.git
cd proxmark3
And this time, before compiling the firmware, I selected the right platform:
cp Makefile.platform.sample Makefile.platform
In Makefile.platform, I commented the line PLATFORM=PM3RDV4 (-> #PLATFORM=PM3RDV4), and uncommented the line #PLATFORM=PM3GENERIC (-> PLATFORM=PM3GENERIC).
And then I compiled it:
make clean
make -j
JTAG
Now that I had the right firmware, I needed to flash it on the proxmark. The documentation was clear about it: the only way to flash a bricked card is to resort to the heavy artillery and use a JTAG probe.
First reaction: PANIC, I don’t have a JTAG probe.
Second reaction: How, but I have a raspberry pi!
So, good news, a raspberry pi can be used as a JTAG probe using openocd, and all the configuration to do so is already in the Iceman repository for raspberry pi 1 to 3 (I didn’t try it, but it looks like the raspberry pi 4 require a different configuration that is not provided). This forum post describes the procedure pretty well.
The wires
On to the next problem: my female/male wires are slightly too thick for the JTAG ports on the proxmark (I believe normal male jumper wire would work, I just have weird wires). However I had this nice phone wires that are juste the right size. Even better, there is just the right number of wire in sheath.

Unfortunately, my raspberry has mal connectors, not really compatible with bare wires. Fortunately, I had some DuPont headers waiting to be used. Soldering time!

Look at my new homemade messy JTAG cable:

The Raspberry
Now, let’s take a look at the raspberry pi. I used a raspberry pi 3 (because this forum post says that the raspberry pi 4 needs a different configuration not provided by the repository). I used the last raspberry pi OS (bullseye) 64bit without issue. I installed on it openocd and cloned the Iceman repository to get the openocd config files.
sudo apt update
sudo apt upgrade
sudo apt install openocd
git clone https://github.com/RfidResearchGroup/proxmark3.git
In the openocd folder, the raspberry pi config must be selected:
cd proxmark3/tools/jtag_openocd/
cp openocd_configuration.sample openocd_configuration
in openocd_configuration, I commented the line CONFIG_IF=interface/jlink.cfg (-> #CONFIG_IF=interface/jlink.cfg), and uncommented the line #CONFIG_IF=interface-raspberrypi2.cfg (-> CONFIG_IF=interface-raspberrypi2.cfg)
Last thing is to put the firmware image on the raspberry pi (I didn’t compile it on the raspberry pi, the poor thing did not support the workload for some reason):
scp recovery/proxmark3_recovery.bin histausse@raspberrypi:~/proxmark3/recovery/
Wirering
The wirering to use is described in the proxmark3/tools/jtag_openocd/interface-raspberrypi2.cfg file. The location of the pins can be found here.
I my case, the mapping was:
TMS-> pin 22TDI-> pin 19TDO-> pin 21TCK-> pin 23GND-> pin 63.3-> pin 1

On the proxmark, I just put the wires in the holes, bended them and put some tape to make sur the wires don’t touch each other.

A bit hacky, but it worked well enough.
The JTAG connection can power the proxmark, but the raspberry pi and the proxmark may lake some power and may glitch, soo it’s better to power both the raspberry and the proxmark.
Shorting pin 54 and 55
The forum post warmed about a protection against JTAG that using JTAG out of the box. But I’m currious, so I tried any way:
histausse@raspberrypi:~/proxmark3/tools/jtag_openocd $ ./openocd_flash_recovery.sh
Open On-Chip Debugger 0.11.0-rc2
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_gates_jtag srst_push_pull connect_deassert_srst
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
Warn : Transport "jtag" was already selected
DEPRECATED! use 'adapter speed' not 'adapter_khz'
adapter speed: 1000 kHz
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : clock speed 1001 kHz
Info : JTAG tap: sam7x.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787 (<unknown>), part: 0xf0f0, ver: 0x3)
Info : TAP auto0.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto1.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto2.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto3.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto4.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto5.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto6.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto7.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto8.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto9.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto10.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto11.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto12.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto13.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto14.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto15.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto16.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto17.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto18.tap does not have valid IDCODE (idcode=0x0)
Info : TAP auto19.tap does not have valid IDCODE (idcode=0x0)
Warn : Unexpected idcode after end of chain: 52 0x00000000
Warn : Unexpected idcode after end of chain: 84 0x00000000
Warn : Unexpected idcode after end of chain: 116 0x00000000
Warn : Unexpected idcode after end of chain: 148 0x00000000
Warn : Unexpected idcode after end of chain: 180 0x00000000
Warn : Unexpected idcode after end of chain: 212 0x00000000
Warn : Unexpected idcode after end of chain: 244 0x00000000
Warn : Unexpected idcode after end of chain: 276 0x00000000
Warn : Unexpected idcode after end of chain: 308 0x00000000
Warn : Unexpected idcode after end of chain: 340 0x00000000
Warn : Unexpected idcode after end of chain: 372 0x00000000
Warn : Unexpected idcode after end of chain: 404 0x00000000
Warn : Unexpected idcode after end of chain: 436 0x00000000
Warn : Unexpected idcode after end of chain: 468 0x00000000
Warn : Unexpected idcode after end of chain: 500 0x00000000
Warn : Unexpected idcode after end of chain: 532 0x00000000
Warn : Unexpected idcode after end of chain: 564 0x00000000
Warn : Unexpected idcode after end of chain: 596 0x00000000
Warn : Unexpected idcode after end of chain: 628 0x00000000
Error: double-check your JTAG setup (interface, speed, ...)
Error: Trying to use configured scan chain anyway...
Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -irlen 2 -expected-id 0x00000000"
Error: auto0.tap: IR capture error; saw 0x0000 not 0x0001
Warn : Bypassing JTAG setup events due to errors
Info : Embedded ICE version 0
Error: unknown EmbeddedICE version (comms ctrl: 0x00000000)
Info : sam7x.cpu: hardware has 2 breakpoint/watchpoint units
Info : starting gdb server for sam7x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : Halt timed out, wake up GDB.
Error: timed out while waiting for target halted
Warn : Flash driver of sam7x.flash.0 does not support free_driver_priv()
Warn : Flash driver of sam7x.flash.1 does not support free_driver_priv()
Well, nop, didn’t work. No choices, we need to short the pins 54 and 55 of the controller. First we need to remove the shield from the main bord of the proxmark, then use some piece of wire to short the pins.
Here is a picture from DonFire (author of the forum post I followed) that show the operation. The closest pin to 3.3V JTAG port is the pin 49, the closest to the TMS JTAG port is the pin 64. Carefull not to short wire radom pins…

Once this operation is done, no need to do it again, JTAG is enable on the card for live.
Flashing
Running proxmark3/tools/jtag_openocd/openocd_flash_recovery.sh again, and this time:
histausse@raspberrypi:~/proxmark3/tools/jtag_openocd $ ./openocd_flash_recovery.sh
Open On-Chip Debugger 0.11.0-rc2
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_gates_jtag srst_push_pull connect_deassert_srst
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
Warn : Transport "jtag" was already selected
DEPRECATED! use 'adapter speed' not 'adapter_khz'
adapter speed: 1000 kHz
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : clock speed 1001 kHz
Info : JTAG tap: sam7x.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787 (<unknown>), part: 0xf0f0, ver: 0x3)
Info : Embedded ICE version 1
Info : sam7x.cpu: hardware has 2 breakpoint/watchpoint units
Info : starting gdb server for sam7x.cpu on 3333
Info : Listening on port 3333 for gdb connections
target halted in Thumb state due to debug-request, current mode: Abort
cpsr: 0x600000f7 pc: 0x002008a0
Warn : Flash driver of sam7x.flash.0 does not support free_driver_priv()
Warn : Flash driver of sam7x.flash.1 does not support free_driver_priv()

Ok, there is some warning, but it worked!
Flashing the firmware, the right way
The proxmark is back in /dev/ttyACM0!
$ ls /dev/ttyACM0
/dev/ttyACM0
Now let flash everything properly. On the laptop, in the proxmark3 repository:
$ ./pm3-flash-bootrom
[=] Session log /home/me/.proxmark3/logs/log_20220824.txt
[+] loaded from JSON file /home/me/.proxmark3/preferences.json
[+] About to use the following file:
[+] /home/me/bin/proxmark3/client/../bootrom/obj/bootrom.elf
[+] Loading ELF file /home/me/bin/proxmark3/client/../bootrom/obj/bootrom.elf
[+] ELF file version Iceman/master/v4.14831-891-g5a6440f29 2022-08-22 20:47:01 a67766443
[+] Waiting for Proxmark3 to appear on /dev/ttyACM0
🕑 59 found
[+] Entering bootloader...
[+] (Press and release the button only to abort)
[+] Waiting for Proxmark3 to appear on /dev/ttyACM0
🕑 49 found
[=] Available memory on this board: 512K bytes
[=] Permitted flash range: 0x00100000-0x00180000
[+] Loading usable ELF segments:
[+] 0: V 0x00100000 P 0x00100000 (0x00000200->0x00000200) [R X] @0x94
[+] 1: V 0x00200000 P 0x00100200 (0x00000d18->0x00000d18) [R X] @0x298
[+] Flashing...
[+] Writing segments for file: /home/me/bin/proxmark3/client/../bootrom/obj/bootrom.elf
[+] 0x00100000..0x001001ff [0x200 / 1 blocks]
. ok
[+] 0x00100200..0x00100f17 [0xd18 / 7 blocks]
....... ok
[+] All done
[=] Have a nice day!
$ ./pm3-flash-fullimage
[=] Session log /home/me/.proxmark3/logs/log_20220824.txt
[+] loaded from JSON file /home/me/.proxmark3/preferences.json
[+] About to use the following file:
[+] /home/me/bin/proxmark3/client/../armsrc/obj/fullimage.elf
[+] Loading ELF file /home/me/bin/proxmark3/client/../armsrc/obj/fullimage.elf
[+] ELF file version Iceman/master/v4.14831-891-g5a6440f29 2022-08-22 20:47:21 a67766443
[+] Waiting for Proxmark3 to appear on /dev/ttyACM0
🕑 59 found
[+] Entering bootloader...
[+] (Press and release the button only to abort)
[+] Waiting for Proxmark3 to appear on /dev/ttyACM0
🕑 49 found
[=] Available memory on this board: 512K bytes
[=] Permitted flash range: 0x00102000-0x00180000
[+] Loading usable ELF segments:
[+] 0: V 0x00102000 P 0x00102000 (0x00047a9c->0x00047a9c) [R X] @0x98
[+] 1: V 0x00200000 P 0x00149a9c (0x00001b34->0x00001b34) [R X] @0x47b38
[=] Note: Extending previous segment from 0x47a9c to 0x495d0 bytes
[+] Flashing...
[+] Writing segments for file: /home/me/bin/proxmark3/client/../armsrc/obj/fullimage.elf
[+] 0x00102000..0x0014b5cf [0x495d0 / 587 blocks]
...................................................................
@@@ @@@@@@@ @@@@@@@@ @@@@@@@@@@ @@@@@@ @@@ @@@
@@! !@@ @@! @@! @@! @@! @@! @@@ @@!@!@@@
!!@ !@! @!!!:! @!! !!@ @!@ @!@!@!@! @!@@!!@!
!!: :!! !!: !!: !!: !!: !!! !!: !!!
: :: :: : : :: ::: : : : : : :: :
. .. .. . . .. ... . . . . . .. .
...................................................................
...................................................................
.............. ok
[+] All done
[=] Have a nice day!
Last check, power-off the proxmark, power-on, and…
$ ./pm3
[=] Session log /home/me/.proxmark3/logs/log_20220824.txt
[+] loaded from JSON file /home/me/.proxmark3/preferences.json
[=] Using UART port /dev/ttyACM0
[=] Communicating with PM3 over USB-CDC
8888888b. 888b d888 .d8888b.
888 Y88b 8888b d8888 d88P Y88b
888 888 88888b.d88888 .d88P
888 d88P 888Y88888P888 8888"
8888888P" 888 Y888P 888 "Y8b.
888 888 Y8P 888 888 888
888 888 " 888 Y88b d88P
888 888 888 "Y8888P" [ ❄️ ]
[ Proxmark3 RFID instrument ]
MCU....... AT91SAM7S512 Rev B
Memory.... 512 Kb ( 59% used )
Client.... Iceman/master/v4.14831-891-g5a6440f29 2022-08-22 20:47:21
Bootrom... Iceman/master/v4.14831-891-g5a6440f29 2022-08-22 20:47:01
OS........ Iceman/master/v4.14831-891-g5a6440f29 2022-08-22 20:47:21
Target.... PM3 GENERIC
[usb] pm3 -->
Victory!