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 https://chromium.googlesource.com/chromiumos/third_party/flashrom
cd flashrom

Make the damned thing:

make CONFIG_FT2232_SPI=no CONFIG_DEDIPROG=no CONFIG_STATIC=yes CHECK_LIBPCI=no NOWARNERROR=yes

Note:

  • 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.

EHCI Debug Gadget & ChromeOS Flashrom on BBB in Arch Linux

su root
cd

EHCI Debug Gadget

pacman -Syu wget
reboot
wget http://www.coreboot.org/images/8/88/Ehci-debug-gadget-patches.tar.gz
tar -xzf Ehci-debug-gadget-patches.tar.gz
cp usbdebug-gadget/g_dbgp.ko /lib/modules/`uname -r`/kernel/drivers/usb/gadget
cat /dev/ttyGS0

ChromeOS Flashrom

pacman -Syu git make gcc dtc
git clone https://chromium.googlesource.com/chromiumos/third_party/flashrom -b firmware-nyan-5771.B
cd flashrom
make CONFIG_SATAMV=0 CONFIG_LINUX_I2C=yes NOWARNERROR=yes CONFIG_LINUX_SPI=yes
cd
echo BB-SPIDEV0 > /sys/devices/platform/bone_capemgr/slots
flashrom/flashrom -p linux_spi:dev=/dev/spidev1.0

 

Procedure for building ChromeOS Flashrom on BeagleBone Black

Why do this? – Because you want to try to make sure you have a version of flashrom that will recognise all Chromebook SPI chips. Also, you may just want to write an area of the ROM instead of the whole thing (such as BOOT_STUB or RW_LEGACY) and upstream Flashrom doesn’t allow you to do that.

Before beginning you will need to make sure your BBB is connected to the internet. If you’re connecting using the micro-USB cable, you will need to do some network setup. On the computer the BBB is attached to run:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -s 192.168.7.0/24 -o wlp1s0 -j MASQUERADE

Where wlp1s0 is the name of the internet connected interface on the BBB attached computer.

On the BBB run:

route add default gw 192.168.7.1

Also make sure you have a valid DNS server/forwarder entered in /etc/resolv.conf (nameserver=) and that you run ntpdate to make sure the BBB’s time and date are correct (for validation of HTTPS certs, and also making sure any rebuilds get done properly due to modification time) e.g.

ntpdate ntp0.esat.net

Install essential dependencies:

apt-get install build-essential libpci-dev libfdt-dev

Clone a suitable branch of the ChromeOS Flashrom repo (I chose this one as a reasonably new ARM Chromebook’s Flashrom, so hopefully it’s quite up to date):

git clone https://chromium.googlesource.com/chromiumos/third_party/flashrom -b firmware-nyan-5771.B

Change into the flashrom directory and run:

make CONFIG_SATAMV=0 CONFIG_LINUX_I2C=yes NOWARNERROR=yes CONFIG_LINUX_SPI=yes

Follow the “spidev” setup instructions from https://blogs.fsfe.org/the_unconventional/2015/06/08/setting-up-a-beaglebone-black-to-flash-coreboot/

Reboot, and from your home directory run:

flashrom/flashrom -p linux_spi:dev=/dev/spidev1.0

You will getting an error about the EEPROM, but that means it’s working, believe it or not. :D

Test with a command such as:

flashrom/flashrom -p linux_spi:dev=/dev/spidev1.0 -w -i BOOT_STUB:some_boot_stub.cbfs

I’m not sure if “enjoy” is the right word.

Procedure to get sound working in Fedora 22 on ASUS C300 Chromebook

This will probably work with other distro’s/Baytrail Chromebook models.

  1. Get to a terminal.
  2. Type “alsamixer”.
  3. Press the brightness down key AKA F6.
  4. Find “Left Speaker Mixer Left DAC” and press “m” to unmute.
  5. Find “Right Speaker Mixer Right DAC” and press “m” to unmute.
  6. Update your distro to hopefully as new a kernel as possible (mine went to 4.1.4-200). This ensures that the sound card has the latest available firmware.
  7. Reboot.
  8. Enjoy shiny (and possibly slightly dodgy) sound.

