Donate to ensure continued Chromebook + SeaBIOS support.

As well as the costs of infrastructure (mainly the cost of this unmanaged server) for building and serving ROM’s, I could also do with donation toward an example of each chipset of Chromebook. If you have benefited from my work, or want to see an Intel Chromebook supported by the script/firmware which isn’t currently (no guarantee that a particular type of mod will be supported, but I endeavour to get *something* that works), please consider making a donation using one of the buttons in the sidebar.

Thank you.

Pi Zero W Flashrom and USB Gadget Debug

dd Raspbian image to microsd:

dd bs=4M if=2017-03-02-raspbian-jessie.img of=/dev/sdb status=progress

Boot from SD (Pi Zero will not start without it).
Connect to wireless.
Enable SSH on startup:

sudo systemctl enable ssh
sudo systemctl start ssh


Log in over SSH and enable the SPI:

sudo vim /boot/config.txt

and uncomment:


Then reboot.

Install libraries necessary to compile ChromeOS Flashrom:

sudo apt install libpci-dev libfdt-dev libusb-dev libusb-1.0-0-dev

Clone ChromeOS Flashrom master:

git clone

Build it:


Test with:

flashrom/flashrom -V -r backup.rom -p linux_spi:dev=/dev/spidev1.0

USB Debug Gadget

The usual update routine:

sudo apt-get update -y
sudo apt-get upgrade -y

Update the kernel:

sudo rpi-update

Get rpi-source:

sudo wget -O /usr/bin/rpi-source

Make it executable:

sudo chmod +x /usr/bin/rpi-source

Tell the update mechanism that this is the latest version of the script:

/usr/bin/rpi-source -q --tag-update

Get the kernel files thingies:

cd linux

Enable g_dbgp in menuconfig as a module – Device Drivers -> USB Support -> USB Gadget Support -> EHCI Debug Device Gadget:

make menuconfig

Prepare the newly selected module(s) for actual building:

make modules_prepare

Apply updated 4.x EHCI debug patches:

tar -xJf debug_patches.tar.xz
patch -p0 < dbgp.patch
patch -p0 < gadget.patch
patch -p0 < u_serial.patch

Make the modules:

make M=drivers/usb/dwc2
make M=drivers/usb/gadget

Copy them to the relevant places:

sudo for f in $(find drivers/usb/gadget/ -name *.ko); do sudo cp $f /lib/modules/$(uname -r)/kernel/drivers/usb/gadget/ ; done
sudo for f in $(find drivers/usb/dwc2/ -name *.ko); do sudo cp $f /lib/modules/$(uname -r)/kernel/drivers/usb/dwc2/ ; done
sudo for f in $(find drivers/usb/gadget/function -name *.ko); do sudo cp $f /lib/modules/$(uname -r)/kernel/drivers/usb/gadget/function ; done

Run depmod so the modules work:

sudo depmod -a

Enable the dwc2 USB controller driver:

echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt

Reboot. Load the module:

sudo modprobe g_dbgp

Configure the virtual serial device to strip out CR/LF’s to sanitise output:

stty -icrnl -inlcr -F /dev/ttyGS0

Cat that serial device good:

cat /dev/ttyGS0

Switch on the Intel based Chromebook, or other device with coreboot compatible USB debug.

Done. With thanks to Kyösti Mälkki for actually getting the damned thing working. :)

Sources in no particular order:



Tweak which may potentially fix graphics on some devices

I saw an interesting post on the coreboot mailing list this AM, which details a problem with graphics on some AMD Richland CPU’s, which is fixed by disabling threading in SeaBIOS:

to answer this question to myself: It seems like my VGA BIOS was neither working with the A4-5300 APU nor the A10-6700 APU. After debugging the problem over the serial port it turned out that SeaBIOS had multithreading issues and recognized the disks only partially and incorrectly --- which then lead to a boot failure.

To solve this issue, I got the hint on IRC (many thanks!) to apply the following patch (also raises the debug level):

