Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

Miyoo Mini Unbricking Guide v1.

0
So, you bricked your Miyoo Mini during a firmware update, and now you’re looking sad with a dark and empty screen.
Don’t worry, this has also happened to quite a few people before you, and it’s almost certainly recoverable. Follow this
guide to get your device back into action.

Disclaimer: Everything you do in this guide is at your own risk. The reader assumes full responsibility for any actions
performed in accordance with these instructions.

How did this happen?

The update process on the Miyoo Mini uses the bootloader/u-boot image burned into the system to update the OS
stored in the onboard flash memory. Every time you boot the unit, it checks for the presence of a miyoo283_fw.img file
in the root of the SD card, and if the version it reads from that file is different than the version it thinks is currently
installed, it will start the update process. This is what is happening in the background when you see the “rocket screen”
during an update.

The problem is the SD card driver inside the bootloader is somewhat buggy, and is very particular about the SD card that
you’re using in the system. There are several distinct phases of the update process that all get queued up at once, and if
this SD card driver cannot properly initialize the SD card at each phase, the update process will skip that phase, and
move on to the next one. This leaves the Miyoo in a weird partially flashed state, and if the wrong phases get skipped, it
will no longer boot.

Great, so how do I recover it?

The easiest thing to do is find as many SD cards as you have lying around, and retry the update procedure on each one
until it works.

You’ll need to use a different (older/newer) version of the firmware than the one you originally bricked the device with,
because the Mini will not try to update again if the file it reads off the SD card is the same version that it thinks it’s on.

Thankfully, Miyoo has put out a firmware version called the “black screen firmware” that generally works quite well for
this.

https://drive.google.com/drive/folders/1JoZG06NFk8hV6bf_ROCHvvAEr4jogHmn

Firmware recovery procedure:

1. Format the SD card as FAT32


2. Put the black screen version of the miyoo283_fw.img file in the root filesystem of the SD card
3. Put the SD card in the Mini
4. Plug in the power cable (with the battery out)
5. Wait between 5-10 minutes per attempt.

Unfortunately, if the screen is blacked out (and it probably is), you’re flying completely blind here, so just wait the full
time at each attempt. Unplug the Mini, take out the SD card, plug the Mini back in and see if you see the boot screen
followed by the charging icon. If so, the recovery was successful. If the first card you try doesn’t work, find another card,
format it, and try again. Some people get lucky on the second card, some people have tried 10+ cards before finding a
good one. Generally, this method recovers the vast majority of bricked units. Once you find the card that recovers the
system, use that *exact same card* to repeat the update to the latest version from Miyoo, and you’re good to go.

This isn’t working no matter how much I try, what now?

The great thing about the above method is that it requires no more skill than changing an SD card, it just takes a ton of
patience. However, the big issue with the above method is that you have no idea what’s really going on behind the
scenes, and if you did, you could recover it with much less “guess and check”.
If you’re comfortable with taking things apart and hooking things up, you’ll need some hardware to dig into the problem
further. Let’s get started.

You will need:

1x mostly dead Miyoo Mini


