Skip to content

atc1441/MiBand10-BES2700iMP-BEST1503-Hacking

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

MiBand 10 SDK - BES2700iMP / BEST1503 (with DOOM)

A working, buildable firmware SDK for the Xiaomi Mi Band 10 application SoC, with a full custom display + touch bring-up and a port of DOOM running on the device.

This repository documents what the chip is, where the SDK came from, and how the missing pieces were recovered so that custom firmware can be built, flashed and actually run on the watch.

This repo is made together with this explanation video:(click on it)

YoutubeVideo

Overview


TL;DR

  • The Mi Band 10 main SoC is the BES2700iMP, known internally at BES as BEST1503.
  • No SDK was ever published for the BEST1503. The closest public code is a leaked SDK for the audio-oriented BES2700IHC / BEST1306.
  • Starting from that BEST1306 SDK, the BEST1503-specific differences (memory map, clocks, the display controller and the touch controller) were recovered by reverse-engineering the stock Mi Band firmware, and added here.
  • Flashing the watch - and the device pinout - was the single hardest part. It was solved using a separate leak of a BES flashing tool that happened to ship the SecondStage bootloader blobs for every BEST variant.
  • On top of the working firmware, GBADoom was ported. It boots, renders to the AMOLED panel and is controlled through the touchscreen.

The SDK folder is named MiBand10_SDK_BES2700IMP_BEST1503_DOOM.

Mi Band 9 / Mi Band 10: both bands use the same BES2700iMP / BEST1503 SoC and are in general very similar, so this work is expected to apply to both. Everything here, however, was only developed and tested on the Mi Band 10.


1. The chip and the naming maze

BES (Bestechnic) sells the same silicon under several names, which makes finding documentation and source confusing:

Marketing name BES internal name Where it is used Focus
BES2700iMP BEST1503 Mi Band 10 application processor Wearable / display
BES2700IHC BEST1306 TWS earbuds and audio devices Audio

The BEST1503 and BEST1306 are close relatives - same ARM Cortex-M33 core family, similar peripherals and a near-identical ROM layout - but they are not drop-in compatible. The two diverge exactly where it matters for a watch:

  • Memory map - the BEST1503 has more on-chip SRAM and a different bank layout.
  • Clocks / PMU - different display and PSRAM clock trees.
  • Display controller - the BEST1503 drives an AMOLED panel (the BEST1306 has no display path wired up).
  • Touch controller - the watch uses a capacitive touch IC the audio SDK knows nothing about.

Because the BEST1503 is a wearable part, BES never released a public SDK for it.


2. Where the SDK came from

There is no BEST1503 SDK in the wild. Two leaks made this project possible:

  1. The BEST1306 / BES2700IHC SDK source leak https://github.com/sprlightning/audio_prj_collections This is an audio-product SDK (TWS earbuds). It contains the full BES build system, the RTOS, the BT host, the HAL and the boot flow - everything except the parts that are specific to a watch. It is the foundation this repository is built on.

  2. A BES flashing tool, leaked inside another project https://github.com/Derek-Vencer/tws_earbuds This repository shipped the host-side flashing flow and, crucially, the SecondStage bootloader .bin blobs for every BEST variant. That is what ultimately allowed writing code to the Mi Band 10.

Everything BEST1503-specific in this tree (the best1503 HAL variant, the display glue, the touch glue, the corrected memory map) was produced by reverse- engineering the stock Mi Band firmware and cross-checking it against the BEST1306 code, then filling in the gaps.


3. What the SDK does

This is a complete embedded firmware SDK based on the BES kbuild system:

  • Core - ARM Cortex-M33 startup, the RTX5 RTOS, the BES memory pools and heap, the fault handlers and the boot/trace plumbing.
  • HAL - clocks (CMU), timers, GPIO/IOMUX, flash controller, UART, I2C/SPI, PMU and the chip-specific best1503 HAL layer.
  • Boot flow - platform/main/main.cpp brings the chip up, then (in this build) hands control to the on-device hardware self-test, which is where the display, touch and DOOM bring-up live.
  • Linker scripts - scripts/link/best1000_1306.lds.S, driven by the per-chip address map in platform/hal/best1503/plat_addr_map_best1503.h.
  • Target configuration - config/best1503/ selects features, board pins and build options.

