Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB boot wipe #28

Open
kimstik opened this issue Mar 9, 2023 · 18 comments
Open

USB boot wipe #28

kimstik opened this issue Mar 9, 2023 · 18 comments

Comments

@kimstik
Copy link

kimstik commented Mar 9, 2023

I made simple stupid blinker on PA0 for ch32v203. It works fine.
My issue that when it assembled with clang instead of GCC it creates bit different elf file which somehow magically erase/disable internal 28k USB bootloader code.

wchisp.exe flash main.elf

After programming this elf file i am not able anymore to use USB ISP, but SDI way still works.
now wch-link over SDI shows empty region of 28k bootloader @0x1FFF8000.

wchisp is flashing stack region over address 0x20002000

May someone confirm the issue?
Any ideas to recover USB bootloader functionality?

wchisp v0.2.0
main.elf.zip

@robots
Copy link

robots commented Apr 19, 2023

This is very interesting feature :-)

@robots
Copy link

robots commented Apr 19, 2023

19:53:56 [INFO] Read ../../../main.elf as ELF format
19:53:56 [INFO] Found loadable segment, physical address: 0x00000000, virtual address: 0x00000000, flags: 0x5
19:53:56 [INFO] Section names: [".init"]
19:53:56 [INFO] Found loadable segment, physical address: 0x00000004, virtual address: 0x00000004, flags: 0x6
19:53:56 [INFO] Section names: [".vector"]
19:53:56 [INFO] Found loadable segment, physical address: 0x00000034, virtual address: 0x00000034, flags: 0x5
19:53:56 [INFO] Section names: [".text"]
19:53:56 [INFO] Found loadable segment, physical address: 0x20002000, virtual address: 0x20002000, flags: 0x6
19:53:56 [INFO] Section names: [".stack"]
19:53:56 [INFO] Firmware size: 536881152
19:53:56 [INFO] Erasing...
19:53:56 [INFO] Erased 524299 code flash sectors
19:53:57 [INFO] Erase done
19:53:57 [INFO] Writing to code flash...

I have just tested this "feature", I want to find way how to replace bootloader with my own. So this is good starting point.

firmware size is wrongly generated, and erase is run on many more sectors than needed

@kimstik
Copy link
Author

kimstik commented Apr 20, 2023

19:53:56 [INFO] Read ../../../main.elf as ELF format
19:53:56 [INFO] Found loadable segment, physical address: 0x00000000, virtual address: 0x00000000, flags: 0x5
19:53:56 [INFO] Section names: [".init"]
19:53:56 [INFO] Found loadable segment, physical address: 0x00000004, virtual address: 0x00000004, flags: 0x6
19:53:56 [INFO] Section names: [".vector"]
19:53:56 [INFO] Found loadable segment, physical address: 0x00000034, virtual address: 0x00000034, flags: 0x5
19:53:56 [INFO] Section names: [".text"]
19:53:56 [INFO] Found loadable segment, physical address: 0x20002000, virtual address: 0x20002000, flags: 0x6
19:53:56 [INFO] Section names: [".stack"]
19:53:56 [INFO] Firmware size: 536881152
19:53:56 [INFO] Erasing...
19:53:56 [INFO] Erased 524299 code flash sectors
19:53:57 [INFO] Erase done
19:53:57 [INFO] Writing to code flash...

I have just tested this "feature", I want to find way how to replace bootloader with my own. So this is good starting point.

firmware size is wrongly generated, and erase is run on many more sectors than needed

Is USB ISP in this chip is dead?

@robots
Copy link

robots commented Apr 20, 2023

Yes, i read the bootloader flash as zeros, that means it was written to zeros. Erased flash in these chips is 0x39 0xe3

@robots
Copy link

robots commented Apr 21, 2023

I played a bit more with this thing, It seemed that the chip locked itself. After connecting to wch linke utility it unlocked and the bootloader section is indeed erased.
More tests to come....

@robots
Copy link

robots commented Apr 23, 2023

