← ProjectsProject 02
2026/Released/Guide

Flashing DumberOS from macOS

I wrote this guide after installing DumberOS on my Doov R77 using only my M1 MacBook. Most existing instructions assumed Windows or an x86 Linux machine, so I documented the complete macOS workflow, including the problems I ran into and the fixes that worked for me.

How to install DumberOS on a Qin / Doov phone using an Apple Silicon Mac

I wrote this guide because I found the whole process pretty complicated.

Most of the existing guides assume that you have a Windows PC or an x86 Linux machine available. I don't. I only had a MacBook M1, so I had to figure out how to do the whole process directly on macOS.

I eventually got DumberOS running successfully on my Doov R77, and this README is the step-by-step guide I wish I had when I started.

I tried to write it for complete beginners and include the problems I actually ran into along the way.

Whenever you see a section called “If this happens to you”, that usually means it happened to me too and I included the fix that worked for me.

The exact macOS workflow in this README was personally tested on a Doov R77 + MacBook M1. The upstream Qin/Doov guide says the general flashing process applies to most compatible Qin/Doov devices, but some models need a different DumberOS image, BROM key combination or unlock method.

[!WARNING] Flashing can erase your data or brick the phone.

Do not skip the stock ROM backup.

Never casually erase or flash the preloader.

Flash DumberOS to system, never to super.

Official sources


1. Is your phone supported?

According to the current Qin/Doov guide:

DeviceDumberOS statusImage
Qin F21 ProOfficially supported30
Qin F22 ProOfficially supported31
Doov R77 Pro / R77cOfficially supported31
Doov R77Officially supported31
Doov R17 / Z17 Pro (3.5")Officially supported31
Qin F25 ProWorks, not officially supported31
Doov R70 ProWorks, not officially supported31
Tiq Mini M5 / M5sWorks, not officially supported31
Qin F22 (non-Pro)Not supported

The F21 Pro is the exception: use a DumberOS build containing 30.

For the other compatible phones, use 31.


2. What you need

  • Compatible phone
  • Apple Silicon Mac
  • ~20 GB free disk space
  • Phone charged to ~60% or more
  • Reliable USB data cable
  • Ideally a USB-C hub with USB-A + USB-A → USB-C data cable

Some Qin/Doov devices are picky about USB-C → USB-C.

If the phone does not charge or appear on the Mac, try:

MacBook → USB-C hub → USB-A port → USB-A-to-USB-C cable → phone


3. Install the Mac tools

Open Terminal.

Check Homebrew:

brew --version

If it is missing:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Install everything we need:

brew install python@3.12 openssl git libusb
brew install --cask android-platform-tools
brew install --cask macfuse

Check ADB and Fastboot:

adb version
fastboot --version

4. Install MTKClient

cd ~
git clone https://github.com/bkerler/mtkclient.git
cd ~/mtkclient

/opt/homebrew/bin/python3.12 -m venv mtk_venv
source mtk_venv/bin/activate

python -m pip install --upgrade pip wheel setuptools
pip install -r requirements.txt
pip install .

Test it:

python ./mtk.py --help

If this happens to you: Unable to find libfuse

This happened to me while setting up MTKClient. Even python ./mtk.py --help failed because mfusepy could not find libfuse.

This fixes it:

brew install --cask macfuse
ls -l /usr/local/lib/libfuse*.dylib

Retry:

cd ~/mtkclient
source mtk_venv/bin/activate
python ./mtk.py --help

5. Create working folders

mkdir -p "$HOME/DumberOS/stock_rom" "$HOME/DumberOS/rom"

Everything in this guide will be stored below:

~/DumberOS/

6. Download the correct DumberOS image

Open:

https://github.com/miki151/dumberos_build/releases

Choose between:

  • gapps — Google Play Services / Play Store
  • vanilla — Google-free / MicroG-oriented

Then choose the correct Android compatibility variant:

Qin F21 Pro

Download:

gapps30

or:

vanilla30

Other compatible Qin / Doov models

Download:

gapps31

or:

vanilla31

Example filename:

dumber_os-YYYYMMDD-gapps31-signed.img.gz

Move and unpack it:

mv ~/Downloads/*.img.gz "$HOME/DumberOS/rom/"
cd "$HOME/DumberOS/rom"
gunzip *.img.gz
ls -lh *.img

You need a real .img file before flashing.


7. Prepare the phone

On the phone:

  1. Open Settings → About phone
  2. Tap Build number repeatedly to enable Developer Options
  3. Open Developer options
  4. Enable:
    • OEM unlocking
    • USB debugging

Connect the phone.

adb devices -l

Approve the USB debugging prompt.

Run it again:

adb devices -l

You want the device state to be:

device

If this happens to you: unauthorized

I got this too. The Mac could see the phone, but ADB was still waiting for Android to authorize it.

On the phone, revoke USB debugging authorizations and enable debugging again.

Then:

adb kill-server
adb start-server
adb devices -l

If nothing appears

This was one of the first problems I ran into. My R77 did not even charge with the USB-C-to-USB-C cable I initially tried.

Check whether macOS sees the USB device:

system_profiler SPUSBDataType

If the phone does not even charge, change the cable / hub setup. Macbook -> USB-C Hub -> USB-A Cable -> Dumbphone


8. Record the original device information

These commands are read-only:

adb shell getprop ro.product.model
adb shell getprop ro.build.fingerprint
adb shell getprop ro.build.version.release
adb shell getprop ro.build.version.security_patch

9. Read the partition table

Disconnect the phone and power it completely off.

cd ~/mtkclient
source mtk_venv/bin/activate
python ./mtk.py printgpt

When MTKClient starts waiting, connect the powered-off phone.

If it works, you should see the GPT partition table.

BROM button combinations

If MTKClient does not detect the phone, start the MTK command first, then hold the model-specific buttons while connecting USB.

DeviceBROM buttons
Qin F21 ProMenu + Back
Qin F22 ProMenu + Back
Doov R77 Pro / R77cCall + Power
Doov R77Call + Power
Doov R17 ProCall + Power

For other models, check the upstream Qin/Doov guide before guessing.

If this happens to you: Handshake failed

I saw this too. In my case MTKClient immediately retried, detected the phone and continued normally.

If MTKClient immediately retries, detects the device and continues, that is usually fine.

If it keeps failing:

  1. Ctrl+C
  2. Disconnect the phone
  3. Power it off
  4. Start printgpt again
  5. Use the correct BROM key combination while reconnecting

10. Make a full stock ROM backup

[!IMPORTANT] Do not unlock or flash anything until this succeeds.

With the phone powered off and disconnected:

cd ~/mtkclient
source mtk_venv/bin/activate

python ./mtk.py rl --skip userdata "$HOME/DumberOS/stock_rom"

Now connect the powered-off phone.

A successful backup should end with something like:

DaHandler - All Dumped partitions success.

If errors occur, stop here.


11. Back up the preloader separately

Disconnect and power off the phone again.

cd ~/mtkclient
source mtk_venv/bin/activate

python ./mtk.py r preloader "$HOME/DumberOS/stock_rom/preloader.bin" --parttype=boot1

Connect the powered-off phone when MTKClient waits.

Then verify the backup and create checksums:

du -sh "$HOME/DumberOS/stock_rom"
ls -lh "$HOME/DumberOS/stock_rom/preloader.bin"

cd "$HOME/DumberOS"
shasum -a 256 stock_rom/* > stock_rom_SHA256.txt
shasum -a 256 -c stock_rom_SHA256.txt

Every checksum should end with:

OK

If possible, keep another copy of this backup somewhere safe.


12. Enter Fastboot

Boot Android normally and reconnect the phone.

adb devices
adb reboot bootloader
fastboot devices

You want a device followed by:

fastboot

If this happens to you: MTK FASTBOOT payload gives Access denied

This happened to me when I tried to enter Fastboot through MTKClient's BROM payload method.

On macOS, this alternative command can fail:

python ./mtk.py payload --metamode FASTBOOT

with:

USB CORE ERROR
[Errno 13] Access denied (insufficient permissions)

If Android still boots and ADB works, simply use:

adb reboot bootloader

instead.


13. Unlock the bootloader

[!WARNING] Unlocking factory-resets the phone.

Most models

Try:

fastboot flashing unlock

Confirm the unlock on the phone if requested.

Then verify:

fastboot getvar unlocked

You need:

unlocked: yes

Qin F21 Pro / devices where normal confirmation does not work

The upstream Qin/Doov guide documents a different method for the F21 Pro and similar devices where the Fastboot confirmation cannot be selected.

Power the phone off, then:

cd ~/mtkclient
source mtk_venv/bin/activate
python ./mtk.py da seccfg unlock

Connect the powered-off phone and let the command finish.

Then enter Fastboot again and verify the bootloader state.

Do not use this alternate method unless normal fastboot flashing unlock does not work or the upstream guide specifically recommends it for your model.


14. Check the active slot

fastboot getvar current-slot

You will normally see:

current-slot: a

or:

current-slot: b

15. Disable AVB / dm-verity verification

Use the vbmeta image from your own stock backup that matches the active slot.

Slot A

ls -lh "$HOME/DumberOS/stock_rom/vbmeta_a.bin"

fastboot --disable-verity --disable-verification flash vbmeta \
"$HOME/DumberOS/stock_rom/vbmeta_a.bin"

Slot B

ls -lh "$HOME/DumberOS/stock_rom/vbmeta_b.bin"

fastboot --disable-verity --disable-verification flash vbmeta \
"$HOME/DumberOS/stock_rom/vbmeta_b.bin"

You want OKAY for both sending and writing.


16. Enter FastbootD

fastboot reboot fastboot
fastboot devices
fastboot getvar is-userspace

You need:

is-userspace: yes

Do not flash system unless you are in FastbootD.


17. Erase old userdata

When switching from stock Android to DumberOS:

fastboot erase userdata
fastboot erase metadata

Both should finish with OKAY.


18. Flash DumberOS

Check the exact image filename:

ls -lh "$HOME/DumberOS/rom"/*.img

Then flash it to system.

Example:

fastboot -S 64M flash system "$HOME/DumberOS/rom/YOUR_DUMBEROS_IMAGE.img"

-S 64M uses smaller sparse chunks and can make large transfers more reliable on macOS.

[!CAUTION] The target is system.

Do not flash the DumberOS system image to super.

Wait until every sparse block has been sent and written successfully.

Do not reboot if the command ends in FAILED.


If this happens to you: usb_write failed with status e00002ed

This was the most annoying problem I ran into.

My first DumberOS flash stopped partway through with this exact macOS USB error. The phone was still in FastbootD, so the most important thing was not to reboot it.

This can happen during large Fastboot transfers on macOS.

Do not reboot the phone.

Leave it in FastbootD.

Disconnect and reconnect USB, then check:

fastboot devices
fastboot getvar is-userspace

You need:

is-userspace: yes

Then repeat the entire system flash:

fastboot -S 64M flash system "$HOME/DumberOS/rom/YOUR_DUMBEROS_IMAGE.img"

If possible, use another USB-A port on the hub.


19. F21 Pro users: check for old TWRP installs

Some F21 Pro devices may have TWRP installed from older community guides.

The upstream Qin/Doov documentation warns that certain TWRP installations break FastbootD and must be removed before DumberOS can be flashed.

If FastbootD does not work on an F21 Pro and you previously installed TWRP, follow the current upstream F21 Pro recovery section rather than flashing random boot images.

See:

https://github.com/xsmh/qin-doov-hacking


20. Reboot into DumberOS

Only after the flash finishes without FAILED:

fastboot reboot

An Orange State / unlocked bootloader warning is normal.

The first boot may take 5–10 minutes.


21. After first boot

Complete the normal setup.

Then check:

Settings → System → Updates

If you installed a gapps build, you can sign into Google and use the Play Store.


Recovery

Keep these files safe:

~/DumberOS/stock_rom
~/DumberOS/stock_rom_SHA256.txt

Before restoring anything, read:

https://github.com/xsmh/qin-doov-hacking

The general MTKClient full-backup restore command is:

cd ~/mtkclient
source mtk_venv/bin/activate

python ./mtk.py wl "$HOME/DumberOS/stock_rom"

This writes partitions back to the phone. Do not run it casually.


Why I wrote this

I just wanted DumberOS on my phone, had no Windows computer available, and found the existing process surprisingly difficult to piece together on an Apple Silicon Mac.

Several things went wrong on the way:

  • USB-C-to-USB-C did not work properly with my R77
  • MTKClient initially failed because of libfuse
  • ADB showed the phone as unauthorized
  • the BROM FASTBOOT payload hit a macOS permissions error
  • the first large Fastboot transfer died with e00002ed

Once I understood what those messages meant, the process became much less intimidating.

So this README is basically my attempt to put everything that finally worked into one place for people who are in the same situation: they want DumberOS, they only have a Mac, and they do not want to piece together five different guides before touching their phone.

If you successfully use this on another Qin/Doov model, or spot something that should be improved, feel free to open an issue or pull request.


Short version

Install macOS tools
↓
Download correct DumberOS image (F21 Pro = 30, others = 31)
↓
Enable OEM unlocking + USB debugging
↓
ADB test
↓
MTKClient printgpt
↓
Full stock ROM + preloader backup
↓
Verify checksums
↓
Enter Fastboot
↓
Unlock bootloader
↓
Disable AVB
↓
Enter FastbootD
↓
Erase userdata + metadata
↓
Flash DumberOS to system
↓
Reboot

A huge thank you to the original developers and contributors behind DumberOS, MTKClient, and the Qin/Doov hacking guides. This guide only exists because of the tools, research, documentation, and community work they shared publicly.

Please support the original projects, report bugs upstream when appropriate, and give credit where it belongs.