1x Raspberry Pi (any version) with attached 40 pin dual row header
6x 2.54mm (0.1") "Dupont connector" female to female jumper wires (ideally in various colors)
1x 2.54mm (0.1") single row straight pin header (any number of pins long, broken into 2x 4pin pieces)

Preparing the hardware

You’ll need to remove the screws holding on the back shell of the Mini, and once removed, on the left-hand side you’ll
see the 4 vertical holes in a row that are used for the debug port.

From top to bottom, the pinouts are:

UART:

Miyoo RasPi

GND Pin 6
RXD Pin 10
TXD Pin 8
3v3 Not Connected

I2C:

Miyoo RasPi

GND Pin 9
SDA Pin 3
SCL Pin 5
3v3 Not Connected
Next snap off 4 pins worth of the single row pin header,
and slip 3 of the Dupont wires over the first three pins.
The fourth pin is the 3v3 signal, and this does not need to
(nor should it ever) be connected for any of these
procedures. It is only present on this header to provide
additional mechanical support for the cable and to
prevent misalignment.

Now take the other end of the Dupont cable, and slip the
connectors over the proper pins on the Raspberry Pi,
following the pinout given above depending on the
connection type required. I’m using a Pi Zero W here, but
any model will do.

When you’re ready to communicate with the Mini, take


the 4 pin connector and slide it into the 4 hole debug
port, paying attention to ensure the ground pin is at the
top and the empty 3v3 pin is at the bottom. Then, angle
the cable in a way such that the tension of the cable
leading away from the debug port holds the pins in place.
It isn't the most secure connection, but it seems good
enough to get the job done without soldering anything in.
Be sure to set the Mini down somewhere you won’t
bump into the cables while you're working on it.
Preparing the software

Install Raspberry Pi OS (raspbian) if not already installed to your Pi. We'll also assume you know how to use the Linux
console / SSH into the Pi to use it.

We're going to need to do some setup to prepare the Pi to talk to the electrical interfaces on the Mini.

First, get a root shell:


pi@raspberrypi:~ $ sudo bash

and we’re going to want to configure the system interfaces:


root@raspberrypi:/home/pi# raspi-config

Select option 3:
3 Interface Options Configure connections to peripherals

and turn on items 4, 5, and 6:


I4 SPI Enable/disable automatic loading of SPI kernel module
I5 I2C Enable/disable automatic loading of I2C kernel module
I6 Serial Port Enable/disable shell messages on the serial connection

You’ll be asked some questions about the serial port, and you’ll need to answer them as follows:
Would you like a login shell to be accessible over serial? => *** No ***
Would you like the serial port hardware to be enabled? => *** Yes ***

If you did this correctly, the following will be displayed:

The serial login shell is disabled


The serial interface is enabled

Then select Finish. You will then be asked “Would you like to reboot now?”, answer Yes.

Once the Pi has rebooted, obtain a root shell again:


pi@raspberrypi:~ $ sudo bash

and let’s install and run a console connection:

root@raspberrypi:/home/pi# apt install picocom


root@raspberrypi:/home/pi# picocom -b 115200 /dev/ttyS0
Type [C-a] [C-h] to see available commands
Terminal ready

Now attach the UART cable that you made using the above instructions to the debug port of the Mini, and apply power
to the Mini via a USB-A to USB-C cable. If everything is connected correctly, you should see the diagnostic output of the
Mini on your SSH terminal. If not, make sure you have good tension on the pins in the board, and they are hooked to the
right pins on the Pi and the Mini.
Finding a good SD card

Now we have to interrupt the normal boot process to get a bootloader shell. This is accomplished by holding down the
enter key on the terminal while the Mini is booting. If you have the "/ # " prompt, you can just type "reboot" (no quotes)
and hold down the enter key. If you have anything else, unplug the Mini power cable and then keep holding down the
enter key on your terminal while you plug the power back in.

The mini will reboot, and you should eventually (keep holding enter until you do) get a prompt that looks like this:

SigmaStar #

If you do, good news, you have a functional bootloader/u-boot image left on your mini. This makes the recovery process
much easier.

Unfortunately, in its current configuration, the only way to load an image into the system is via the SD card slot. The SD
card driver inside the bootloader (which is different from the driver in the booted Linux system) is very flaky/picky about
what SD card you have (which is how you ended up in this mess in the first place).

Insert a blank FAT32 formatted card into the SD card slot (note: windows will not format most large SD cards as FAT32,
you need to use a special tool like Rufus to format it correctly, exFAT will not work)

You now have to start testing SD cards in the bootloader to see if they are suitable for upgrading the firmware:

There are 3 commands you have to run to fully test a card:


mmc rescan
mmc info
fatls mmc 0:1

This is a SanDisk Extreme 64GB card. If your card behaving similar to this, do not attempt to use it for upgrading the
Mini:
SigmaStar # mmc rescan
gpio debug MHal_GPIO_Pad_Set: pin=19
_[sdmmc_0] Err: #Cmd_41 (0x401F8000)=>(E: 0x0008)(S: 0x00000120)__(L:919)
_[sdmmc_0] Err: #Cmd_1 (0x00000000)=>(E: 0x0008)(S: 0x00000120)__(L:919)
Card did not respond to voltage select!

SigmaStar # mmc info


gpio debug MHal_GPIO_Pad_Set: pin=19
_[sdmmc_0] Err: #Cmd_41 (0x401F8000)=>(E: 0x0008)(S: 0x00000120)__(L:919)
_[sdmmc_0] Err: #Cmd_1 (0x00000000)=>(E: 0x0008)(S: 0x00000120)__(L:919)
Card did not respond to voltage select!

SigmaStar # fatls mmc 0:1


get_dev_hwpart (mmc, 0, 0)
get_dev_hwpart ifname mmc, name usb,reloc_get_dev 23f3aad0, select_hwpart 00000000,mmc_get_dev 23f74908,
mmc_select_hwpart 23f738b8
get_dev_hwpart ifname mmc, name mmc,reloc_get_dev 23f74908, select_hwpart 23f738b8,mmc_get_dev 23f74908,
mmc_select_hwpart 23f738b8
gpio debug MHal_GPIO_Pad_Set: pin=19
_[sdmmc_0] Err: #Cmd_41 (0x401F8000)=>(E: 0x0008)(S: 0x00000120)__(L:919)
_[sdmmc_0] Err: #Cmd_1 (0x00000000)=>(E: 0x0008)(S: 0x00000120)__(L:919)
Card did not respond to voltage select!
** Bad device mmc 0 **
get_device_and_partition(mmc, 0:1) return -1, fstype=1

This is a Samsung Pro Plus 32GB card, and it works perfectly for upgrading the Mini.

SigmaStar # mmc rescan


gpio debug MHal_GPIO_Pad_Set: pin=19

SigmaStar # mmc info


Device: MStar SD/MMC
Manufacturer ID: 1b
OEM: 534d
Name: 00000
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 29.8 GiB
Bus Width: 4-bit

SigmaStar # fatls mmc 0:1


get_dev_hwpart (mmc, 0, 0)
get_dev_hwpart ifname mmc, name usb,reloc_get_dev 23f3aad0, select_hwpart 00000000,mmc_get_dev 23f74908,
mmc_select_hwpart 23f738b8
get_dev_hwpart ifname mmc, name mmc,reloc_get_dev 23f74908, select_hwpart 23f738b8,mmc_get_dev 23f74908,
mmc_select_hwpart 23f738b8
part str 1, part 1
part_type is 2, part 1
get_partition_info part 1, ret 0
return part 1
get_device_and_partition(mmc, 0:1) return 1, fstype=1
probe fstype = 1, info->fstype=1
probe fs_dev_desc = 00000001, info->null_dev_desc_ok=0
system volume information/

0 file(s), 1 dir(s)

Some cards will work fine with "mmc rescan", and "fatls mmc 0:1", but fail on "mmc info". As long as you can repeatedly
run "fatls mmc 0:1" and not get any errors, that’s the important one, and you can probably not worry about a bad "mmc
info". However, the ideal card will pass all three.

Run fatls mmc 0:1 several times in a row, and if it succeeds every time you run it, this card should be compatible with
the upgrade procedure. This is your "golden card" that you'll want to use for all future updates to the Mini.

Quick aside about card brands: these two cards above are verified genuine from reputable retailers and made by major
card manufacturers. This is not to say that “Samsung works and SanDisk doesn’t”, because it really is total luck as to
which cards will work and which cards will fail. I’ve seen otherwise identical cards (size, brand, version, etc) where one
works fine and the other fails completely. I would not count on finding a trend of “brand X works better than brand Y”.
Now you will want to check which version of the Miyoo firmware the device thinks it's on.

SigmaStar # env print miyoo_version


miyoo_version=202201082152

You will want to pop the SD card out of the Mini now, and put a copy of the miyoo283_fw.img in the root of the SD card
that does *not* match the version that it's currently reporting. For most people, you are going to want to use the "black
screen" firmware file available from Miyoo for this. This firmware is old enough it's unlikely that the version your device
is currently reporting is the same as that firmware file has inside it. In the event that you put the black screen firmware
on your *bootloader tested working SD card*, and it doesn't start to update after a couple of tries, don't hesitate to try a
different version if you get stuck. However, if you try a couple of different versions and it doesn't take off on any of
them, you've probably got something else going on.

Unplug the Mini from the power cable, insert your SD card with the firmware file in the root, make sure your UART cable
is in place, and plug in the power cable. If all goes according to plan, you start to see the Mini begin to flash multiple
partitions of the entire system all in a row. Wait until it's completely finished, and as long as you don't see any obvious
errors, proceed on.

Remove the power cable from the Mini, take the SD card out, and plug the cable back in. Check the front screen for signs
of life. If it shows the boot screen and then the charging icon, that’s a good indicator of success. Delete the *.img file
from the SD card (or format it again), and put the SD card back in the Mini. Pull the power cable out, and if you hold the
power button down on the Mini while plugging in the power cable back in, it should boot to the OS instead of the
charging screen to fully verify.

You can reassemble the device at this point if all looks good.

Now that you're back in operation, take the very latest firmware .img file version from Miyoo, put it on the root of the
*exact same* SD card you used to recover it with, and it should flash again like normal.

Congratulations, you just unbricked your Mini.

Help, none of this has worked and I'm still bricked.

There is one last method you can use to recover a completely dead Mini. Perhaps your bootloader is gone or all the SD
cards in the world don’t seem to work for you. You can directly program the onboard flash *very* slowly using the I2C
protocol over the debug port on the Mini. No joke, it takes almost 90 minutes to do it this way, but it should work when
all else has failed.

You’ll need to make an additional cable as indicated above, using the I2C pinout instead of the UART pinout. You really
want to make two cables here (although you could get away with one if you have to), because you’ll need to switch
between UART and I2C modes to fully start the process.

First, we’ll need some additional software on the Pi, including a custom configured version of flashrom v1.2 that
understands how to use this interface.

Get a root shell if you don’t already have one:


pi@raspberrypi:~ $ sudo bash

and let’s get some software:

root@raspberrypi:/home/pi# apt install i2c-tools screen build-essential libpci-dev libusb-1.0-0-dev


root@raspberrypi:/home/pi# wget https://github.com/flashrom/flashrom/archive/refs/tags/v1.2.tar.gz
root@raspberrypi:/home/pi# tar -zxvf v1.2.tar.gz
root@raspberrypi:/home/pi# cd flashrom-1.2/
root@raspberrypi:/home/pi/flashrom-1.2# make CONFIG_MSTARDDC_SPI=yes
CONFIG_ENABLE_LIBPCI_PROGRAMMERS=no

Note: The make line above is all one line (not two), and now wait for it to build.

Assuming it compiled correctly, now copy the binary out of the source tree to the parent directory.

root@raspberrypi:/home/pi/flashrom-1.2# cp flashrom ..
root@raspberrypi:/home/pi/flashrom-1.2# cd ..
root@raspberrypi:/home/pi/#

Connect the UART cable between the Pi and the Mini, and connect to the console

root@raspberrypi:/home/pi# picocom -b 115200 /dev/ttyS0


Type [C-a] [C-h] to see available commands
Terminal ready

Boot up the Mini while holding the enter key, so that you get dropped to the SigmaStar prompt:

SigmaStar #

Once at the prompt send the command “debug” (no quotes), and the system should reply back with:

SigmaStar # debug

debug mode on, cmdline is disabled

If your bootloader is badly damaged or missing to the point you can’t get a SigmaStar prompt, while I’ve not been able
to test this, you should be able to skip this step in that case.

While leaving the device powered on, now remove the UART cable from the Mini, and replace it with the I2C cable,
making sure the ground pin and empty 3v3 pin is in the proper position.

Open a new terminal / SSH session to the Pi, and run:

pi@raspberrypi:~ $ sudo bash


root@raspberrypi:/home/pi/# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- 49 -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- 59 -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

You want to see a number 49 on the output of i2cdetect. If you don’t, recheck all your I2C cable wiring and make sure
the Mini is in debug mode via the bootloader.

If address 49 is detected, then issue:


root@raspberrypi:/home/pi/# ./flashrom -p mstarddc_spi:dev=/dev/i2c-1:49,noreset=1
and flashrom will attempt to detect your flash chip:

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).


Info: Will try to use device /dev/i2c-1 and address 0x49.
Info: Will NOT reset the device at the end.
Found GigaDevice flash chip "GD25B128B/GD25Q128B" (16384 kB, SPI) on mstarddc_spi.
Found GigaDevice flash chip "GD25Q127C/GD25Q128C" (16384 kB, SPI) on mstarddc_spi.
Multiple flash chip definitions match the detected chip(s): "GD25B128B/GD25Q128B", "GD25Q127C/GD25Q128C"
Please specify which chip definition to use with the -c <chipname> option.
Info: Reset command was not sent. Either the noreset=1 option was used, or an error occurred.

My particular chip happens to be a 128C and flashrom can’t auto-select the specific model, so we'll pass that option to it
as asked: (This may not be required if flashrom can auto-select your chip)

root@raspberrypi:/home/pi# ./flashrom -p mstarddc_spi:dev=/dev/i2c-1:49,noreset=1 -c "GD25Q127C/GD25Q128C"

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).


