September 28, 2015 - Javier Martinez Canillas

How to Install a Linux Mainline Kernel and Distro on Exynos Chromebooks

Over the last year I spent some time improving the mainline support for the Exynos based Chromebooks. This blog post explains how to install a Linux mainline kernel and distribution on these machines. The first half covers some background information that explains what needs to be done to the Chromebook to make this happen, and the second half is a step-by-step guide to complete the process.

A Bit of Background Information

Chromebooks use a fairly unique boot system to improve reliability during upgrades and provide better hardware security. This makes the process of installing a different Linux distro on the device a bit more challenging than most consumer devices.

ChromeOS Verified Boot

Chromebooks use a technique called verified boot (vboot) to ensure all binaries are safe to be executed. The Chromebook comes with firmware (a vendor u-boot in the case of Samsung Chromebooks) that has vboot support and is composed of a read-only and a read / write part. The firmware expects a signed Flattened Image Tree (FIT) image to load.

For ChromeOS, this FIT image contains a kernel image and a Flattened Device Tree (FDT). But it can also contain a u-boot image which should be able to load and execute non-signed kernels. This process of making an u-boot to load another u-boot instead of a kernel is known as u-boot chain loading.

Google provides the keys that allow developers to sign their own binaries by using the vbutil_kernel tool, but Chromebooks can only boot binaries signed with this key when are in developer mode. In normal mode, they can only boot binaries signed by the vendor.

ChromeOS disk partition layout and special GPT flags

Bootable media for Chromebooks require a GUID Partition Table (GPT). This is because the GUID Partition Entry Array has an Attributes field in which some bits are reserved to be used by partitions of any given type.

The “ChromeOS kernel” partition type has the following attribute flags stored in these bits:

  • Priority: the order in which the firmware needs to look for a kernel.
  • Tries: the number of times the firmware should try booting from this.
  • Successful: this partition is known to be a good one so the tries flag is omitted.

These flags can be modified using the cgpt tool that is a GPT manipulation util that has support for the ChromeOS extensions.

More information about the ChromeOS disk format, its custom partition types and flags can be found in the ChromiumOS wiki.

ChromeOS boot process

The Chromebook firmware tries to load a FIT image from the partition with the highest priority by reading the GPT priority flags for each partition. Priority is a 4-bit flag so the maximum priority is 15 and the minimum is 1. A priority of 0 means that the partition is not bootable. The firmware tries to boot the number of times specified in the tries flag and each time it fails, decrements that field until is 0 and gives up and tries to boot the partition with the next highest priority.

If a partition with higher priority is marked as successful equal to 1, the firmware will omit the tries and will always try to boot that partition. Which means that if the kernel in that partition does not boot, the machine won’t boot again and will need to be recovered. So it is always a good idea to first mark as successful equal to 0 and only mark the partition as successful equal to 1 once it was verified that the kernel booted correctly. This is exactly what ChromeOS does and why that flag exists in the first place.

Step-by-Step Process

There are many approaches to install a mainline kernel and a Linux distro using the stock firmware and so not voiding the warranty. In this post I will walk you through the installation of a v4.2 kernel and a Fedora root filesystem into partitions of the internal eMMC and use a signed FIT image format that is the one expected by the Chromebook stock firmware. With this method, both Fedora and ChromeOS can be available for boot by changing the partition’s boot priority.

Other options include chain loading a mainline u-boot or installing the Linux distro and the mainline kernel into a removable media but those can be explained in following posts.The commands in this post are to install a Fedora root filesystem and a v4.2 kernel on an Exynos5250 Snow (Chromebook1) and an Exynos5800 Peach Pi (Chromebook2) but the process is general enough that can be used for most ARM based Chromebooks.

Prerequisites

To follow this article, an ARMv7 hard float toolchain is needed and also the mkimage and vbutil_kernel tools. How to install these will depend on your Linux distribution so follow the installation instructions of your distribution to install them.

Enable Developer Mode

Self-signed FIT images can only be booted when the machine is in developer mode so the first step is to enable developer mode on the Chromebook. Additionally, Developer mode also gives access to a root shell that is needed for this installation. The ChromiumOS wiki has instructions to enable developer mode for both Snow and Peach Pi/Pit.

WARNING: Enabling developer mode will wipe your user data.

Resize the KERN-C and ROOT-C Partitions

ChromeOS has an interesting partition scheme that consists of 2 rootfs and 2 kernel partitions, but only one pair is active at any time. When ChromeOS is updated, the new rootfs and kernel are written to the inactive partitions. Then, the priorities are changed and the machine is rebooted. Next, the new kernel is booted and is only checked once to see if it boots correctly. After a successful boot, the new kernel partition is marked as boot successful and the old partitions becomes inactive. With this method, there is always a pair that is known to be good that can be used to roll back if something goes wrong as a result of the update.

This is possible because ROOT-{A,B} are mounted as read-only and all the writable user data is in a different partition labeled as STATE and mounted in /mnt/stateful_partition. However, there is a third pair of partitions that are not used and have a size of 1 sector. These can be used to install a custom kernel and rootfs without affecting ChromeOS, but first these need to be resized by stealing some space from the STATE partition.

You can check the partition layout by using the cgpt tool. For example in the Peach Pi:

The partition sizes are in 512 byte disk sectors. So the STATE partition size in the ChromeOS of my Peach Pi is 21295105 sectors (a little less than 10 GiB). This partition size can be reduced so 10 MiB can be taken for KERN-C and 8 GiB for ROOT-C.

Save the script in the Chromebook and execute it. It will resize the partitions, update the GPT table and reboot.

WARNING: running this script will wipe all the data in your user partition!

This script is based on commands from this ChromiumOS wiki page.

On boot, the startup script will create all the files in the stateful partition again. This will take considerable time and then the machine will reboot into ChromeOS.

Copy the Fedora root Filesystem to the ROOT-C Partition

The next step it to take an ARMv7 hard float Fedora image and copy it to a removable media since the stateful partition on the Chromebook most likely won’t have enough space for the image as most of the space is taken by ROOT-C.

Then, on the Chromebook check the partitions and offsets of the Fedora image:

The third partition is the rootfs, so associate a loop device with the file at the offset of the rootfs partition and do a raw copy to the ROOT-C partition. Since the size is in 512 bytes sector, multiply it to get the offset in bytes:

Build a Kernel and Copy to KERN-C Partition

Download the latest stable kernel (v4.2.1 at the time of this article):

Configure using the Exynos default configuration but enable the WiFi driver as a module since we are going to boot without an initramfs and the driver needs to load a firmware from the rootfs on probe. Enabling it as a module ensures its driver is probed after the rootfs containing the firmware is mounted.

Build the kernel image, modules and device trees:

Install the modules in a removable media so these can be copied to the Fedora rootfs in the Chromebook:

The next step is to create a signed FIT image so it can be copied to the KERN-C partition of the Chromebook eMMC. To create a FIT image, there is a need of a FIT source file that contains configurations, one or more kernel binaries and one or more FDT.

The following FIT source for example will add support for both Snow and Peach Pi in the same FIT image. The firmware has its own FDT blob with a compatible string so it picks the FDT that has a compatible string that matches the one in the firmware. That way the same FIT image can be used to boot either Snow or Peach Pi since each firmware will choose the correct FDT.

So create a kernel.its file with the following content:

The FIT image has the kernel command line embedded on it so first create a config for it:

Then create the FIT image and sign it:

Copy the kernel.kpart to the removable media

On the Chromebook, mount the media device and the Fedora rootfs partitions, copy the modules to the rootfs and the kernel to the KERN-C partition:

Copy the cgpt binary to the Fedora rootfs so the ChromeOS kernel partition priority can be bumped from Fedora. There is a package for cgpt but it is still good to have the binary in case things go wrong and for example networking is not working to install the package.

Remove stale entries from Fedora’s /etc/fstab and only keep the entry for the root partition. This is how my fstab looks for example:

Finally unmount the Fedora rootfs partition:

At this point the Fedora rootfs and the mainline kernel are installed but the Chromebook will still boot ChromeOS so bump KERN-C priority and set tries flag to 1 but leave successful to 0 until you are sure that the kernel can boot correctly:

Reboot, when the machine is booted again, it should boot the mainline kernel and should mount the Fedora partition as rootfs.

If everything goes well and the mainline kernel booted correctly, mark the boot as successful:

Now the Chromebook should be able to boot either Fedora or ChromeOS. To boot ChromeOS again, just switch the priorities for both KERN-A and KERN-C partitions from Fedora:

And to boot again into Fedora, do the opposite from ChromeOS:

Enjoy Linux on Your Chromebook

This guide specifically outlines this process for Fedora, but you should be able to get just about any Linux distro running on your Exynos Chromebook using similar steps. If you encounter any differences for other distros, or have questions, feel free to post a comment.

Happy hacking!

Javier Martinez Canillas

About Javier Martinez Canillas

Javier was a Senior Linux Kernel Developer for the Samsung Open Source Group. He has contributed to different kernel subsystems with a focus on ARM and Exynos SoC support. Besides hacking, he enjoys spending as much time as possible with his wife Tami and their twins, running, reading and writing technical articles like "Kbuild: the Linux Kernel Build System", published by the Linux Journal.

Image Credits: Köf3 - via Wikimedia Commons

Linux Chromebook / Exynos / Linux / Samsung /

Comments

  • Yaki Yang says:

    Thanks for your good material, but I got some questions in step-by-step processes,
    wish you could share some helps 🙂

    1. About ” Copy the Fedora root Filesystem to the ROOT-C Partition” step:
    Is there any way to setup mainline kernel with ChromeOS itself ?

    2. About “Build a Kernel and Copy to KERN-C Partition” step:
    As my hardware is Peach Pit, guess I should replace the “exynos5250-snow” with
    “exynos5420-peach-pit” in kernel.its file, is it right ?
    %s/exynos5250-snow/exynos5420-peach-pit/

    And I failed at vbutil_kernel step, note I move the mainline kernel into chroot env,
    the vbutil_kernel remind me that missing bootloader file,
    (cr) (20150918|REBASE-i 1/18) yakir@server ~/trunk/src/linux-next $ vbutil_kernel –version 1 –arch arm –keyblock /usr/share/vboot/devkeys/kernel.keyblock –signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk –vmlinuz kernel.itb –config config.txt –pack kernel.kpart
    ERROR: Missing required bootloader file.

    • Javier Martinez Canillas Javier Martinez Canillas says:

      Hello Yakir,

      We already talked in the mailing lists but I’ll answer your questions here for completeness and other people reference.

      1) Yes, you can copy any rootfs, the blog uses Fedora just as an example. I haven’t booted ChromeOS in a while but last time I tried about a year ago, it expected 3D HW acceleration to be working which is not supported in mainline and also the ChromiumOS tree has features (i.e: dark resume) that are not present in mainline and are used ChromeOS user-space programs.

      2) Yes, you have to use the exynos5420-peach-pit FDT for Peach Pit.

      I haven’t seen that vbutil_kernel error before but since you mentioned in the mainling list that were able to boot mainline in your Peach Pit and Snow, I assume you sorted it out.

      Best regards,
      Javier

  • Andrew Basterfield says:

    First of all great write up! I am trying to get a Chromebook 2 (peach pit – XE503C12) to boot mainline Linux. I already have it booting a custom 3.8 Chromium kernel but whenever I try mainline I just get a blank screen. Any ideas?

    • Andrew Basterfield says:

      I needed to add an entry for exynos5420-peach-pit.dtb to kernel.its!

      • Javier Martinez Canillas Javier Martinez Canillas says:

        Hello Andrew,

        Yes, the kernel.its in the article is an example to show how to have two Exynos Chromebooks (5250 Snow and 5800 Peach Pi) supported by a single FIT image. But you should use the correct Device Tree for your device. Glad that you figured out and have it working!

  • Luka Perkov says:

    Can you write a guide how to build & flash mainline uboot for the chromebooks?

    Also, is there any way to recover bricked chromebooks?

    • Javier Martinez Canillas Javier Martinez Canillas says:

      Yes, I’ll write a guide on how to build and install a mainline u-boot for Chomebooks so it can be chain loaded from the verified boot firmware.

      You can always recover a Chromebook to its original factory state by reinstalling ChromeOS (more info at http://google.com/chromeos/recovery).

      Now if by bricked you mean that the write protection was removed and a broken bootloader was flashed in the originally read-only flash, then I’m afraid that I don’t know how that could be recovered.

      • Luka Perkov says:

        Thanks Javier! Chain loading uboot is a start. What I would like to do is to replace the original uboot on the SPI flash.

        As for debricking method then I could simply flash directly to the SPI via buspirate or something 🙂

        • Javier Martinez Canillas Javier Martinez Canillas says:

          Hello Luka,

          Yes you could replace the original u-boot on the SPI flash but I wouldn’t recommend it since I don’t see the advantage while you risk to brick your device.

          If you find having to press Ctrl + d, waiting 30 secs or the beep annoying, you can change the Google Binary Block (GBB) flags and set GBB_FLAG_DEV_SCREEN_SHORT_DELAY.

          The arch wiki page has information on how to do it: https://wiki.archlinux.org/index.php/Chrome_OS_devices but you need to disable the flash write-protect for that.

          And yes, I guess that you could use buspirate or something to write to the SPI flash but I never tried it.

  • Michael Llewellyn says:

    You can fix the ” Missing required bootloader file” error by creating an empty file (eg dummy.txt) and passing –bootloader dummy.txt. This seems to vary depending on vbutil version use. I was using vboot tools from the Arch Linux alarm respository i think…

    Many thanks for the great article, I’d love to see one on mainline uboot! Explaining how to create an image to flash to the SPI would be awesome too cos I would love to finally get there after trying so many times… but I can totally see that it just isn’t worth it. At the moment I would just like to get mainline kernel on my snow again 🙂

    I flashed nv_uboot (without simplefb but, i think, without some fixes to the bootloader that have happened since then) to the SPI flash a long time ago and wasn’t ever able to get a mainline kernel to boot. I have only recently discovered that the ChromeOS recovery seemed to flash verified uboot again 🙂 Clever google, wish I had tried it sooner. Arch linux package a mainline kernel for exynos chromebooks which did work for me but has broken with the latest release (just blank screen).

    Now I am uncertain again –
    Did the ChromeOS recovery give me the lastest, standard firmware? It says something about daisy-test during boot and so could it be developer firmware?? Maybe it picked up on the fact thatthe write-protection on the SPI was disabled?

    • Isaque Galdino says:

      About the “ERROR: Missing required bootloader file.”, the dummy file must have at least one line, i.e. no touch dummy.txt, you need to:
      $ cat <dummy.txt

      EOF

      😉

  • Cian O'Flynn says:

    Thanks for a great tutorial.

    I got to boot fedora with 4.3 kernel but don’t have very much space left on /
    http://sprunge.us/deHC

  • Cian O'Flynn says:

    I fixed that by booting form sd and using gpart to use unallocated space, so have the full 8gb available now.

  • Cian O'Flynn says:

    Hi

    running
    mkfs.ext4 /dev/mmcblk0p7
    before
    dd if=/dev/loop1 of=/dev/mmcblk0p7 bs=4M
    prepares the full 8gb file system.

    Not sure if I messed up the module bit of the tutorial, but there are very few modules available (no usb storage or bluetooth) on boot. Have a missed something?

    Once you have a working system, is it possible to build the kernel on the the system itself rather than cross compile?

    I’m not familiar with fedora but I had problems installing httpd, cpio error on install. I think that is related to SELinux setup.

  • E.S. Quinn says:

    Thanks for this guide! with it I’ve managed to get a Vanilla 4.4 kernel up and running on an existing Chrubuntu OS install. (First gen Snow chromebook for what it’s worth)

    Unfortunately, I can’t get the audio to play back. Alsa sees a Snow-I2S-MAX98095 device and presents the mixer for it, but unlike on the older 3.8 series kernel, unmuting the “Left Speaker Mixer Left DAC1” and “Right Speaker Mixer Right DAC1” channels doesn’t seem to help.

    Does the audio work on your end, and if so did you have to do anything special to it?

    • Javier Martinez Canillas Javier Martinez Canillas says:

      Hello,

      I’m glad that 4.4 worked for you.

      Yes, audio not working reliable on Snow and Peach boards is a known issue and hopefully will be fixed soon.

      • Hello Javier,
        I installed Debian Jessie on the external SD card with vanila kernel 4.4 (with some tweaks) on C32 (Peach) and everything works without problem i.e. audio, wifi, camera, USB, brigtness control, suspend, touchpad with double taps (no nedd to press lower corners, what I find iritating). It works so good that I now think to use it as main work device but I have to learn how to install Mali driver (kernel and X11). Although it works quite well even without Mali drivers (but I will try to install if I found time).
        BTW, thank you for your article which is really clearly written and helped me a lot to install Linux on this quite fine piece of hardware.

  • […] a previous post, I explained how to boot a mainline Linux Kernel to use a standard distribution on a Samsung […]

  • jonathan hudson says:

    So, six months on and still no DAISY / peach sound device in main line kernels (at least on Arch 4.6.3). A regression against kernel 3.8.
    Is it still the plan that this “hopefully will be fixed soon”? Any more definite time scales?

    • Javier Martinez Canillas Javier Martinez Canillas says:

      Hello Jonathan,

      Unfortunately there isn’t a time scale for this. I spent some time to get sound working properly but it seems that’s not trivial.

      Keep in mind that the 3.8 kernel that is shipped in the Chromebooks and mainline are two completely different things, so this is not a regression against 3.8 but rather a missing functionality in the Daisy/Peachs upstream support.

Leave a Reply to Use a mainline U-Boot and non-signed kernels on Exynos Chromebooks - Samsung Open Source Group Blog Cancel reply

Your email address will not be published. Required fields are marked *

Comments Protected by WP-SpamShield Anti-Spam