diff --git a/payloads/external/SeaBIOS/Makefile b/payloads/external/SeaBIOS/Makefile
index 4b108d5..10e5aea 100644
--- a/payloads/external/SeaBIOS/Makefile
+++ b/payloads/external/SeaBIOS/Makefile
@@ -37,6 +37,8 @@ checkout: fetch
        cd seabios; git checkout master; git branch -D coreboot 2>/dev/null; git checkout -b coreboot $(TAG-y)
 config: checkout
+       echo "CONFIG_DEBUG_LEVEL=5" >> seabios/.config
+       echo "CONFIG_THREADS=n" >> seabios/.config
        echo "    CONFIG     SeaBIOS $(TAG-y)"
        echo "CONFIG_COREBOOT=y" > seabios/.config

So, I’ve disabled multi-threading in all the builds as a precaution, as I know some people with older models have had occasional graphics problems, and I guess having slightly slower init from SeaBIOS is a small price to pay if it means your machine actually boots! Now, I’m not saying this is definitely the cause of the occasional problems, as I don’t know, and they are completely different CPU’s buy different manufacturers, but it can’t hurt, right?

All’s well that Braswell …


This is another one of those “I bet you haven’t seen this before” moments. Thanks to Matt DeVillier and Aaron Durbin for giving me a sniff at where to start. You will see from the above that’s Grub2 and it’s running on an Acer Chromebook R11 (Braswell).

What works?

  • Display
  • Mouse (at least on Fedora 23)
  • USB booting

What doesn’t work?

  • Text mode display is slow (if you have a big Grub menu like I do, it takes upwards of a minute to draw it and get the timer up).
  • Sound (at least in Fedora 23)
  • eMMC (the controller addresses we have are wrong and I can’t currently find out what they should be, as the cbmem output is truncated to the tune of 23kb, which means we don’t see the sdcard controller addresses, or anything to do with SeaBIOS)
  • Updating the RW_LEGACY slot from within Linux (as the static version of flashrom I currently have isn’t new enough to deal with the SPI chip on the R11)

How did you do it?

As usual, it was a fudge of a few things. First of all I used the ChromiumOS SDK to build the actual RW_LEGACY slot (so it has the correct offset, etc in) “emerge-cyan –nodeps chromeos-seabios” is the pertinent command, which places the resultant RW_LEGACY CBFS at /build/cyan/firmware/seabios.cbfs.serial of the chroot. Then I made a few mods like putting the Baytrail payload in, renaming seavgabios.rom to pci8086,22b1.rom in the CBFS, and removing the links file.

Where can I find the file to try myself?

It’s at, md5sum  c0effe935130bd6b53704b07a9bfc7c1 and you can apply it by running:

flashrom -w -i RW_LEGACY:legacy-seabios-cyan-310316.cbfs

Enabling kinetic scrolling in Fedora 23 on a Chromebook with an Elan touchpad

Apparently, the Synaptics driver was replaced by libinput in Fedora 22, which doesn’t currently support kinetic/inertial scrolling. Here’s how to get it working.

Copy /usr/share/X11/xorg.conf.d/50-synaptics.conf to /etc/X11/xorg.conf.d/51-synaptics.conf, add the following to the bottom, and reboot:

Section "InputClass"
 Identifier "Enable kinetic scrolling for Elan Touchpad"
 MatchProduct "Elan Touchpad"
 MatchDriver "synaptics"
 Option "CoastingSpeed" "20"
 Option "CoastingFriction" "50"

Adjusting Chromebook Keyboard Mapping In Linux

As is usual with computery things, there are many ways to do this. But, this is my preferred method:

sudo touch /etc/udev/hwdb.d/61-keyboard.hwdb
sudo vim /etc/udev/hwdb.d/61-keyboard.hwdb
# Acer Chromebook 15
# Top row keys (between ESC and power button)
# KEYBOARD_KEY_3b=back
# KEYBOARD_KEY_3c=forward
# KEYBOARD_KEY_3d=refresh
# KEYBOARD_KEY_3f=switchvideomode
 KEYBOARD_KEY_db=search # Same position as caps lock key on most keyboards
