Firmware

m-bootloader

Loud86/100

MIT clean-room bootloader for the M-VAVE FM-1 and SMK-37 Pro / Elite (JieLi AC791N), and M-Flasher's flash loader

m-bootloader is custom firmware for the M-VAVE FM-1, by @jvitkauskas. Open source under MIT, latest release v1.3 (November 2026), 25 stars on GitHub.

forM-VAVE FM-1·by@jvitkauskas

Unclaimed. Is this yours? Sign in with GitHub as @jvitkauskas to claim it.

Downloads
0
Stars
25
Forks
2
Commits
39
Last commit
Download v1.3

fm1-uboot.fwsc· 17 KB· +7 files

MIT· jvitkauskas/m-bootloader·downloads come from the creator’s GitHub releases

14
Commits
3
Releases
14 commits and 3 releases in the last year
Activity · last 12 months

m-bootloader

An open-source (MIT) bootloader for the M-VAVE FM-1 and SMK-37 Pro / Elite synthesizers (JieLi AC791N), plus the small flash loader that M-Flasher runs on the chip to read and write its flash.

It replaces the bootloader M-VAVE ships, adding a way back into USB download mode and a recovery menu, so a unit with broken or unwanted firmware can be reflashed without opening it. M-VAVE's stock firmware, Snoop37 and Baud Girl run with it.

Features

  • Download mode from the keys. Hold REC (FM-1) or SEQ REC (SMK-37) while switching on. The unit appears on USB in the chip's download mode, ready for M-Flasher.
  • MIDI mode. Reinstall firmware from a browser installer over USB MIDI, including from a phone, with no computer and no firmware running. It's in the recovery menu, which also opens by itself when there's no valid firmware (specification §11.6). The unit reads the package twice, to check it and then to write it, so an installer's progress bar fills about twice as fast as the unit's. Wait for the unit. Tested with SLOOP's, Felucca's, Melodee's and ChoralRoot's installers, from Linux, Android and iOS (the MIDIWeb app), and on the SMK-37 Pro with ChoralRoot's SMK-37 installer from Linux. Baud Girl's installer refuses it, and needs M-VAVE's firmware on the unit. Keep the installer's tab in front, as browsers slow background tabs down. If you stop an install with the menu key or a restart, choose MIDI mode again before an installer's resume button can find the unit. On an SMK-37 Elite, which hasn't been tested, an install this way leaves it reporting itself as a Pro.
  • Recovery menu. Hold PLAY (FM-1) or SEQ PLAY (SMK-37) while switching on. The menu also opens by itself when the firmware cannot start. It shows the firmware's state and size, pending updates and the flash chip, and offers:
    • Boot app and Download mode;
    • Boot anyway: start firmware that fails its checksum, once;
    • Wipe user data: erase the settings areas the firmware declares, and nothing else. The menu lists the exact ranges, and you hold the key for 3 s to confirm.
  • SD card (FM-1). With an m-card board and a FAT32 card fitted, the menu gets an SD card item at the top. It loads and runs /MBOOT/MENU.BIN from the card, which can be any program built for it (docs/SPEC.md §11.5). The card is only touched when the menu is open. This is new and not yet tested on real hardware.
  • Checked start. Every firmware file's checksum is verified before the firmware starts.
  • Firmware updates. M-VAVE's own updater and other firmwares' updaters run as they do with the stock bootloader.
  • Calibration guard (SMK-37). Keeps a copy of the factory calibration and puts it back if it is erased.
  • Flash loader for M-Flasher. Fast reads (about 860 KB/s), an on-chip CRC32 check, checked writes, the flash chip's unique ID, and progress on the unit's own screen.

Status

SMK-37 Protested on hardware: start-up (about 1 s), both keys, every menu action, the calibration guard, an official M-VAVE update, Snoop37 and Baud Girl, all loader operations, installation with M-UPGRADE
SMK-37 Elitesame build as the Pro, with the same flash layout; installation with M-UPGRADE tested with the Elite firmware on an SMK-37
FM-1tested on hardware: start-up, both keys, every menu action, an official M-VAVE update, SLOOP, all loader operations, installation with M-UPGRADE

Build 1.4-ac26c70, with the short configuration, on an FM-1 and an SMK-37 Pro: installing with M-Flasher and M-UPGRADE, stock firmware, putting the stock bootloader back, and Baud Girl. On the FM-1 also official 015 and 016 updates, SLOOP, Felucca, ChoralRoot and Melodee. The SMK-37's own official update has not been run from it. VDDIO has not been measured.

Official M-VAVE updates and Baud Girl's installer put the stock bootloader back, with its full configuration. Reinstall m-bootloader afterwards, with M-Flasher or M-UPGRADE.

Do not install 1.3 or older over this version. They need the configuration it removes, and stop at their menu with BAD CONFIG on every start; Boot app still starts the firmware. Melodee's installer offers 1.2 as an option, so leave that unticked. Reinstalling this version with M-Flasher fixes it.

FAILED -5 from Felucca-family firmware. Melodee's Return to official V15, and M-UPGRADE on an SMK-37 running such firmware, refuse because the boot area differs from the package's. The boot area and firmware stay as they were. Use M-Flasher instead.

Going from FM-1 016 back to 015 leaves garbage presets and wrong pitch, with any bootloader: 016 overwrites the presets once it runs, and official updates do not restore them. Only a backup with the original area does.

Baud Girl overwrites the SMK-37's stock presets. Stock firmware installed afterwards has none, with any bootloader, until a backup with the original area is restored. Back up before installing it.

Not tested on the FM-1's newer flash chip. FM-1s sold from late 2026 have a UCUN UC25HQ80 flash (JEDEC ID 0xB36014) instead of the Puya P25Q80H (0x856014). One such unit did not start after m-bootloader was installed, and the cause is not known yet (M-Flasher #13). Check FLASH CHIP in M-Flasher before installing. With 0xB36014, whether through M-Flasher or M-UPGRADE, install it at your own risk.

Install

Back up your unit with M-Flasher first. Then install the build for your board, smk37-uboot.boot or fm1-uboot.boot from the releases:

m-flasher bootloader --file smk37-uboot.boot

M-Flasher writes only the boot area. It keeps the chip-key record that firmware installers need and drops the rest of the configuration, which the bootloader does not use, for more room (specification §5.3). If the bootloader is ever broken, the USB_KEY dongle still forces the chip into download mode (specification §4.3).

A unit running M-VAVE's firmware enters download mode on a MIDI message, whichever bootloader it has, so a stock unit can be backed up first: the SysEx F0 22 24 35 7D F7 on its first MIDI port (specification §4.2). On Linux, find the port with amidi -l, then amidi -p hw:N,0,0 -S 'F0 22 24 35 7D F7'. M-Flasher sends it with its DOWNLOAD MODE button, from 0.5.0.

With M-VAVE's updater

fm1-uboot.fwsc, smk37-pro-uboot.fwsc and smk37-elite-uboot.fwsc install it with M-VAVE's M-UPGRADE, over USB MIDI, without download mode. The unit has to run firmware that M-UPGRADE can update, such as M-VAVE's, and keeps it.

A package holds no firmware, only our installer (src/installer.c): the unit's firmware stores it and the bootloader starts it. It writes only the bootloader and its boot-area record, shows its progress on the screen, and restarts the unit. M-UPGRADE then waits for an updater that never comes, and times out with an error; the installation is done by then. Tested from M-VAVE's bootloader on an FM-1 (firmware 015) and on an SMK-37 with the Pro and the Elite firmware (016). This version was tested on an FM-1 and an SMK-37 Pro, both on firmware 016, and leaves the same boot area as M-Flasher.

The packages are labelled version 099, as M-UPGRADE refuses the version a unit already has. If it refuses a unit running other firmware, its force upgrade skips the model and version checks.

Build

You need Python 3, GNU Make, Rust and a C compiler, and the pi32v2 LLVM toolchain release pi32v2-23.1.5-2. Nothing from JieLi is needed. On Linux x86-64:

curl -fLo toolchain.tar.xz https://github.com/jvitkauskas/pi32v2-llvm/releases/download/pi32v2-23.1.5-2/pi32v2-llvm-23.1.5-2-linux-x64.tar.xz
echo 'cb896562418a2be93edb9bac26af4bc81a106a32974002a78e6b9fc203c93990  toolchain.tar.xz' | sha256sum -c
mkdir toolchain && tar -xJf toolchain.tar.xz -C toolchain --strip-components=1
cargo install --locked --git https://github.com/exoticorn/upkr --rev a9e56d9d50d1f64cab7590f2c584a12b173e7715 upkr
make

Upkr is the packer that stores stage 1. make UPKR=<path> uses one installed elsewhere. The release also has packages for Linux arm64 and macOS, with their checksums in SHA256SUMS. make TOOLCHAIN=<directory> uses a toolchain unpacked elsewhere.

OutputWhat
build/fm1/uboot.bootbootloader for the FM-1
build/smk37/uboot.bootbootloader for the SMK-37 Pro / Elite
build/fm1/uboot.fwsc, build/smk37/uboot-pro.fwsc, uboot-elite.fwscthe same bootloaders as M-UPGRADE packages; the Elite's differs from the Pro's only in the model name M-UPGRADE checks
build/loader/mflr-loader-a.bin, -b.binflash loader, at RAM 0x01C20000 and 0x01C28000

Builds are reproducible: the same commit and toolchain release give the same bytes. The version shown by the menu and by M-Flasher is VERSION plus the git commit, for example 1.1-e9a25e1. The build fails if an image outgrows its slot.

make test runs the tests: the formats, the loader protocol, and the start-up and menu of both boards on a simulated chip and flash. make sanitize runs them under ASan and UBSan, and make reproducible checks that two builds match. Some tests also use flash images of real units and M-VAVE's packages in testdata/. Those contain M-VAVE's firmware, so they are not in the repository, and the tests skip them when absent.

Source

PathWhat
src/startup.S, src/stage0.cstage 0: entry, power and clock, holding the key for download mode (specification §4.4)
src/boot.cstage 1: start-up decisions, menu
src/midi_update.c, src/usb_midi.cMIDI mode: the update protocol, and the USB-MIDI device
src/core.cflash formats, checksums, ciphers, updater decoding, wipe and calibration rules (portable C, also built for the tests)
src/contract.cwhat the firmware and updaters are handed at start
src/platform.c, src/board.c, src/display.cclock, SPI flash, keys, LEDs, screen
src/loader.c, src/loader_target.cthe flash loader
src/sdboot.cfinding a card, and loading and running /MBOOT/MENU.BIN from it
src/installer.c, src/installer_start.Sthe installer in the .fwsc packages
tools/container and M-UPGRADE package packing, build checks
docs/SPEC.mdthe specification it was written from: hardware, formats and protocols

Clean room

m-bootloader was written from scratch, from a specification of the chip, the flash formats and the protocols (docs/SPEC.md). No code from JieLi's SDK or from the earlier open bootloader went into it. The people who studied the original wrote only the specification, and separate sessions that never saw the original wrote the code.

MIT licence: see LICENSE.