Info: Will try to use device /dev/i2c-1 and address 0x49.
Info: Will NOT reset the device at the end.
Found GigaDevice flash chip "GD25Q127C/GD25Q128C" (16384 kB, SPI) on mstarddc_spi.
No operations were specified.

Now we are ready to start flashing. At this point, you have to decide if you want to backup your existing firmware or not.
I’m not sure if there is anything valuable in the broken firmware, but if you blow it away without making a copy, it’s gone
forever. It will take an additional 30 minutes to back up the firmware if you choose to do so. Also, because these
operations take so long, you’ll probably want to run them in “screen” so that in the event you get disconnected, they
will continue to run. Just type “screen” (no quotes) and hit enter twice. Your current shell is now screen enabled. This is
not mandatory, but probably a good idea.

Save the existing firmware (optional):


root@raspberrypi:/home/pi# ./flashrom -p mstarddc_spi:dev=/dev/i2c-1:49,noreset=1 -c "GD25Q127C/GD25Q128C" -r
existing-firmware.bin

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).


Info: Will try to use device /dev/i2c-1 and address 0x49.
Info: Will NOT reset the device at the end.
Found GigaDevice flash chip "GD25Q127C/GD25Q128C" (16384 kB, SPI) on mstarddc_spi.
Reading flash... done.
Info: Reset command was not sent. Either the noreset=1 option was used, or an error occurred.