# KEYBOARD_KEY_3e=fullscreen, no defined key sym

Obviously, you will want to adjust the svn and pn bits, as well as perhaps adjusting what the keys do to your own liking. You can find the correct vendor/part bits in dmidecode output:

sudo dmidecode |less

Then rebuild the hardware db and reboot:

sudo udevadm hwdb --update

Booting Linux under UEFI and Legacy BIOS

The overall problem.

Work have given me a MacBook Pro to use, although they’re not too enamoured at the thought of me putting Linux on the internal SSD. I must haz Linux.

The overall answer.

I had a 128GB M2 SSD in my Acer Chromebook 15 at home, so I purchased a USB M2 SSD enclosure/adapter, with a view to using Linux via it and my SSD on the MacBook Pro, and it being fast.

The problem MKII.

Once I had Linux on said SSD in said enclosure/adapter, and booting on said MacBook Pro, I was unable to boot it on my Acer Chromebook 15 running SeaBIOS. I guess a secondary reason for me wanting the SSD in the enclosure, would be that I could take my OS, boot it “anywhere”, and it would be fast (i.e close to the theoretical maximum of USB 3.0 with very low latency, at least on a device with USB 3.0). The basic problem is that the Mac uses UEFI and the Chromebook uses “legacy” BIOS. Both have differing mechanisms for boot.

The answer MKII.

So, the answer turned out to be putting a “bios_boot” partition on the SSD in the first one meg (obviously not over the mbr and partition table), installing Grub again, and fiddling with the grub config a little. In this way the external SSD boots on both UEFI and Legacy BIOS systems.

How did you do that?

I referenced an article I wrote 5 years ago and did a little sideways thinking:

The commands would be as follows, assuming the internal SSD is /dev/sda and the external SSD/enclosure is /dev/sdb:

  1. Backup the existing first 1 MB of the drive – sudo dd count=2048 if=/dev/sdb of=mbr.gpt.bak
  2. sudo gdisk /dev/sdb
  3. Type n
  4. Type 3 (assuming that partition number is available)
  5. Type 34 (this is the starting sector of the partition we’re creating)
  6. Type 2047 (this takes the partition up to the one meg boundary)
  7. Type ef02 (this makes the partition the “bios_boot” type)
  8. Type w to save and quit.

I then reinstalled Grub to the SSD:

sudo grub2-install --target i386-pc /dev/sdb

For some reason it wouldn’t work without the target specified. Then I had to get around the Grub config.

The primary difference between Linux booted on UEFI, and Linux booted on Legacy BIOS, is the command to load the kernel/initrd. In UEFI this is “linuxefi” and “initrdefi”, in Legacy BIOS it’s “linux” and “initrd”, or “linux16” and “initrd16”. So, the easiest thing to do was create a custom Grub config to deal with booting none UEFI. In /etc/grub.d/40_custom I put:

menuentry 'Fedora (4.2.7-300.fc23.x86_64) 23 (SeaBIOS Mode)' --class fedora --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-4.2.7-300.fc23.x86_64-advanced-a2c26bf5-3f1b-436f-8291-8ee94f8dc7b4' {
 set gfxpayload=keep
 insmod gzio
 insmod part_gpt
 insmod ext2
 set root='hd1,gpt2'
 if [ x$feature_platform_search_hint = xy ]; then
 search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt2 --hint-efi=hd1,gpt2 --hint-baremetal=ahci1,gpt2 a2c26bf5-3f1b-436f-8291-8ee94f8dc7b4
 search --no-floppy --fs-uuid --set=root a2c26bf5-3f1b-436f-8291-8ee94f8dc7b4
 linux /boot/vmlinuz-4.2.7-300.fc23.x86_64 root=UUID=a2c26bf5-3f1b-436f-8291-8ee94f8dc7b4 ro rhgb quiet
 initrd /boot/initramfs-4.2.7-300.fc23.x86_64.img

