Fixing Linux Suspend on Chromebook by Upgrading EC Firmware

The Problem

I’ve been running Linux on a Lenovo IdeaPad Slim 3 Chromebook (google-magneton), but there’s a critical issue: suspend is broken. Instead of entering sleep mode, the device resets itself. Close the lid, and you lose everything.

The issue is in the EC firmware that ships with the device. It doesn’t disable SRCLKENA0 during suspend, so the EC fails to detect when the system enters S3 sleep state. After a timeout, it assumes the system is hung and sends a SysRq to force a reboot.

dmesg output:

[ 61.794284] EC detected sleep transition timeout. Total sleep transitions: 0

EC logs:

[8664.771400 Handle sleep: 1]
[8674.772800 Warning: Detected sleep hang! Waking host up!]
[8674.773900 event set 0x0000000000080000]
[8674.774900 S0ix suspend sleep hang detected!]
[8674.775800 Consecutive sleep hang count: soft=1 hard=0]
[8674.776900 Warning: Detected sleep hang! Waking host up!]
[8674.792300 HC 0x00a9]
[8674.793300 Handle sleep: 2]
[8674.796700 HC 0x0067 err 9]
[8674.805900 HC 0x0101]
[8674.812000 HC 0x011a]
[8674.813700 HC 0x0133]
[8674.816400 HC 0x0061]
[8675.031200 HC 0x009e]
[8675.100900 HC 0x009e]
[8680.167800 HC 0x009e]
[8684.777400 Sending SysRq to trigger AP kernel panic and reboot!]
[8684.829200 AP will be force reset in 10000ms if hang persists]

The Fix

Build and flash updated EC firmware. The process:

  1. Build EC firmware using ChromeOS SDK
  2. Disable write protection on the device
  3. Disable software sync (prevents ChromeOS from overwriting custom EC firmware)
  4. Flash the new firmware

Prerequisites

Important Warnings

Building EC Firmware

You need the ChromeOS SDK to build EC firmware. It runs in a chroot. I did this on Debian but any Linux distro should work.

# Create workspace
mkdir ~/chromiumos
cd chromiumos

# Initialize repo and sync sources
repo init -u https://chromium.googlesource.com/chromiumos/manifest.git
repo sync -j$(nproc)

Build the firmware for steelix (the EC board for magneton):

./chromite/bin/cros_sdk
cd ../platform/ec
zmake build steelix

Firmware location:

Disabling Write Protection

Check if write protection is enabled:

$ crossystem | grep wpsw
wpsw_cur = 1  # [RO/int] Firmware write protect hardware switch current position
$ flashrom -p ec --wp-status
...
Protection mode: hardware

Enable CCD (Closed Case Debugging)

CCD allows you to modify firmware without opening the case. On the Chromebook (in Developer Mode), press CTRL+ALT+F2 and login as root:

gsctool -a -o

Press the power button when prompted (multiple times over 2-3 minutes). When you see PP Done!, the device reboots into normal mode. Boot back into Developer Mode before continuing.

Disable RO Verification

gsctool -a -I AllowUnverifiedRo:always

Press the power button when prompted during the command execution.

gsctool -a -w disable

Press the power button again when prompted to confirm.

Reboot the EC:

ectool reboot_ec

Unlock EC Write Protection

flashrom -p ec --wp-disable

Verify Everything is Unlocked

All of these checks should pass. If any fail, go back and repeat the previous steps:

$ crossystem | grep wpsw
wpsw_cur = 0  # [RO/int] Firmware write protect hardware switch current position
$ gsctool -a --wp
Getting WP
WP: 00000004
Flash WP: forced disabled
at boot: follow_batt_pres
$ ectool flashprotect
Flash protect flags: 0x00000000
Valid flags:         0x0000083f wp_gpio_asserted ro_at_boot ro_now all_now STUCK INCONSISTENT UNKNOWN_ERROR
Writable flags:      0x00000001 ro_at_boot
$ flashrom -p ec --wp-status
...
Protection mode: disabled

Disable Software Sync

ChromeOS has a feature that automatically overwrites EC firmware on boot to match the system firmware. If you skip this step, custom EC firmware will be replaced on next boot.

futility gbb --set --flash --flags=0x239

This sets the following GBB flags:

The important one is DISABLE_EC_SOFTWARE_SYNC which prevents overwriting custom EC firmware.

Flash EC Firmware

Backup the current firmware first:

flashrom -p ec --read backup.bin

Copy backup.bin to another machine immediately. Don’t store it only on the Chromebook.

Copy the firmware to the Chromebook:

Transfer ec.bin from your build machine to the Chromebook via USB or network.

Firmware location on build machine:

~/chromiumos/src/platform/ec/build/zephyr/steelix/output/ec.bin

Flash the new firmware:

On the Chromebook:

flashrom -p ec --write ec.bin

Reboot the EC:

ectool reboot_ec

The Chromebook will restart with the new firmware.

Results

Suspend works. Close the lid, wait a few seconds, open it - the device wakes up without rebooting. Battery drain during suspend is minimal. The device is now usable as a Linux laptop with working suspend.

This fix was only possible because Chromebooks allow access to low-level hardware through CCD and firmware flashing tools. Without the ability to modify EC firmware, this device would be stuck with broken suspend on Linux. Users should have control over their devices - open hardware access enables fixing bugs that manufacturers won’t address for alternative operating systems.

#chromebook #ec #zephyr #linux