Hacking Flashing binaries onto HWFLY (v3 for OLED)

HelloShitty

Well-Known Member
OP
Member
Joined
Jan 16, 2022
Messages
147
Trophies
0
Age
122
XP
207
Country
Antarctica
Hello.

So, I'm a noob regarding this Nintendo stuff. However I like to dig in when it comes to electronics, programming, etc. I'm also a Linux user and I can't even believe most of these hacking is taking place under Windows! Knowing that this HWFLY chip is based on ARM chips, and knowing that Linux have an extensive support for ARM and huge community, I find it curious, to say at least, that no one or very little people is actually using Linux for this!

Anyway, I have a Nintendo Switch OLED and therefore I purchased an HWFLY v3. I got it earlier this week and I started digging about how to flash both
C:
bootloader.bin
and
C:
firmware.bin
in their respective addresses, as mentioned by method 3 in the repository github page here.

My setup is the following:
Debian BullsEye
OpenOCD
telnet
J-Link clone
and I'm using TMS, TCK, 3.3V and GND lines.
Laptop -- USB Cable -- J-Link -- HWFLY

I'm also following this video regarding connections and procedure. Of course, I had to adapt to my setup.
I know that there is someone in this forum that is probably using Linux for some of this stuff, but probably he's quite busy with many other things and won't come here just to discuss with some random guy what I am trying to do and how am trying to do it!

Anyway, I'm going to describe the steps I took and what happened in the process.
Before that, I want to make some considerations about the Github repository of the binary files and the video from Sthetix himself!

1st - Github repository
As I'm using Linux, I went to method 3. So while reading I find myself wondering why they mention a payload.bin file when there is no such file. This said, I assume that this payload.bin file is in fact firmware.bin file! I'm mentioning this because when we are messing with this kind of stuff, no errors are allowed. The smallest mistake and you get a brick instead of a functional chip!

Then, apparently, the tools provided by the people running this repository are only for windows. I'm really sorry for my words, but in my perspective this is a shame! :P... Don't take me wrong, I'm just a bit frustrated I don't have a ready to use tool as Windows users have!

2nd - Sthetix video
Sthetix mentions that when we connect the USB cable to the ST-Link (or GB something OB) programmer that we should see a red led light up. I got this red led at the beginning, but after start messing up with the chip, the red led no longer came up. More about this further in the thread.

Also, Sthetix mentions that when trying to flash the binary files, if we get errors, we MUST change USB port (under Windows) and not doing so, we will damage the chip! If anyone has any more info on this, please share. How can we damage the chip by not changing the USB port? In his video I see at least 4 failed attempts (or maybe success at the 4th port). How many computers (laptops) have 4 available USB ports or more? I only have 3 and one is already being used by the wireless mouse receiver! What if we get errors on all ports?


Anyway, this is already a long thread and I have the feeling very little people will read it through.

So, in my case, I started OpenOCD like:
Bash:
./openocd -s ~/Storage/Software/Linux/openocd/tcl/ -f interface/jlink.cfg -c "adapter speed 2000; transport select swd" -f target/stm32f1x.cfg
Open On-Chip Debugger 0.11.0-rc1+dev-00032-gbd1adcffe-dirty (2021-01-23-18:54)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
swd
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link V9 compiled Sep  1 2016 18:29:50
Info : Hardware version: 9.60
Info : VTarget = 3.327 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Error: stm32f1x.cpu -- clearing lockup after double fault
Polling target stm32f1x.cpu failed, trying to reexamine
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections

Then, I tried to flash bootloader.bin from telnet console:
Bash:
$ telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> program /media/Storage/Nintendo/hwfly-firmware/firmware/bootloader.bin 0x08000000 verify
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
device id = 0x17040410
STM32 flash size failed, probe inaccurate - assuming 128k flash
flash size = 128kbytes
stm32x device programming failed
failed erasing sectors 0 to 11
embedded:startup.tcl:530: Error: ** Programming Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 595
at file "embedded:startup.tcl", line 530
>

This seemed to me like a lock problem and as I saw in Sthetix video, he used some unlock option with the softwares he used, so I tried to do the same by:

Bash:
> stm32f1x unlock 0
stm32x unlocked.
INFO: a reset or power cycle is required for the new settings to take effect.

>

So, I shutdown telnet and OpenOCD, unplugged and plugged back the USB cable and tried again to program bootloader.bin
Bash:
$ telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> program /media/Storage/Nintendo/hwfly-firmware/firmware/bootloader.bin 0x08000000 verify
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
device id = 0x17040410
STM32 flash size failed, probe inaccurate - assuming 128k flash
flash size = 128kbytes
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
stm32f1x.cpu: external reset detected
timed out while waiting for target halted
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x61000003 pc: 0x080001ac msp: 0x20003fc0
error waiting for target flash write algorithm
error writing to flash at address 0x08000000 at offset 0x00000000
embedded:startup.tcl:530: Error: ** Programming Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 595
at file "embedded:startup.tcl", line 530
>

So, this was also a a no go. At this point, I'm out of knowledge! So, I talked to a friend of mine that is actually contributor on OpenOCD and is working on electronics and embedded systems for ages and he gave me some more tips and we were digging on this, but without big breakthroughs. Anyway, I'll just mention what we did so far.

He told me to start OpenOCD with the following option: -c "set WORKAREASIZE 0"
Bash:
$/openocd -s ~/Storage/Software/Linux/openocd/tcl/ -f interface/jlink.cfg -c "adapter speed 2000; transport select swd" -c "set WORKAREASIZE 0" -f target/stm32f1x.cfg
Open On-Chip Debugger 0.11.0-rc1+dev-00032-gbd1adcffe-dirty (2021-01-23-18:54)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
swd
0
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link V9 compiled Sep  1 2016 18:29:50
Info : Hardware version: 9.60
Info : VTarget = 3.333 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections

After this, I tried again to program bootloader.bin file at the specified address, from telnet:
Bash:
$ telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> program /media/Storage/Nintendo/hwfly-firmware/firmware/bootloader.bin 0x08000000 verify
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000154 msp: 0x20004000
** Programming Started **
device id = 0x17040410
STM32 flash size failed, probe inaccurate - assuming 128k flash
flash size = 128kbytes
not enough working area available(requested 60)
no working area available, can't do block memory writes
couldn't use block writes, falling back to single memory accesses
** Programming Finished **
** Verify Started **
not enough working area available(requested 52)
** Verified OK **
>

So, this seemed to work. Seems that we cannot use the option -c "set WORKAREASIZE 0" to unlock the chip, but it is required to program the file. Note that the chip is unlocked at this point! And also note that since the first time I tried to flash bootlader.bin file, I never saw the red led light up again. At this point, no led is lighting up!

So, in this condition, I tried immediately to upload firmware.bin file too.
Bash:
> program /media/Storage/Nintendo/hwfly-firmware/firmware/firmware.bin 0x08003000 verify
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000154 msp: 0x20004000
** Programming Started **
not enough working area available(requested 60)
no working area available, can't do block memory writes
couldn't use block writes, falling back to single memory accesses
** Programming Finished **
** Verify Started **
not enough working area available(requested 52)
SWD DPIDR 0x2ba01477
Failed to read memory at 0x08010004
embedded:startup.tcl:530: Error: ** Verify Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 591
at file "embedded:startup.tcl", line 530
>

So, firmware.bin failed to program correctly. We get a read memory error at 0x08010004. No clue what is going on at this point. However, we did a few more tests around this memory address. We tried to write a word and read it to check if it was in fact written and it could be read!
Bash:
> mdw 0x20000000
0x20000000: ffffffff

> mdw 0x20002000
0x20002000: 703f6966

> mww 0x20000000 0xcafe
> mdw 0x20000000      
0x20000000: 0000cafe

> mdw 0x20002000      
0x20002000: 703f6966

>

So, I think this shows that we can read an write in chip flash memory. We showed 2 memory addresses, wrote in one of them an then showed again the same memory addresses, an the word we trie to write, was there!

After this, we just tried to read the memory address that error out when we tried to flash firmware.bin and we got a read error, but a bit weird:
Bash:
> mdw 0x08010004
SWD DPIDR 0x2ba01477                                                                                                                                                                                 
Failed to read memory at 0x08010008
>