Now you’ll need a good working copy of the firmware to flash into the system. If you have a previous good backup of the
flash, you can use that, or located here is a backup that someone else has created:

root@raspberrypi:/home/pi# wget https://github.com/linux-chenxing/linux-


chenxing.org/files/7739940/MiYoo283v1.1.zip
root@raspberrypi:/home/pi# unzip MiYoo283v1.1.zip

Make sure the Mini is in a place where you will not bump into it, as this next part will take about 90 minutes. If the I2C
cable comes even the slightest bit loose during this process, you’ll have to start this next step over.
Write the new firmware:
root@raspberrypi:/home/pi# ./flashrom -p mstarddc_spi:dev=/dev/i2c-1:49,noreset=1 -c "GD25Q127C/GD25Q128C" -w
MiYoo283v1.1.bin

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).


Info: Will try to use device /dev/i2c-1 and address 0x49.
Info: Will NOT reset the device at the end.
Found GigaDevice flash chip "GD25Q127C/GD25Q128C" (16384 kB, SPI) on mstarddc_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
Info: Reset command was not sent. Either the noreset=1 option was used, or an error occurred.

After you see “VERIFIED”, the flash is restored, and you can reboot the Mini by pulling and reinserting the power plug.
You should see the screen light up, it will show the boot splash graphics then the charging icon.

This will be an older version of the firmware, so in order to update, you’ll still need to find a good working SD card with
the earlier procedure, or obtain a flash dump of a system that’s already up to date and flash that instead.

That’s it. This procedure uses the low level factory programming interface available on the Mini’s processor, which
should always be available no matter how badly corrupted your firmware is. As long as you can communicate with
address 49 on the I2C bus, you should be able to reflash your Mini back into operation.

You might also like