Then run su -c “grub2-mkconfig > /boot/grub2/grub.cfg” and you will be able to boot Linux both under UEFI *and* Legacy BIOS.

Bear in mind, that if you upgrade the kernel while booted under Legacy BIOS, the prober/autoconfig will automatically change the primary menu options from linuxefi to linux16, so watch out for that.

Also, the usual disclaimers apply – you broke it you bought it, YMMV, etc, etc.

Dual Boot ChromeOS & Linux on a Chromebook

You will need:

  • A Chromebook, obviously (Haswell or Broadwell, although it may also work with older Chromebooks, doesn’t seem to work with Baytrail)
  • 2 or more USB sticks
  • An appropriate distro ISO

Please note – As a result of booting ChromeOS from SeaBIOS, the HWID is not available, therefore ChromeOS will not update. To update, you will need to flash back to the stock BOOT_STUB or use CTRL + D in the case of RW_LEGACY to boot ChromeOS as normal, then instigate an update yourself, and flash the modified BOOT_STUB again if you need to.

If you’ve already flashed your Chromebook to install Linux previously, you will need to flash back to stock, if running a modified BOOT_STUB/Full ROM. You’ll then need to run ChromeOS recovery. If you’ve previously modified your RW_LEGACY slot, it’s worth bearing in mind that ChromeOS Recovery will flash the stock RW_LEGACY, regardless of what state of functionality it leaves you in. In this case you will need to flash the modified RW_LEGACY slot again.

This procedure was tested on an Acer Chromebook 15, and an HP Chromebook 14.

From ChromeOS Crosh shell, we firstly need to resize the stateful partition to make some space for Linux, like so:

sudo cgpt add -i 1 -s 4194304 /dev/sda

Here, we have told cgpt to resize partition 1 to 2 GB in size. This is how you workout what the argument for -s should be:

Size you want in GB * 1024 (gives MB) * 1024 (gives KB) * 1024 (gives bytes) / 512 (to give number of 512 byte sectors). Remember you probably want 8 GB minimum for a Linux install, so on a 16GB eMMC/SSD as comes standard in many Chromebooks, this should be about right.

Next we need to disable rootfs verification, so we can plonk a copy of the ChromeOS kernel into the root of the third partition, for Grub2 to pick up and use, later on:

sudo /usr/share/vboot/bin/ --remove_rootfs_verification --partitions 2

Next, we need to get our copy of the ChromeOS kernel and put it on a USB stick. Warning – although many distro’s contain a “vboot_utils” package, vbutil_kernel doesn’t have the same functionality as in ChromeOS, hence why we need to do it now:

sudo vbutil_kernel --get-vmlinuz /dev/sda2 --vmlinuz-out /media/removable/UNTITLED/chromeos-vmlinuz

Where “UNTITLED” is the label of your USB stick.

We also want a copy of the current boot record and partition layout (this is important so you can boot the “normal” way on occasion, and actually update ChromeOS, otherwise ChromeOS Recovery will like to wipe your disk):

sudo dd bs=1k count=32 if=/dev/sda of=/media/removable/UNTITLED/chromeos-gpt.bak

Now would probably be a good time to reboot, and check the damned thing still works. :)

If appropriate, now is the time to flash the modified BOOT_STUB.  Also, have your Linux Live USB plugged in, then reboot.

Install your distro as normal, but leave the ChromeOS partitions intact. Fedora will insist you create at least 2 partitions – 1 for “biosboot” (an area for Grub to store itself) and another for the system – /dev/sda13 and /dev/sda14 respectively.

Reboot again, and take another copy of the disks partition table as above, but replacing the name appropriately. Then you should copy your vmlinuz file to the root of /dev/sda3.

Now onto configuring Grub. In /etc/grub.d/40_custom add:

menuentry "Chrome OS" {
 insmod part_gpt
 insmod ext2
 set root=(hd0,gpt3)
 linux /vmlinuz root=/dev/sda3 rw noresume noswap i915.modeset=1 loglevel=1 quiet noinitrd tpm_tis.force=1

There’re a couple of important things here. Firstly we want to make sure Grub is loading GPT support (as we’re using ChromeOS’ GPT layout, hence part_gpt). We have to also make sure we refer to the partition as “gpt” as opposed to “msdos”, as would be “normal”, and we’re adding a kernel cmdline option to effectively bypass the TPM. The latter is needed otherwise ChromeOS takes 10 minutes trying to start, using the TPM for user directory encryption. All good fun.

Run update-grub/grub2-mkconfig > /boot/grub2/grub.cfg and reboot again to test the ChromeOS option.

That should be about all that’s needed. If you need to update ChromeOS you will have to flash back the stock BOOT_STUB (if you’re using it), and dd back the chromeos GPT layout, then start ChromeOS normally. Obviously, you need to be careful you do both of those at the same time, otherwise you could leave yourself with a semi-unbootable system which will require wiping with ChromeOS recovery. Conversely, when you have updated, you will need to flash back the modified BOOT_STUB and dd back the distro GPT layout to get back into the dual boot setup.

One more thing, in my attempts to get this working on Baytrial I ascertained that the following commands are needed to bypass the default partition maximum of 8 for MMC devices in Linux:

umount /dev/mmcblk0p[1,3,5]
sudo modprobe -r mmc_blocksudo modprobe mmc_block mmcblk.perdev_minors=32

If anyone wants to pick that up and run with it in terms of getting ChromeOS to actually boot using this dual-boot setup, be my guest.

Compiling static 32-bit ChromeOS Flashrom on Fedora 22 32-bit

Install gcc and ting’:

dnf groupinstall "C Development Tools and Libraries"

Install some required static library dependencies.

dnf install pciutils-devel-static zlib-static libfdt-devel glibc-static

Clone ChromeOS Flashrom master:

git clone
cd flashrom

Make the damned thing:



  • CONFIG_FT2232_SPI=no and CONFIG_DEDIPROG=no are set so that a static libusb dependency isn’t required.
  • CHECK_LIBPCI=no is set because the Makefile seems to have problems detecting where the static version of libpci is.
  • NOWARNERROR=yes is set because of a minor error near the beginning of the compile.

That’s all, she wrote.

New ROM Release – 190915

Apart from automation being an end in itself, I wanted to be able to easily put new SeaBIOS payloads into the firmware mods, and ensure consistency. All the firmware mods now contain the same version of SeaBIOS (from the master branch), the major additional feature (for some models at least) being SD card support.

I expect to make further payload updates as and when salient features become available in SeaBIOS master. When an update is made there will be a small period (probably less than an hour) where the script goes into maintenance mode, and I test the payload on one of each of the last 4 generations of Chromebook (Sandy/Ivybridge, Haswell, Baytrail and Broadwell). Please use the community to direct all feedback.

Patch For

It seems the ChromeOS recovery script isn’t working for me the last few weeks. It fails with:

ERROR: The config file isn't valid.

Looking at the script and config file, it’s because the config file is currently coming in with a line space in each model stanza, which means the script thinks the first and second halves of the stanza are actually separate stanzas.

I fixed it with the following patch:

--- 2014-12-16 04:00:00.000000000 +0000
+++ 2015-09-07 14:53:00.771904673 +0100
@@ -381,6 +381,9 @@
+ *)
+ skipping=yes
+ ;;
 # Between paragraphs. Time to check what we've found so far.

Basically what it’s doing here is saying, “if we don’t find a valid recognised key (or indeed we find an empty line ;) skip that line”. Does the job …

Save the above text to linux_recovery.patch and apply it with:

patch -p0 < linux_recovery.patch

Now, if someone can tell me where to find valid HWID’s, I’d appreciate it, as the config file doesn’t have them any more. Note: this doesn’t fix the script as a whole. Seems to be pretty broken ATM.