If you notice, we asked to read 0x08010004 but the error mentions 0x08010008. No idea why. However, today I can't replicate this error. Yesterday, after trying again to read at 0x08010004 I eventually got this instead:
Bash:
> mdw 0x08010004                                                                                                                                                                                    
0x08010004: ffffffff
>

Ok, I think I'm not going to add anymore info for now. We just did an erase flash memory test and that's all.
At this point, if I run the chip, I can see the 2 very weak led colours blinking very fast, red and blue (or purple), like side by side. I'm not sure this means that firmware.bin is badly written or what it means.
So, if anyone is willing to dig deeper on this, I would be up to that.
 
Last edited by HelloShitty,

HelloShitty

Well-Known Member
OP
Member
Joined
Jan 16, 2022
Messages
147
Trophies
0
Age
122
XP
207
Country
Antarctica
Ok, an update.
After a few more attempts and changing a couple of things I managed to (what I think) flash successfully both bootloader.bin and firmware.bin. However, it seems that the LEDs are still not blinking correctly.

I added a new wire to the mix connecting pin 7 of this chip to nTRST on my j-link clone. Not sure it helped in anyway but at least I could now flash firmware.bin file correctly and verify both files.

Bash:
> program /media/Storage/Nintendo/hwfly-firmware/firmware/firmware.bin 0x08003000 verify 
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
device id = 0x17040410
STM32 flash size failed, probe inaccurate - assuming 128k flash
flash size = 128kbytes
** Programming Finished **
** Verify Started **
** Verified OK **
>

I verified the files from withing telnet:
Bash:
> verify_image /home/psysc0rpi0n/Storage/Nintendo/hwfly-firmware/firmware/bootloader.bin 0x08000000
verified 11884 bytes in 0.324656s (35.747 KiB/s)

> verify_image /home/psysc0rpi0n/Storage/Nintendo/hwfly-firmware/firmware/firmware.bin 0x08003000 
verified 76756 bytes in 2.006804s (37.351 KiB/s)

>

After this and after getting some errors while trying to reset the chip, I decided to power cycle and eventually I got the leds like this:
unknown.png


This seems static, but it's not. They are flashing very very fast and very dim. I think they are dim because tey can't ligt up fast enough due to how fast they are blinking. But the color codes at github shows a similar situation:
image.png


I have been told that it is still not good and that I should try a full chip erase which is what I'll do next.
 

HelloShitty

Well-Known Member
OP
Member
Joined
Jan 16, 2022
Messages
147
Trophies
0
Age
122
XP
207
Country
Antarctica
Ok, I think this is done.
I just performed a mass erase, flashed both files again and then tried to connect the mod chip to the tiny USB adapter and connect the USB cable to the laptop and it looks like this:


I think I was looking to the leds and they didn't have any meaning, I guess! At least, while connected to the USB cable, it blinks as it should!
 

HelloShitty

Well-Known Member
OP
Member
Joined
Jan 16, 2022
Messages
147
Trophies
0
Age
122
XP
207
Country
Antarctica
After some more digging an discussing with my friend, we think there is some instability while trying to read the chip memory. I don't know if this might be related with some possible weaker connection by some poor wire soldering or if this j-link clone likes more GND wires to stabilize the signals (this happened to me in the past. I had 4 GND wires connected to an STM32 chip before I could flash firmware onto it).

Anyway, I have already removed the wires from the chip and I'm not going to do any more testing unless I really need it for some reason.

Another fact we came up with this memory reading issues is that if I insist reading these memory addresses that sometimes errors out, they eventually return their contents without errors. I mean, I run the command to read a memory address, it errors out, I repeat it once or twice more and eventually the contents are returned.
 

HelloShitty

Well-Known Member
OP
Member
Joined
Jan 16, 2022
Messages
147
Trophies
0
Age
122
XP
207
Country
Antarctica
Note for myself, using openocd, telnet, under Linux
When needed SWD to reflash chipnx make sure to:
check option WORKINGAREASIZE 0 only needed to program the chip. Not needed to unlock the chip!
mass_erase 0
lower target speed to 100Hz
disable watchdog with stm32f1x options_write 0 SWWDG
try to flash firmware.bin prior to bootloader.bin
 
General chit-chat
Help Users
    Psionic Roshambo @ Psionic Roshambo: https://imgur.com/gallery/ixIxxLJ