Build Your Own Baytrail BOOT_STUB

You’ll need git, gcc, ncurses-devel, iasl and possibly other tools installed.

Presumably from your home directory, run:

git clone https://github.com/KevinOConnor/seabios.git -b baytrail-testing baytrail-seabios

to download Kevin O’Connor’s Baytrail specific SeaBIOS sources. Change into the baytrail-seabios directory:

cd baytrail-seabios

Create a valid .config, and build:

echo -e 'CONFIG_COREBOOT=y\n# CONFIG_HARDWARE_IRQ is not set' > .config
make olddefconfig
make

and download the shellball for your device:

export MODEL=your_model_name
mkdir ${MODEL}
cd ${MODEL}
lftp https://johnlewis.ie/Chromebook-ROMs/shellballs/${MODEL}
mirror

Now we are going to prepare a new CBFS and download a statically linked cbfstool:

cp bios.bin bios.bin.new
wget https://johnlewis.ie/Chromebook-ROMs/utils/cbfstool
chmod +x cbfstool
./cbfstool bios.bin.new print

to confirm everything has gone okay so far. Now we have to remove the existing payloads, add a new one, plus config files, and write out the CBFS:

./cbfstool bios.bin.new remove -n fallback/vboot
./cbfstool bios.bin.new remove -n fallback/payload
./cbfstool bios.bin.new add-payload -n fallback/payload -f ../out/bios.bin.elf -c lzma
./cbfstool bios.bin.new add -n etc/boot-menu-message -f ../chromeos/etc/boot-menu-message -t raw
./cbfstool bios.bin.new add -n etc/boot-menu-key -f ../chromeos/etc/boot-menu-key -t raw
./cbfstool bios.bin.new add -n bootorder -f ../chromeos/bootorder -t raw
./cbfstool bios.bin.new add-int -i 0xd091f000 -n etc/sdcard0
./cbfstool bios.bin.new add-int -i 0xd091c000 -n etc/sdcard1
dd bs=1M skip=7 if=bios.bin.new of=bios.cbfs.new

Time to get flashy:

wget https://johnlewis.ie/Chromebook-ROMs/utils/flashrom
chmod +x flashrom
sudo ./flashrom -w -i BOOT_STUB:bios.cbfs.new

Assuming you haven’t received any errors thus far, it may be safe to reboot. Didn’t work? Something went wrong? Get yourself a RPi/BBB, suitable jumper wires, and Pomona 5250 SOIC clip!

Clone your disk using Jeltka

Please note, if you don’t understand what’s going on here, it’s very easy to screw the source partition up, and lose your data! Be warned!

Obviously, boot into Jeltka first. Then, check the filesystem of the partition in question, in preparation for resizing the filesystem to it’s minimum size (please note, you may need to adjust device names accordingly):

e2fsck /dev/sda1

Then resize the filesystem to it’s smallest possible size using the -M flag of resize2fs:

resize2fs -M /dev/sda1

Mount the filesystem, check it’s size using df, and unmount it again (so fdisk can write the partition table successfully, later on):

mount /dev/sda1 /mnt
df -h
umount /dev/sda1

Now, we also need to reduce the size of the partition itself. This is so dd doesn’t copy more data than necessary (which could save you a lot of time). In the interests of safety, it’s always a good idea to make the partition at least 1GB bigger than the filesystem (fdisk and resize2fs, etc. calculate sizes in slightly different ways, the extra partition size ensures the partition is big enough to contain the filesystem). We also need to be careful because the version of fdisk included with Busybox uses the old 63 sector, default starting point for partitions, and your disk is probably partitioned with a 2048 sector starting point (this became the default in standard fdisk with the advent of GPT partitioning some years ago).

fdisk /dev/sda

To accommodate previous, we now change display units to sectors by pressing “u”. Press “p” to print the existing layout, to confirm the partition does indeed start at sector 2048. Then delete the existing partition – “d” followed by “1” (assuming the partition we’re concerned with is the first partition on the disk). Now we create a new partition with the same starting point – “n”, “p”, “1”, “2048”, “+14G” (where 14G is the size in gigabytes, you want the partition to be). Now type “p” again, and double check everything is as it should be, before hitting “w” to save the partition table and exit. Don’t worry too much if you’ve messed up here, as long as you can create a partition with the same starting point as the original, and enough size to accommodate the filesystem contained on it, you won’t lose any data. However, if you do something rash like create a new filesystem on an incorrectly sized/started partition, you will in fact be overwriting your nice data. In short, don’t do it!