The BES2700IHC SDK is an audio SDK; for this watch build the entire audio subsystem is left out (the Mi Band has no audio hardware), which both simplifies the firmware and frees a large amount of flash for the DOOM WAD (see §7 Memory & size).


4. What was recovered by reverse-engineering the stock firmware

The stock Mi Band runs a Vela/NuttX-based image. By analysing it, the following BEST1503-only pieces were reconstructed and wired into the SDK:

Memory map

The BEST1306 headers describe only 512 KB of SRAM (4 × 128 KB banks). The BEST1503 actually has 1.4 MB (0x160000) of contiguous on-chip SRAM - this was confirmed against a RAM dump of the running chip and is now reflected in plat_addr_map_best1503.h (RAM3_SIZE / RAM_TOTAL_SIZE). The flash is 4 MB (the SDK default of 2 MB was corrected in config/best1503/target.mk).

Display - RM690B0/C0 AMOLED

The panel is a Raydium RM690B0/C0 AMOLED (≈212 × 520 visible). It is driven through the BES LCDC SMPN path as a 1-lane HW QSPI command stream:

  • the clock tree and pads are configured exactly as the stock firmware does;
  • a full panel init sequence (CASET/RASET, COLMOD, display-on, brightness) is replayed;
  • frames are pushed as 8 bpp RGB332 (one byte per pixel) over the FIFO with the 0x2C / single-write opcode.

The whole display path was traced out of the stock firmware register-by-register and re-implemented from scratch in platform/main/.

Touch - Hynitron CST92xx

The capacitive touch controller is a Hynitron CST92xx at I²C address 0x5A, bit-banged on GPIO pins 6/7 with an interrupt line on pin 27. The touch report format (event byte, 12-bit packed X/Y, frame marker, ACK-to-refresh) was reverse-engineered and is read directly by the firmware.

The original BES hal_gpio rejects pins ≥ 38; the BEST1503 has many more GPIOs, so register-level GPIO/IOMUX helpers are used instead.


5. DOOM

A port of GBADoom (the doomhack GBA port lineage) lives in apps/doom/. It is gated behind the DOOM=1 build switch so the normal firmware build is unaffected.

What was done to make it run on the BEST1503:

  • Self-contained engine - the engine sources were made independent of their original board SDK; a small glue layer (bes_glue.c, bes_compat.h, lcd.c) bridges DOOM to the BES HAL.
  • Display - DOOM renders an 8 bpp palettised frame; lcd.c converts the active palette to the panel's RGB332 with ordered (Bayer) dithering and blits it to the centre of the AMOLED, with an on-screen control overlay drawn around it.
  • Input - the touchscreen is mapped to DOOM: tap zones around the game image for movement/turn, the centre for fire, and on-screen buttons for use/menu.
  • Timing - DOOM's 35 Hz tick is derived from the BES system timer.
  • Memory - DOOM gets its own dedicated heap above the framebuffer; the 256 KB GBA reciprocal lookup table was dropped in favour of the Cortex-M33 hardware divider, saving flash.
  • The IWAD is embedded directly in flash and read in place (XIP).

6. Building

Requirements (Windows): MSYS2 make 4.4.1 and the arm-none-eabi GCC toolchain (10.3.x) on PATH. A GNUmakefile wrapper drives the SDK build.

# normal watch firmware (no DOOM)
make clean all  T=best1503 CHIP=best1503 DEBUG=1 MAGIC_NUM=1 LIBC_ROM=0 HW_SELFTEST=1

# firmware with DOOM (audio subsystem dropped to make room)
make clean all  T=best1503 CHIP=best1503 DEBUG=1 MAGIC_NUM=1 LIBC_ROM=0 HW_SELFTEST=1 DOOM=1

A bare make builds incrementally and flashes; clean is only run when you ask for it (a from-scratch build is slow). The output image is out/best1503/best1503.bin.

Key build switches (config/best1503/target.mk):

Switch Meaning
T / CHIP always best1503 for this device
HW_SELFTEST=1 build the on-device display/touch/DOOM bring-up
DOOM=1 compile and launch DOOM (drops the audio subsystem)
LIBC_ROM=0 required - the ROM libc thunks hold BEST1306 ROM addresses
MAGIC_NUM=1 bake the boot-header magic

7. Memory & size

Region Size Notes
SRAM 1.4 MB corrected from the SDK's 512 KB
Flash 4 MB corrected from the SDK's 2 MB
Framebuffer 212 × 520, 8 bpp shared panel buffer

The DOOM build drops the entire audio stack (codecs, audio processing, media player, the audio apps and services) because the watch has no audio hardware. Combined with replacing the reciprocal table, this frees roughly 0.7 MB of flash - taking a build that overflowed the 4 MB part back down to ~89 % usage, leaving room for a full IWAD.


8. Flashing

Flashing is done over UART using a Python flasher (flasher/) and the SecondStage bootloader blob recovered from the leaked flasher tool. The single hardest part of this whole project was finding the flasher protocol and the Mi Band test pads / pinout - without the SecondStage .bin from Derek-Vencer/tws_earbuds there was no way in.

Pinout

make flash PORT=COM9        # flash out/best1503/best1503.bin to a serial port

auto_test.py automates a power-cycle + flash + serial-log capture (it uses a Nordic PPK2 for power control); adjust the COM ports and baud at the top of the script to match your wiring. The debug/trace UART runs at 921600 baud.

⚠️ Flashing replaces the stock firmware. Make a full backup of the device flash first, and only do this if you understand the recovery path. This is unofficial, has no warranty, and can brick your device.


9. DOOM controls (touch)

The control zones are drawn on screen around the game image:

  • Tap above / below / left / right of the image - move forward / back, turn left / right (hold to keep moving).
  • Tap the centre (the game view) - fire.
  • Top-left button - START (open / close menu, escape).
  • Top-right button - USE (open doors, confirm menu, start a new game).

To start a game: tap START, then USE to select New Game and the skill.


10. Repository layout

MiBand10_SDK_BES2700IMP_BEST1503_DOOM/
├── platform/        ARM startup, HAL, the best1503 chip layer, main + bring-up
│   └── hal/best1503/plat_addr_map_best1503.h   corrected memory map
├── config/best1503/ target configuration, board pins, feature switches
├── scripts/link/    linker scripts (best1000_1306.lds.S + tail_section)
├── apps/            application modules
│   └── doom/        the GBADoom port + BES glue + embedded IWAD
├── services/        system services (BT host, storage, …)
├── bthost/          Bluetooth host stack
├── rtos/            RTX5 RTOS
├── flasher/         host-side UART flasher + SecondStage bootloader
├── lib/ utils/ thirdparty/  support libraries
├── GNUmakefile      build + flash wrapper
└── Makefile         the SDK build (driven by the wrapper)

11. Videos

Preview Video
MiBand 8 DOOM port Mi Band 8 DOOM port - an earlier DOOM port running on the Mi Band 8.
Mi Band 9 teardown Mi Band 9 teardown - teardown of the Mi Band 9, recorded while it was still in the "no hacking" state.
Mi Band 10 teardown Mi Band 10 teardown - teardown of the Mi Band 10, also recorded under the previous "no hacking" status, which this project now makes obsolete.

12. Sources & credits

The BEST1503-specific HAL, the display/touch bring-up, the corrected memory map, the flashing flow for the Mi Band, and the DOOM port were all developed here by reverse-engineering the stock firmware and adapting the leaked BEST1306 SDK.


13. Disclaimer

This is an independent, unofficial project. It is not affiliated with, endorsed by or supported by Xiaomi or Bestechnic. All trademarks belong to their respective owners. The leaked SDK and tools referenced above are linked for documentation only. Flashing custom firmware can permanently damage your device - proceed entirely at your own risk.

About

Overview of the the Research and Custom Firmware for the MiBand 9 and 10 and its BES2700iMP / BEST1503 SoC and Doom

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors