cros ec: Difference between revisions

From cabochon
Jump to navigationJump to search
No edit summary
No edit summary
 
(7 intermediate revisions by 2 users not shown)
Line 12: Line 12:


In most cases, EC has a separate SPI flash divided into two parts: EC_RO and EC_RW. EC_RO is supposed to be only written by the factory, while EC_RW updates get shipped within coreboot.rom, and flashed on runtime if the hash mismatches. ''this behavior is actually quite complicated and should be explored deeper, especially around softbricks due to newer EC_RW version than the one in coreboot''
In most cases, EC has a separate SPI flash divided into two parts: EC_RO and EC_RW. EC_RO is supposed to be only written by the factory, while EC_RW updates get shipped within coreboot.rom, and flashed on runtime if the hash mismatches. ''this behavior is actually quite complicated and should be explored deeper, especially around softbricks due to newer EC_RW version than the one in coreboot''
== Compilation ==
Note: The following instructions were tested by compiling for morphius on Debian Trixie, but should generally apply to most distros and most boards using the legacy EC.
<syntaxhighlight lang="shell-session">
# Install build deps
sudo apt install git gawk make pkg-config libftdi-dev libncurses-dev libusb-1.0-0-dev gcc gcc-arm-none-eabi
# Clone the source
git clone https://chromium.googlesource.com/chromiumos/platform/ec
cd ec
# You usually want to check out the specific branch used for your device as the main branch tends to be broken
# Check for firmware-<baseboard>-* branches
git checkout firmware-zork-13434.B-master
# Build the firmware
make -j$(nproc) BOARD=morphius CROSS_COMPILE_arm=arm-none-eabi-
</syntaxhighlight>
You may run into some compiler errors as the version of gcc will be much newer than what the code was intended to be compiled with. Some of these can be fixed by changing -Werror to -Wno-error in Makefile.toolchain.
In case compilation fails on a util, such as iteflash, you can skip compiling the host utils by specifying the build target. Add build/<board>/ec.bin to the make command.
== Zephyr EC Compilation ==
TODO


== Common misconceptions ==
== Common misconceptions ==
Line 18: Line 45:


Cr50 is a completely separate chip on the board. This is why in most cases you can recover a bad EC flash with a SuzyQ cable; Cr50's firmware never gets touched outside the factory.
Cr50 is a completely separate chip on the board. This is why in most cases you can recover a bad EC flash with a SuzyQ cable; Cr50's firmware never gets touched outside the factory.
== Variants ==
=== cros_fp ===
The fingerprint MCUs used in chromebooks also run cros_ec firmware. These builds are slimmed down and include proprietary components for fingerprint matching and sensor drivers. It is unknown whether the firmware can be replaced or modified.
There are several different chips/firmwares used for cros_fp, such as bloonchipper(hatch_fp) and dartmonkey(nami_fp/nocturne_fp) (Bloons TD references).
=== cros_pd ===
The USB PD chips on some/all(?) chromebooks run cros_ec firmware. The main ec communicates with the PD chips for firmware updates and control. Coreboot on some boards will expose cros_pd to the os.
=== cros_scp ===
The SCP is a MCU on Mediatek chips. On chromebooks, this runs cros_ec firmware. The SCP handles functions such as video processing, power management, sleep, and others. The firmware for this lives in /lib/firmware/mediatek/$SOC/scp.img and is loaded on boot by the kernel driver.
=== cros_ish ===
ISH stands for Intel Sensor Hub, which sort of acts like an ec. This variant is most likely only used on Intel reference boards as all recent chromebooks have a dedicated ec.
=== cros_tp ===
This variant is used by the Google Pixelbook(eve)'s touchpad (rose). It simply communicates with the touchpad and os to communicate input events. The firmware can be upgraded via Google's flashrom fork. It is unknown if this is used in other chromebook models.
=== Hammer ===
On chromebooks with a detachable keyboard, the keyboard runs a firmware called Hammer, which is cros_ec. There are several hammer variants, which are bland, don, duck, eel, gelatin, hammer, jewel, magnemite, masterball, moonball, staff, star, wand, whiskers, whitebeard, zed. The firmware can be update via ChromeOS, it is unknown how to manually update though.
=== Cr50 ===
Cr50 is the firmware that runs on the first generations of the Google Security Chip ([[GSC]]), the H1 (H1B2C/H1B3C). This runs a heavily modified version of cros_ec, with some proprietary components. The firmware is signed and will not load unsigned firmware, if you can even get it on the chip. The second generation GSC (D2/H1D2C) runs Ti50 firmware. According to questionable sources, this firmware is half cros_ec and half rust (another victim of rewrite in rust). This firmware is also mostly proprietary, with only a few references to Ti50 in Cr50.
== Flashing with stm32mon ==
On models where cros_ec lives in an STM32, there are multiple ways to flash the chip. If <code>flashrom -p raiden_debug_spi:target=EC</code> doesn't work for you (or selects the wrong chip), and you can't / don't want to boot the machine to run <code>flashrom -p ec</code> internally, using stm32mon may be of interest. This method requires SuzyQ, or a probe soldered directly onto the board; Instructions below use the SuzyQ.
# Make sure you've unlocked full access to EC (<code>gsctool -a -o</code>) and set the feature flags to "Always" on ttyUSB0 (GSC)
# Run the following on the [[GSC]] console: <syntaxhighlight>
  ecrst on
  gpioset EC_FLASH_SELECT 1
  bitbang 2 57600 even
  ecrst pulse
  </syntaxhighlight>
# Run stm32mon pointing to the 3rd console (EC, usually ttyUSB2): <code>./stm32mon --device=/dev/ttyUSB2 -c</code>. An example invocation that dumps the EC (which you should do before messing about) is <code>./stm32mon --device=/dev/ttyUSB2 -c -r testread.bin</code>
It does not appear that you need to repeat those steps for subsequent commands, chip should be held in the flashing state until you run <code>reboot</code> on GSC, which reboots the EC.
=== Troubleshooting ===
If your stm32mon is misbehaving like this:
<syntaxhighlight>
./stm32mon version: no_version  brady@epicserver
Waiting for the monitor startup ...Timeout
Timeout
Done.
NACK
Failed to get command GETID ACK
--
RESP_ACK          1
RESP_NACK          1
RESP_BUSY          0
RESP_DAMAGED_ACK  0
JUNK              0
--
Failed: -1
</syntaxhighlight>
* Check the selected port
* Double check whether all GSC commands succeeded
* Run <code>ecrst pulse</code>, this should return the chip to a sane state
* sometimes stm32mon needs a ^C and it will work the next time? it's a weird creature
* if it fails half-way through, add <code>-u</code> (Flash WP Unlock) to the command
== Flashing with uartupdatetool (Nuvoton) ==
Like above, those notes imply SuzyQ. Rough steps on how to get an image flashed:
# build ec
# get uartupdatetool from build util dir
# get npcx_monitor.bin from build chip/npcx/spiflashfw dir
# get ec.bin from build dir
# connect to gsc uart (usually <code>/dev/ttyUSB0</code>), run: <syntaxhighlight>
  gpioset EC_TX_CR50_RX_OUT 0
  ecrst pulse
  </syntaxhighlight>
# read the flash: <code>./uartupdatetool --port=ttyUSB2 --baudrate=115200 --read-flash --file=ec.bin</code>

Latest revision as of 00:18, 28 October 2025


note: this page is a stub. someone should help me by expanding it

cros_ec, the Embedded Controller or just EC for short, is a microcontroller present on all Chromebook models. It handles power states, battery charging, LEDs (including the keyboard backlight), sensors, and some input devices. Depending on the platform, it can have several additional tasks; for instance, on some Zork boards, it also handles the microphone.

Unlike conventional laptops, cros_ec's firmware is fully open source. The first version is easily buildable given a generic arm-none-eabi toolchain (and a few trivial source patches, if you're building on plain Linux); Newer boards switched to Zephyr RTOS, which at the present requires a ChromeOS chroot.

Architecture

Based on chips by a variety of manufacturers, including Nuvoton and ITE. (expand this list please)

In most cases, EC has a separate SPI flash divided into two parts: EC_RO and EC_RW. EC_RO is supposed to be only written by the factory, while EC_RW updates get shipped within coreboot.rom, and flashed on runtime if the hash mismatches. this behavior is actually quite complicated and should be explored deeper, especially around softbricks due to newer EC_RW version than the one in coreboot

Compilation

Note: The following instructions were tested by compiling for morphius on Debian Trixie, but should generally apply to most distros and most boards using the legacy EC.

# Install build deps
sudo apt install git gawk make pkg-config libftdi-dev libncurses-dev libusb-1.0-0-dev gcc gcc-arm-none-eabi

# Clone the source
git clone https://chromium.googlesource.com/chromiumos/platform/ec
cd ec

# You usually want to check out the specific branch used for your device as the main branch tends to be broken
# Check for firmware-<baseboard>-* branches
git checkout firmware-zork-13434.B-master

# Build the firmware
make -j$(nproc) BOARD=morphius CROSS_COMPILE_arm=arm-none-eabi-

You may run into some compiler errors as the version of gcc will be much newer than what the code was intended to be compiled with. Some of these can be fixed by changing -Werror to -Wno-error in Makefile.toolchain.

In case compilation fails on a util, such as iteflash, you can skip compiling the host utils by specifying the build target. Add build/<board>/ec.bin to the make command.

Zephyr EC Compilation

TODO

Common misconceptions

  • cros_ec != Cr50/Ti50 != SuzyQ

Cr50 is a completely separate chip on the board. This is why in most cases you can recover a bad EC flash with a SuzyQ cable; Cr50's firmware never gets touched outside the factory.

Variants

cros_fp

The fingerprint MCUs used in chromebooks also run cros_ec firmware. These builds are slimmed down and include proprietary components for fingerprint matching and sensor drivers. It is unknown whether the firmware can be replaced or modified.

There are several different chips/firmwares used for cros_fp, such as bloonchipper(hatch_fp) and dartmonkey(nami_fp/nocturne_fp) (Bloons TD references).

cros_pd

The USB PD chips on some/all(?) chromebooks run cros_ec firmware. The main ec communicates with the PD chips for firmware updates and control. Coreboot on some boards will expose cros_pd to the os.

cros_scp

The SCP is a MCU on Mediatek chips. On chromebooks, this runs cros_ec firmware. The SCP handles functions such as video processing, power management, sleep, and others. The firmware for this lives in /lib/firmware/mediatek/$SOC/scp.img and is loaded on boot by the kernel driver.

cros_ish

ISH stands for Intel Sensor Hub, which sort of acts like an ec. This variant is most likely only used on Intel reference boards as all recent chromebooks have a dedicated ec.

cros_tp

This variant is used by the Google Pixelbook(eve)'s touchpad (rose). It simply communicates with the touchpad and os to communicate input events. The firmware can be upgraded via Google's flashrom fork. It is unknown if this is used in other chromebook models.

Hammer

On chromebooks with a detachable keyboard, the keyboard runs a firmware called Hammer, which is cros_ec. There are several hammer variants, which are bland, don, duck, eel, gelatin, hammer, jewel, magnemite, masterball, moonball, staff, star, wand, whiskers, whitebeard, zed. The firmware can be update via ChromeOS, it is unknown how to manually update though.

Cr50

Cr50 is the firmware that runs on the first generations of the Google Security Chip (GSC), the H1 (H1B2C/H1B3C). This runs a heavily modified version of cros_ec, with some proprietary components. The firmware is signed and will not load unsigned firmware, if you can even get it on the chip. The second generation GSC (D2/H1D2C) runs Ti50 firmware. According to questionable sources, this firmware is half cros_ec and half rust (another victim of rewrite in rust). This firmware is also mostly proprietary, with only a few references to Ti50 in Cr50.

Flashing with stm32mon

On models where cros_ec lives in an STM32, there are multiple ways to flash the chip. If flashrom -p raiden_debug_spi:target=EC doesn't work for you (or selects the wrong chip), and you can't / don't want to boot the machine to run flashrom -p ec internally, using stm32mon may be of interest. This method requires SuzyQ, or a probe soldered directly onto the board; Instructions below use the SuzyQ.

  1. Make sure you've unlocked full access to EC (gsctool -a -o) and set the feature flags to "Always" on ttyUSB0 (GSC)
  2. Run the following on the GSC console:
      ecrst on
      gpioset EC_FLASH_SELECT 1
      bitbang 2 57600 even
      ecrst pulse
  3. Run stm32mon pointing to the 3rd console (EC, usually ttyUSB2): ./stm32mon --device=/dev/ttyUSB2 -c. An example invocation that dumps the EC (which you should do before messing about) is ./stm32mon --device=/dev/ttyUSB2 -c -r testread.bin

It does not appear that you need to repeat those steps for subsequent commands, chip should be held in the flashing state until you run reboot on GSC, which reboots the EC.

Troubleshooting

If your stm32mon is misbehaving like this:

./stm32mon version: no_version  brady@epicserver
Waiting for the monitor startup ...Timeout
Timeout
Done.
NACK
Failed to get command GETID ACK
--
RESP_ACK           1
RESP_NACK          1
RESP_BUSY          0
RESP_DAMAGED_ACK   0
JUNK               0
--
Failed: -1
  • Check the selected port
  • Double check whether all GSC commands succeeded
  • Run ecrst pulse, this should return the chip to a sane state
  • sometimes stm32mon needs a ^C and it will work the next time? it's a weird creature
  • if it fails half-way through, add -u (Flash WP Unlock) to the command

Flashing with uartupdatetool (Nuvoton)

Like above, those notes imply SuzyQ. Rough steps on how to get an image flashed:

  1. build ec
  2. get uartupdatetool from build util dir
  3. get npcx_monitor.bin from build chip/npcx/spiflashfw dir
  4. get ec.bin from build dir
  5. connect to gsc uart (usually /dev/ttyUSB0), run:
      gpioset EC_TX_CR50_RX_OUT 0
      ecrst pulse
  6. read the flash: ./uartupdatetool --port=ttyUSB2 --baudrate=115200 --read-flash --file=ec.bin