So, i connected the chip to the WCHlink utility in windows. It told me that the chip was locked. Unlocking the chip helped, and i can read the bootlaoder memory as empty:

(gdb) monitor mdw 0x1fff8000 100
0x1fff8000: e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339
0x1fff8020: e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339
0x1fff8040: e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339
0x1fff8060: e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339
0x1fff8080: e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339
0x1fff80a0: e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339 e339e339

I think what happened is, that the chip tried to erase flash in 64kB blocks. Flash memory in these chips is external SPI or QSPI flash.

Bootloader erases memory like this:
shot-2023-04-23_15-57-52

First at most 0x3f 64kB blocks, then at most 0x1f 32kBlocks, then at most 3x 4kBlocks, then rest as 1kBlocks (4x256).
minimum amount is 8sectors, maximum 0x1e0 (480) sectors. Sector is 1k.

If you request erase of 480sectors, that is 0x78000. This chip's flash memory goes up to address 0x38000. So the bootloader tries to erase memory "beyond".

The problem here is:

  • Chip should no allow to erase beyond what is mapped to address space
  • bootloader should check chip memory size.

How to get data back ? Well that is problem. When you try to program anything higher than 0x08038000 you get hardfault. Except when you try to program 0x1fff8000 address space. But it wont get written, but it will not hardfault either! It will hang there for the write in progress flag to drop.

My guess is that there is some "unlock bootloader" for ch32v20x/30x chips. But i have not found it yet. (I have tested the ch32v003 method FLASH_BOOT_MODEKEYR).

Here is the test code i use:
test.txt

any suggestions are welcome :-)

@elfmimi
Copy link

elfmimi commented Apr 24, 2023

Thanks for sharing your findings. it's very interesting.

@robots
Copy link

robots commented Apr 24, 2023

IMG_20230413_105327

@robots
Copy link

robots commented Apr 24, 2023

you can see second die in upper left corner

@elfmimi
Copy link

elfmimi commented Apr 24, 2023

Wow!

@robots
Copy link

robots commented Apr 24, 2023

fiddling with bits that you should not ....

(gdb) monitor mdw 0x1fff8000 10
0x1fff8000: 12341234 12341234 12341234 e339e339 e339e339 e339e339 e339e339 e339e339
0x1fff8020: e339e339 e339e339

I call it success (at least partial), the flash controller locked up, and needed power cycle. But the data is there !!

@kimstik
Copy link
Author

kimstik commented Apr 25, 2023

Now it will be nice to find a way to change the bootloader part (at least one bit)
There is a possibility that my code simply disabled access to the bootloader, but did not erase it.

@Xelus22
Copy link

Xelus22 commented Jul 8, 2023

Is there a datasheet on the bootloader sequence? Looks like as you said there is no check in the bootloader (or a logic error). I also would like to know if you can USB ISP over the USB HS interface (on CH32V305/7).

@robots
Copy link

robots commented Aug 20, 2023

Sorry guys for looong time waiting :)

https://github.com/robots/wch-ch32v20x-flash

I have written soft to repair the bootloader (or replace it with anything else)

@elfmimi
Copy link

elfmimi commented Aug 20, 2023

amazing!

@Xelus22
Copy link

Xelus22 commented Aug 21, 2023

Potentially could get a tinyUF2 going in the bootloader then :O (at least for ch32v307 as that is support in tinyUSB)

@kimstik
Copy link
Author

kimstik commented Aug 21, 2023

Potentially could get a tinyUF2 going in the bootloader then :O (at least for ch32v307 as that is support in tinyUSB)

Exactly! Or tiny DFU bootloader if UF2 will not fit.

@kimstik
Copy link
Author

kimstik commented Aug 21, 2023

Sorry guys for looong time waiting :)

https://github.com/robots/wch-ch32v20x-flash

I have written soft to repair the bootloader (or replace it with anything else)

	// unlock bootloader area - 0x1fff8000
	FLASH->CTLR |= 0x20 00 00 00;

Perfect catch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants