MrChromebox scripts: Full ROM firmware for ChromeOS devices
Scripts for setup/install/firmware update for ChromeOS devices
At a glance
- What is it?
- The MrChromebox scripts repository is a set of shell and Python utilities for flashing custom coreboot firmware onto ChromeOS devices, with a device database mapping hardware IDs to boards, a CDN layout that tracks only the current and previous release trains, and a standalone downloader for pulling Full ROM images offline. It has no releases and ships under the Unlicense.
- Who is it for?
- MrChromebox scripts fit a ChromeOS device owner who wants to replace the signed firmware with a custom coreboot build, who has already identified their board in the device database, and who can recover a device with an external programmer if a flash goes wrong.
- Can I use it commercially?
- Yes. Unlicense is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An entry point that downloads and runs the real script
The repository is the home of the ChromeOS Firmware Utility script, and for most users the primary entry point is firmware-util.sh, which automatically bootstraps the Firmware Utility script on the ChromeOS device.
The bootstrap design is deliberate. The entry point is small enough to fetch and run over the network, and it handles script initialisation and dependency checking, downloads the required firmware files and utilities, deals with cross-platform compatibility across ChromeOS, ChromiumOS, and Linux, and then executes the real thing. It also supports optional private deploys by overriding the script_url, in which case the other helper scripts still sync from production.
That last point is a small but important detail for anyone running an internal fork of these scripts. You can point the entry point at your own copy of the main script without having to re-host the device database, the release metadata, or the shared functions, because those still come from the production tree. The repository is therefore usable as a base for a private distribution without forking the whole thing.
The scripts themselves are split by responsibility, and the split is the interesting part of the design. firmware.sh is the main utility and does the actual work. functions.sh holds the core shared functionality, including system detection and device identification, firmware tool path management for flashrom, cbfstool and the gbb-utility among others, Full ROM URL resolution, terminal UI functions and colour codes, and hardware write protection handling. sources.sh holds the release metadata and the firmware source URLs. device-db.sh is the device database itself, and device-db-functions.sh holds the lookups over it.
The scripting language is shell, with Python used for the offline analysis tasks, and the project is distributed under the Unlicense, which is a public domain dedication with no attribution requirement.
The device database is the map of what can be flashed
device-db.sh is described as a comprehensive device database, and the description of its contents is what makes the whole project work.
It holds hardware ID mappings for hundreds of ChromeOS devices, together with device descriptions, CPU platforms, and feature flags, covering devices from Sandy Bridge through the modern platforms. The format of an entry is fixed and documented, as a bracketed hardware ID followed by a pipe separated set of fields.
The format of an entry is a bracketed hardware ID followed by a pipe separated set of fields, `[HWID]="description|CPU|override|flags|"`, and the trailing pipe is part of the format, and the fields are: a description for the board, the CPU platform, an override, and flags. The override is what lets a board be treated as a different board for firmware purposes, which is how a handful of devices are handled. The flags carry the device traits the scripts test for, and device-db-functions.sh provides the flag checking, with names such as isCbox, kbl_rwl18, and others, along with the device lookup, the pattern matching, and the retrieval of descriptions and overrides.
The lookup is a pattern match rather than an exact string match, and it resolves through the longest pattern first. That matters because ChromeOS hardware IDs come in families, with a board identifier and a suffix that varies by variant, and the offline downloader accepts either a ROM slug such as drobit or a full hardware ID string, which it resolves through the database.
The scale of the database is also the maintenance cost. Hundreds of entries have to track the boards the community actually owns, and the three Python scripts in the repository exist precisely to keep that list honest, which is the subject of a later section.
Flashing, rolling back, and what write protection means
firmware.sh is the script that does the work, and its listed capabilities are what separate a firmware tool from a file downloader.
It flashes RW_LEGACY firmware for legacy boot support, and it installs custom coreboot firmware in the Full ROM, UEFI, form. Within that there are three distinct operations. It can install or update to the current Full ROM release, or to a per-board hotfix. It can roll back to the previous Full ROM release, that is the n-1 release, when the device is eligible for it. And it can set boot options and configure firmware settings.
The rollback is the part to read twice, because the eligibility condition is doing the work. The script tracks the current and previous releases only, so the n-1 image is the oldest thing available, and a rollback needs the device to be in a state the script accepts as eligible. For a board that flashed late in a train, the previous release may not be the release it is running.
The hardening is the other detail worth knowing. The script retries once on failure when flashing a Full ROM, and if it still fails it restores /tmp/bios.bin while preserving /tmp/flashrom.log. Preserving the log is the part that matters to you, since the log is the evidence of what went wrong, and the restore is the part that matters to the board, since it puts back the image that was there before the failed attempt.
Write protection is handled in the shared functions, because it is the physical reality that sits underneath all of this. A board with the write protect screw set will refuse the flash, and the script has to detect and explain that rather than fail in a confusing way.
One safety note belongs here even though the README does not phrase it as a warning. This script writes firmware to the mainboard of the device. A failed flash that cannot be recovered with external hardware means a bricked board, and no script in this repository can help you with that case.
The CDN layout, hotfixes, and the flat fallback
sources.sh holds the release metadata and the firmware source URLs, and understanding that file explains how the download and the flash find the right image.
The layout is the interesting part. Production Full ROMs are published under versioned directories, with a path of the form full_rom/MrChromebox-<version>/coreboot_edk2-<board>-mrchromebox_<YYYYMMDD>.rom, so the version is in the path and the build date is in the filename. A concrete example is a URL under the site files directory for a specific version and board.
On top of that there are three rules. The utility tracks the current and previous, n and n-1, releases only, which is why a rollback is limited to the previous train. Per-board hotfixes live at the flat full_rom/ root, with the same filename pattern but the hotfix build date, and they exist to skip a defective current train image for one board. And with fullrom_layout set to versioned, which is the default for production, a missing versioned object may fall back to the flat CDN root.
That flat fallback is what makes the hotfix mechanism work. When a board's image in the current train is bad, the hotfix is published at the flat root with the same filename, and the versioned lookup misses, falls back to the flat root, and finds the hotfix. The value fullrom_layout can also be set to flat for private or test trees, where the versioned directories do not exist.
The file also holds the CDN bases for the Full ROM, the RW_LEGACY images, the boot stubs, the CBFS images, and the utilities, plus the RW_LEGACY and other payload filenames, and the release slots are named as the current and previous trains. The same file carries the optional per-board hotfix overlay under the FW_HOTFIX variable.
The rule to remember is the retention one: two trains and the hotfixes, nothing older is kept on the CDN, which is why an archived install needs the downloader to fetch the image while the train is still current.
The offline downloader, and the quoting rule
download-fullrom.sh is a standalone helper that downloads Full ROM images from the CDN without running the firmware utility, and the README says it is for mirrors, air-gapped installs, and archival.
The argument handling is where most of the care sits. A board argument can be a ROM slug such as drobit, a ChromeOS hardware ID prefix such as DROBIT, or a full hardware ID string, and there is a form that takes a second board argument for a variant.
./download-fullrom.sh drobit
./download-fullrom.sh DROBIT # HWID / board prefix
./download-fullrom.sh "DROBIT C4B-..." # full HWID string
./download-fullrom.sh drobit eve
./download-fullrom.sh --all -o /tmp/romsA pinned release always pulls from the versioned directory and ignores hotfixes.
./download-fullrom.sh 2606.1 drobit
./download-fullrom.sh 2603.2 --allAnd the other options cover listing the available versions, a dry run that prints the URLs only, an explicit output directory, parallel downloads with a default of four, a build date for a train the script does not know, and the help flag.
./download-fullrom.sh --list-versions # current / previous / hotfixes from sources.sh
./download-fullrom.sh -n drobit # dry-run (print URLs only)
./download-fullrom.sh -o /tmp/roms drobit
./download-fullrom.sh -j 8 --all # parallel downloads (default: 4)
./download-fullrom.sh 2501.0 -d 20250115 drobit # unknown train: pass build date
./download-fullrom.sh -hTwo behaviours are worth memorising. The default output directory is ./MrChromebox-<version>, which for an unpinned latest download is the current train version from sources.sh. And --all keeps going after individual failures, with a -k flag for the same behaviour with an explicit board list, because a mirror job that aborts on the first missing board is useless.
The quoting rule is the one that saves you a confusing afternoon. Full hardware ID strings should be quoted so the shell does not split on spaces or expand glob characters, and the README names the characters explicitly. Unquoted, a hardware ID containing a question mark or a bracket becomes a glob pattern, and the script will search the filesystem for it instead of looking it up in the database.
The Python scripts that keep the device list honest
Three Python scripts handle the parts of the job that are not about flashing, and between them they are the maintenance half of the project.
identify_missing_firmware.py finds boards in the device database that have no published UEFI Full ROM on the CDN. It parses device-db.sh for ROM slugs, honouring the overrides and skipping the entries marked noUEFI, checks the current versioned release path from sources.sh with the flat root fallback, and writes a missing_firmware.txt grouped by platform. In other words, it answers the question of which boards in the database are not yet flashable, which is the list the maintainers work from.
sync_db_to_json.py propagates updates to the website device list. It analyses the hardware ID prefixes in device-db.sh, compares them with the devices.json file the website uses, and updates the JSON with missing hardware ID and board name entries. The two files have to agree, and a script is a better way to keep them in agreement than a person editing JSON by hand.
update_db_from_recovery.py works from the other direction, pulling from ChromeOS itself. It downloads the ChromeOS recovery configuration from Google, parses recovery.conf to extract device metadata, and generates or updates device database entries with hardware IDs and firmware information. That is the path that adds new boards, and it means the database is built from Google's own recovery metadata rather than from a list someone typed out.
There is also setup-kodi.sh, which is explicitly a legacy script that is no longer supported. It redirects users to the main Firmware Utility script and is kept as a historical reference for Kodi installation on ChromeOS devices.
On the project itself, the repository has no GitHub releases, the last push was on 2026-10-19, and the licence is the Unlicense, which places the scripts in the public domain. The main site is mrchromebox.tech, and the top level of the repository is exactly the set of scripts described here with no build system in between, which is what you would expect from a tool that is copied to a device and run there rather than compiled and installed.
Editorial conclusion
MrChromebox scripts fit a ChromeOS device owner who wants to replace the signed firmware with a custom coreboot build, who has already identified their board in the device database, and who can recover a device with an external programmer if a flash goes wrong. It does not fit a ChromeOS user who wants the stock system, and it does not fit an air-gapped installer who needs an image from a train older than the previous release, because only the current and previous trains and per-board hotfixes are kept. Verify first that your hardware ID appears in device-db.sh and that a Full ROM exists for that board, that you know how to recover a device with a failed flash, and that you read the rollback section of the documentation, since the n-1 rule decides whether a return to the previous release is even possible for your board.
Frequently asked questions
What does firmware-util.sh do in the MrChromebox scripts?
It is the entry point script that downloads and executes the main firmware utility. It handles script initialisation and dependency checking, downloads the required firmware files and utilities, supports ChromeOS, ChromiumOS and Linux, and can be pointed at a private deploy by overriding script_url while the other helpers still sync from production.
How do I download a Full ROM image without flashing the device?
Use the standalone download-fullrom.sh helper, which fetches images from the CDN without running the firmware utility. Pass a board slug such as drobit, a hardware ID prefix, or a quoted full hardware ID string, and use a version argument such as 2606.1 to pin a specific train.
Can I roll back to the previous firmware release?
Yes, when the device is eligible. The utility tracks only the current and previous, n and n-1, releases, so the previous train is the oldest image it can restore, and the rollback only applies to a device whose current state qualifies.
What are the per-board hotfixes in the MrChromebox firmware CDN?
They are Full ROM images published at the flat full_rom/ root with the same filename pattern and the hotfix build date, and they exist to skip a defective current train image for a particular board. With the default versioned layout, a missing versioned object falls back to the flat CDN root, which is how the hotfix is found.
Why should I quote full hardware ID strings when using download-fullrom.sh?
Because an unquoted hardware ID containing spaces or glob characters would be split by the shell or expanded as a glob, so the script would search the filesystem instead of resolving the board through the device database. The README names the characters to watch for, including the asterisk, the question mark, and square brackets.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mrchromebox-scripts)Was this useful?