Flashrom @ Chromium.org
[ Public ]
(non-public documentation is obsolete)
Chromium OS currently uses Flashrom as the userspace tool of choice for firmware updates on x86 and ARM. Flashrom is an open-source, cross-platform EEPROM programming utility with an active community and a large combination of supported host chipsets, flash memory devices, and external programmers.
In addition to having a very adaptable hardware model, Flashrom is very versatile from a software standpoint. It can target different ROMs in the same system. It can perform partial updates to the ROM image. It can manipulate write protection settings for specific chips.
The code is generally adaptable to a wide variety of chipsets and interfaces and is thus a good candidate for servicing the needs of Chromium OS platforms.
Flashrom main URL: http://www.flashrom.org
Document short URL: http://goo.gl/i5sMq
Anonymous download: git clone http://git.chromium.org/chromiumos/third_party/flashrom.git
Developer download: git clone ssh://gerrit.chromium.org:29418/chromiumos/third_party/flashrom.git
Read the Chromium OS Developer Guide for information about how to manage public keys to avoid annoying interactive password prompts.
This document is licensed under a Creative Commons Attribution 3.0 Unported License.
Feel free to copy, modify, and distribute this document however you see fit. Attribution goes to the Flashrom Community.
In Sept. 2014, a more friendly userguide can be found here: https://sites.google.com/a/chromium.org/dev/chromium-os/packages/cros-flashrom
The info below is a more verbose and is somewhat outdated, but can still be a useful reference.
Before we get started, keep in mind the following:
For these examples, we assume the x86 firmware ROM is connected directly to the host via SPI and the EC ROM is connected via the EC to LPC. The following diagram illustrates this relationship:
Let’s assume we wish to read the x86 and EC firmware ROMs:
flashrom -p internal:bus=spi -r bios.bin # read x86 firmware
flashrom -p internal:bus=lpc -r ec.bin # read EC firmware
Similarly, to write the x86 and EC firmware ROMs (assume write-protection disabled):
flashrom -p internal:bus=spi -w bios.bin # write x86 firmware
flashrom -p internal:bus=lpc -w ec.bin # write EC firmware
If any section of the ROM is hardware write-protected, we must specify writeable regions for Flashrom to target. Let’s assume we have a 4MB x86 BIOS ROM that is divided into a writeable lower half and a write-protected upper half. To write to the lower 2MB of the 4MB BIOS ROM (address 0x000000 to 0x1fffff):
echo “0x000000:0x1fffff lower” > layout.txt
flashrom -p internal:bus=spi -l layout.txt -i lower -w bios.bin
A full listing of command-line options can be seen by using the -h or --help. This section focuses on options we’ll be using in this document.
The following switches are in mainstream flashrom. The -l and -i options will be explained in the ROM Layout section below.
-r | --read read flash and save to
-w | --write write to flash
-p | --programmer <name>[:<param] specify the programmer device and parameters
These two options have to do with partial updates and are necessary for working with write-protected ROMs. See “ROM Layout and Write Protected ROMs” for more details.
-l | --layout read ROM layout from <file>
-i | --image <name> flash image <name> from flash layout
These have been added for Chromium OS to help work with our write-protected ROM model. They are long-options only.
--wp-status show write protect status
--wp-range set write protect range
--wp-enable enable write protection
--wp-disable disable write protection
(aka Partial Writes & You)
All production Chromium OS machines and most development machines have hardware write-protection enabled by default. Please refer to your hardware’s documentation for details.
Write-protection status can be determined by using the “--wp-status” option. Here is an example of how to read the write-protection status:
localhost ~ # flashrom -p internal:bus=spi --wp-status 2>/dev/null
Found chip "Winbond W25Q32" (4096 KB, SPI) at physical address 0xffc00000.
WP: status: 0x98
WP: status.srp0: 1
WP: write protect is enabled.
WP: write protect range: start=0x00200000, len=0x00200000
This tells us that bytes 0x200000 thru 0x3fffff are write-protected.
The Flashrom page on chromium.org has a nice tutorial on how to work with specific regions of flash: https://sites.google.com/a/chromium.org/dev/chromium-os/packages/cros-flashrom#TOC-Partial-Reads-and-Writes
Experimental support for Dediprog SF100 programmers is available using “-p dediprog” command line argument.
Note: Support was added by reverse engineering Dediprog’s protocol. It is not officially supported by Dediprog and may cause damage (we’ve bricked a few SF100’s already).
Bus Pirate is a preferred choice the USB/SPI programmers since it is entirely open. Command usage and additional info is available here: http://www.flashrom.org/Bus_Pirate
Flashrom is typically run interactively. For our purposes we use an alternate CLI oriented toward automated usage, “cli_mfg,” instead of the default “cli_classic.” Here are the differences:
Chrome OS devices keep the BIOS and EC firmware ROMs separate. This means that a single programmer, ie an x86 “southbridge,” may have multiple targets. On current-generation x86 platforms, they may be selected by switching the “Boot BIOS straps” bit.
For Flashrom, we added a command-line option to select target on-the-fly, “-p internal:bus=”. For example:
flashrom -p internal:bys=spi -r /tmp/spi_rom.bin # read from SPI
flashrom -p internal:bus=lpc -r /tmp/lpc_rom.bin # read from LPC
Information about the latest testing script, dubbed test_v2.sh, is available here: https://docs.google.com/document/d/1IoBR7rHXJFiahC6dGnNKqaNFfg-q89_NMHuFyiJ7JnA/edit#heading=h.nq3kh8uu03di
Whenever possible, it is preferred that you develop in the open source project community. When submitting code, send the patch (usually a unified diff) via e-mail to firstname.lastname@example.org. It can be helpful to add [PATCH] to the beginning of the subject line in the e-mail so people know to expect a code review. For example: “[PATCH] Add Foobar support”. Submit the patch “in-line” so that people reading the e-mail can quote and respond to specific lines of code more easily.
The Flashrom community uses the Developer’s Certificate of Origin procedure the same as the Linux kernel community [ More Information ]. This means appending “Signed-off-by: email@example.com” to patches to ensure proper release of ownership to the open source community.
Patchwork has been set up for Flashrom and is available for your code reviewing pleasure here: http://patchwork.coreboot.org/project/flashrom/list/
This repository exists for two main reasons:
In general, this repository will allow us to make UI changes needed for our factory install process and system update scripts as well as architectural needed to support new chips.
Synchronizing Google’s flashrom repo with the mainstream git repo requires the use of “git svn” to preserve history between mainstream Flashrom’s SVN repo and our git repo. This will allow us to merge without conflicts since the history of both the mainstream repo and the chromium.org repo will concur.
# You may need to run “git svn init” to make sure we have the full mainstream repository’s history in a tracking repository.
# This step may fetch the entire mainstream repository’s history, starting at r1.
$ git svn init -T trunk svn://coreboot.org/flashrom
# This should update remotes/trunk
$ git svn fetch
$ git checkout -b “merge” cros/master
$ git merge remotes/trunk # resolve conflicts
# push to master
$ git push --dry-run ssh://gerrit.chromium.org:29418/chromiumos/third_party/flashrom.git HEAD:refs/heads/master (remove --dry-run if things look good)
todo: fill this in
The blackbox unit tests are for regression testing. They assume that the version of flashrom that is installed in the system-wide path, e.g. /usr/sbin/flashrom, is in working order.
The unit test scripts are broken up into two parts:
The basic invocation is:
There are some some environment variables which need to be set:
FLASHROM: Mandatory, path to the Flashrom binary to test (e.g. /tmp/flashrom)
FLASHROM_PARAM: Optional, parameters to pass in (e.g. -p internal:bus=lpc)
The do_tests.sh script does the following:
All tests create their own logfiles (test_name.sh.log). The temporary files are not deleted since it can be useful to compare results between different trials.
Note about destructive tests (those involving erase/write operations): Some scripts have additional environment variables which must be set. For example, some devices require that you specify an “alternate” image to test with. Typical examples include embedded controllers (ECs) which run code out of ROM, and thus cannot be left with an invalid image. So the alternative image could be an old version of the firmware. This allows Flashrom to test its erase and write logic and leave the ROM image in a usable state.