Now we’re ready to do the actual copying using dd. I’m assuming here that you have a USB key/drive attached, and you’re going to output the partition image to a file on the USB key, with a view to dd’ing it onto a replacement HD/SSD, which you’ll physically put in your Chromebook subsequently. I’m assuming the USB key already has a compatible filesystem on it (ext4, FAT or NTFS, IIRC). Again, be careful to use the correct device name. First we’ll mount the USB stick somewhere suitable:

mount /dev/sdb1 /mnt

We should also backup the existing partition table and boot sector thusly:

dd bs=512 count=1 if=/dev/sda of=/mnt/bootsector.img

Then we’ll dd the partition to a file on the USB stick:

dd bs=1M if=/dev/sda1 of=/mnt/partition.img

If we had another console available, we could check on dd’s progress like so – find dd’s process number, and send a signal to it, to display progress every 60 seconds:

ps -e |grep dd
watch -d -n 60 kill -SIGUSR1 1234

Where “1234” is dd’s PID (will undoubtedly be something else entirely).

Assuming you didn’t run out of space on your USB whatever, dd will have completely successfully (eventually), and you can now set about swapping your HD/SSD out for a nice, shiny, big one. :)

Back already? Okay, now we’re ready to copy the partition table/bootsector over, and create a new partition to take advantage of all that space! Make sure you’ve mounted the USB whatever again.

dd if=/mnt/bootsector.img of=/dev/sda

Then use fdisk to create a new partition, as we did previously, only this time don’t specify a size (it will default to the end of disk).

Then, copy the partition image to the new partition we just created, using dd:

dd bs=1M if=/mnt/partition.img of=/dev/sda1

When this has finished, check you can mount the filesystem! Assuming you can, we can now resize the filesystem to take advantage of all that juicy space you’ve just purchased:

e2fsck /dev/sda1
resize2fs /dev/sda2

Success?

Tentative fix/work-around for i915 GPU hangs

Some of you may have noticed the GPU hangs on Haswell Chromebooks in recent versions of you favourite distro. Well, a man called Fabrice G. (via email) furnished me with what appears to be a fix, this afternoon. It’s rather a long addition to the kernel cmdline, and I’m not sure if *absolutely* all of it is needed, but it certainly appears to be doing the job on my HP Chromebook 14, in CentOS 7, with a 3.17 kernel.

Simply add the following to GRUB_CMDLINE_LINUX in /etc/default/grub:

drm.debug=0 drm.vblankoffdelay=1 i915.semaphores=0 i915.modeset=1 i915.use_mmio_flip=1 i915.powersave=1 i915.enable_ips=1 i915.disable_power_well=1 i915.enable_hangcheck=1 i915.enable_cmd_parser=1 i915.fastboot=0 i915.enable_ppgtt=1 i915.reset=0 i915.lvds_use_ssc=0 i915.enable_psr=0

then run:

su -c "grub2-mkconfig > /boot/grub2/grub.cfg"

in CentOS/Fedora, or:

update-grub

in Debian/Ubuntu/etc

Enjoy!

Making the touchpad work on a HP Pavilion Chromebook in Ubuntu 14.04 and 14.10

For Ubuntu 14.04 you have to add the following to /etc/rc.local before “exit 0”:

modprobe -r chromeos_laptop
modprobe i2c-i801
modprobe chromeos_laptop

For Ubuntu 14.10 you also have to add a “sleep 1” after loading the i2c module, so it would in this case read:

modprobe -r chromeos_laptop
modprobe i2c-i801
sleep 1
modprobe chromeos_laptop

Then copy /usr/share/X11/xorg.conf.d/50-synaptics.conf to /etc/X11/xorg.conf.d/51-synaptics.conf and edit it adding the following lines to the inputclass section named “touchpad catchall”:

Option "FingerHigh" "5"
Option "FingerLow" "5"

Reboot, and there you have it!

Extracting the shell-ball ROM using a ChromeOS image

As an example I’m performing this on Fedora 20. I assume that you’re doing it from your home directory.

1. Download the linux script for downloading ChromeOS images. From the cli type/paste:

wget https://dl.google.com/dl/edgedl/chromeos/recovery/linux_recovery.sh

2. Make the script executable so it will run:

chmod +x linux_recovery.sh

3. Run the script:

./linux_recovery.sh

4. Type the model name of the Chromebook you’re trying to get the ROM for e.g. “HP Chromebook 14”, then type the number of the corresponding image e.g. “8”. Once the file has downloaded, the script will attempt to extract it with a view to writing to USB, however, the tmp mount in Fedora doesn’t get allocated enough space and you get the following error:

chromeos_5712.88.0_falco_recovery_stable-channel_mp-v2.bin: write error (disk full?). Continue? (y/n/^C)

To which I say “n”.

5. Remove the partially extracted file, or you will get space errors:

rm /tmp/tmp.crosrec/*.bin

6. Note the name of the file above, as it will be needed for subsequent commands. Unzip the file into your home directory like so, adding “.zip” onto the end of the filename you noted above:

unzip /tmp/tmp.crosrec/chromeos_5712.88.0_falco_recovery_stable-channel_mp-v2.bin.zip

7. Use kpartx to make sense of the image’s partition structure. First of all make sure it’s installed. This is also a good time to install another dependency which will be needed later (specifically by the extract script):

sudo yum install kpartx sharutils

8. Run kpartx to add a mountable mapping to each of it’s partitions in /dev/mapper:

sudo kpartx -a /tmp/tmp.crosrec/chromeos_5712.88.0_falco_recovery_stable-channel_mp-v2.bin

9. The partition we want to get at is the system partition, which is now mapped to /dev/mapper/loop0p3 however, we have to mount it read-only otherwise mounting will fail:

sudo mount -o ro /dev/mapper/loop0p3 /mnt

10. Create a directory for the extracted files (you don’t want them messing up your home directory):

mkdir shellball

11. Do the extraction:

/mnt/usr/sbin/chromeos-firmwareupdate --sb_extract shellball

12. Write a valid hardware id (you can get a list of all id’s by running the linux_recovery.sh script without any search terms) to the shellball ROM so that ChromeOS will update, for example. After cd’ing into the shellball directory run:

./gbb_utility --set --hwid="PEPPY A2A-A2E-A5W" bios.bin bios.bin.new

13. Optionally set GBB flags as you like:

./gbb_utility --set --flags=0x489 bios.bin.new bios.bin.newer

14. Download statically linked flashrom and flash extracted BIOS:

wget https://johnlewis.ie/flashrom && chmod +x flashrom && sudo ./flashrom -w bios.bin.newer

15. Tidy up:

umount /mnt
dmsetup remove /dev/mapper/loop0p[0-9][0-9]
dmsetup remove /dev/mapper/loop0p[0-9]
losetup -d /dev/loop0

16. Remove /tmp/tmp.crosrec if you can’t wait for a reboot:

rm -rf /tmp/tmp.crosrec

How to make the legacy SeaBIOS firmware slot the default on a Haswell/Broadwell based Chromebook

Divulged this evening by Duncan Laurie on the coreboot mailing list:

If you want to boot SeaBIOS by default and you have unlocked the SPI flash write protection you can set flags in the (write protected) “GBB” flash region that will make it boot legacy mode by default.

In Chrome OS there is a script called set_gbb_flags.sh that will do this for you. Run the script with no arguments to get a list of possible flags and then to enable short dev mode screen (1 second timeout) followed by default legacy mode boot you could use these flags:

GBB_FLAG_DEV_SCREEN_SHORT_DELAY 0x00000001
GBB_FLAG_FORCE_DEV_SWITCH_ON 0x00000008
GBB_FLAG_FORCE_DEV_BOOT_LEGACY 0x00000080
GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY 0x00000400

/usr/share/vboot/bin/set_gbb_flags.sh 0x489