Gentoo on Skylake-based Chromebooks


Recently, there have been new Skylake-based Chromebooks based on two development boards, namely Glados and Kunimitsu. These Chromebooks are particularly interesting to use as a Linux laptop because of the decent hardware you get for the price, the build quality of most of these Chromebooks and because ChromeOS is based on Linux Gentoo. In this tutorial, we will mostly be focusing on installing Linux Gentoo and Funtoo on these Chromebooks, but these instructions can also be applied to other distributions.

We will consider the following Glados-based devices:

  • Samsung Chromebook Pro (Caroline)
  • HP Chromebook 13 G1 (Chell)
  • ASUS Chromebook Flip C302 (Cave)

and the following Kunimitsu-based devices:

  • Thinkpad 13 Chromebook (Sentry)
  • Chromebook 14 for work (CP5-471) (Lars)
  • Dell Chromebook 13 3380 (Asuka)

If you have another Skylake-based Chromebook not mentioned here, but that is based on Glados or Kunimitsu (see, then it is very likely that these instructions will work for you as well.


The current status for these Chromebooks is as follows:

  • Internal storage (eMMC)
  • SD-card
  • Internal keyboard
  • Touchpad
  • Touchscreen
  • WiFi
  • Bluetooth
  • Audio
    • nau88l25_ssm4567 (Caroline, Chell)
      • Speakers
      • Microphone
      • Headphones
      • Jack detection
    • nau88l25_max98357a (Asuka, Cave, Lars, Sentry)
      • Speakers
      • Microphone
      • Headphones
      • Jack detection
  • Suspend/resume

Note: while audio does work for me, it does not seem to work for everyone. The issues are being tracked at Furthermore, audio is not yet in a perfect state as PulseAudio does not know how to transition between speakers and headphones. I will update this post in the future as this issue progresses into a proper solution.

Developer mode

In order to get access to a shell, we'll have to switch the device to developer mode:

  • Turn off the laptop.
  • Whilst holding the Escape and the Refresh key, poke the Power key to invoke recovery mode.
  • Once the recovery screen appears, press the Control and D keys.
  • Confirm switching to developer mode by pressing the Enter key. The laptop will now reboot and prepare the system for developer mode. This process will commonly take about ten to twenty minutes.

If all went well, developer mode should now be enabled. In order to boot ChromeOS, you'll now have to press the Control and D keys to confirm that you want to boot from the SSD.


The boot process of Chromebooks is somewhat more complicated than the boot process of x86 devices (BIOS and UEFI) and ARM devices (u-boot). Similar to these devices, some Chromebooks do use the same firmware and boot loaders, but in a more extensive fashion. Despite the fact that there are still some legacy Chromebooks that use a BIOS for x86 and u-boot for ARM, Coreboot seems to be the firmware of choice for most of the Chromebooks.

One of Google's major considerations during the design of the boot process has been the concern of trust. When booting up the Chromebook, the first component that will be turned on is the CPU. The CPU will then load and execute the various boot loader stages that have been burnt into the ROM accompanying the CPU. The goal of these boot loader stages is to initiate certain parts of the CPU, and load the firmware from the ROM that has been soldered onto the motherboard. This ROM is split up into a read-only section and a read-write section, where the prior verifies the latter before loading and executing it. For most Chromebooks, this ROM will contain Coreboot, as well as some payload such as Depthcharge, or u-boot in the case of older Chromebooks. This payload will then determine what kernel to boot from the disk by inspecting the GPT partitions. Once a kernel has been chosen, it will be verified and loaded by the payload. Alternatively, some Chromebooks ship with SeaBIOS as a payload, but since there might be some fixes required, you may have to update it. See for more information about this. We will instead use the existing Depthcharge payload to boot our self-signed images.

The verification process is part of the verified boot (vboot) specification and implementation. This process mostly relies on cryptography, where a private and a public key are used for signing (encrypting the kernel) and verification (decrypting the kernel) respectively. Fortunately, this verification process can be disabled, in which case the developer keys can be used to sign your own kernel images.

Let's disable this verification process:

  • Boot into ChromeOS and switch to a different tty using Ctrl + Alt + F2 (Forward key).
  • Type shell to get into a bash shell.
  • Type sudo su to become root.
  • Type crossystem dev_boot_usb=1 dev_boot_signed_only=0 to enable booting from external media, and to disable the boot verification process.
  • Reboot the system to allow the changes to take effect.

After the changes have taken effect, it should now be possible to boot from external media using the Ctrl + U keys.

ChromeOS-related tools

To sign the images, partition the storage device, communicate with the microcontroller behind CrosEC, we will need various tools. To install these tools on Linux Gentoo or Linux Funtoo, you can use the ebuilds from my overlay.

First create a file called /etc/portage/repos.conf/synkhronix.conf as follows:

location = /usr/local/overlay/synkhronix
sync-type = git
sync-uri =
auto-sync = yes

Next we fetch the overlay and update the eix database:

emerge --sync

Then we can install the tools as follows:

emerge -av vboot-utils mosys

Partitioning the SD-card

To start with running Linux Gentoo or Funtoo, I recommend to keep your installation on an external storage medium such as a USB drive or SD-card first. Furthermore, I also recommend using an existing Linux system to set up the USB drive or SD-card, as the ChromeOS system is quite cumbersome to use without something like crouton.

At minimum, we'll only need a kernel partition and a rootfs partition. First, we'll reserve 64 kiB for the kernel partition and the remaining storage for the rootfs using gdisk. First install sys-apps/gptfdisk if you haven't installed it already:

emerge -av gptfdisk

Then we can set up the partitions, assuming that your storage device is named /dev/mmcblk1 and the first partition is named /dev/mmcblk1p1 (please change these to the appropriate names):

  • Run gdisk /dev/mmcblk1
  • Press the O key to start with an empty partition lay-out.
  • Press the N key to create a new partition.
  • Press the Enter key to use the default offset.
  • Type +64M and press the Enter key to create a 64M partition.
  • Type 7f00 and press the Enter key to assign the ChromeOS kernel partition type.
  • Press the N key to create a new partition.
  • Press the Enter key three times to use the default offset, size and partition type.
  • Press the W key to save the changes to the disk.

Next we mark the kernel partition as bootable using cgpt:

cgpt add -i 1 -t kernel -S 1 -T 5 -P 10 /dev/mmcblk1p1

Once the changes have been saved, we can format the rootfs partition as an Ext4-filesystem:

mkfs.ext4 /dev/mmcblk1p2

Finally, we can mount the partition and install the root filesystem and the Portage package manager by downloading and extracting the stage3 and Portage tarballs respectively:

mkdir -p /mnt/gentoo
mount /dev/mmcblk1p2 /mnt/gentoo
wget -O -$(wget -O - 2>/dev/zero | tail -n1) | tar xjp -C /mnt/gentoo/
wget -O - | tar xjp -C /mnt/gentoo/usr/

Alternatively, if you want to use Linux Funtoo, you can set it up as follows:

mkdir -p /mnt/gentoo
mount /dev/mmcblk1p2 /mnt/gentoo
wget -O - | tar xJp -C /mnt/gentoo/

Finally, you can also copy an existing rootfs from an existing system, as long as it has been compiled for the same architecture:

mkdir -p /mnt/gentoo
mount /dev/mmcblk1p2 /mnt/gentoo
cp -ax / /mnt/gentoo

Building a Linux kernel

The mainline support for Chromebooks has improved much in the past few years. Therefore we will opt to build a mainline kernel for our Chromebook. Unmask sys-kernel/gentoo-sources and emerge the latest Gentoo kernel source:

echo "sys-kernel/gentoo-sources ~amd64" >> /etc/portage/package.keywords
emerge -av gentoo-sources

Browse to /usr/src/linux and download the following kernel configuration to get some sane defaults for your Chromebook:

cd /usr/src/linux
wget -O .config

Next, update the config to be compatible with the current version of your Gentoo kernel sources:

make olddefconfig

This configuration can be further fine-tuned using make menuconfig, but it should already be fine for our needs. Build the kernel and the modules as follows:

make -j4 bzImage modules
INSTALL_MOD_PATH=/mnt/gentoo make modules_install

Then we have to create an empty boot.txt file and set up the kernel cmdline arguments in cmdline:

echo "console=tty0 rootwait rw root=/dev/mmcblk1p2" > cmdline
echo " " > boot.txt

Finally, we can sign the image using vbutil_kernel:

vbutil_kernel --pack kernel.kpart --keyblock /usr/share/vboot/devkeys/kernel.keyblock --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk --version 1 --vmlinuz arch/x86/boot/bzImage --bootloader boot.txt --config cmdline --arch x86_64

Now that it has been signed, write it to the kernel partition on your SD-card:

dd if=kernel.kpart of=/dev/mmcblk1p1

Now that the SD-card is ready, you can try booting it on the Chromebook.


The relevant kernel config options for networking are:

     Device Drivers  --->
 [*]   Network device support  --->
 [*]     Wireless LAN  ---> 
 <M>       Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi)
 <M>         Intel Wireless WiFi DVM Firmware support
 <M>         Intel Wireless WiFi MVM Firmware support

Make sure that CONFIG_IWLWIFI is set to compile as a kernel module, as you will otherwise have to embed the Intel WiFi firmware into your kernel.

Next, we have to install dhcpcd and wpa_supplicant in order to be able to use WiFi:

emerge -av dhcpcd wpa_supplicant

Then add these services to automatically start up:

rc-update add dhcpcd default
rc-update add wpa_supplicant default

Finally, edit your /etc/wpa_supplicant/wpa_supplicant.conf to contain the settings for the networks you want to be able to connect to. If you like a more GUI-oriented approach, you might be interested in using wicd or NetworkManager instead.

Input devices

The relevant kernel config options for the touchpad and the touchscreen are:

     Device Drivers  --->
       Input device support  --->
 [*]     Mice  --->
 <M>       ELAN I2C Touchpad support
 [*]         Enable I2C support
 [*]         Enable SMbus support
 [*]     Touchscreens  --->
 <M>       Elan eKTH I2C touchscreen
       I2C Support  --->
 -*-     I2C bus multiplexing support
         I2C Hardware Bus support  --->
 <*>       Synopsys DesignWare Platform
 [*]         Synopsys DesignWare Slave
 <*>       Synopsys DesignWare PCI
 -*-     I2C slave support
 -*-   Pin controllers  --->
 <*>     Intel Sunrisepoint pinctrl and GPIO driver
 -*-   GPIO Support  --->
       HID Support  --->
 <*>     Generic HID driver
         I2C HID support  --->
 <*>       HID over I2C transport layer

Then set up the following input devices in /etc/portage/make.conf for X11:

INPUT_DEVICES="evdev libinput synaptics"

Other than not being able to use multi-touch gestures, these should work out of the box.


The relevant kernel config options for audio are:

     Device Drivers  --->
       I2C Support  --->
 -*-     I2C bus multiplexing support
         I2C Hardware Bus support  --->
 <*>       Synopsys DesignWare Platform
 [*]         Synopsys DesignWare Slave
 <*>       Synopsys DesignWare PCI
 -*-     I2C slave support
 -*-   Pin controllers  --->
 <*>     Intel Sunrisepoint pinctrl and GPIO driver
 -*-   GPIO Support  --->
 <*>   Sound card support  --->
 <*>     Advanced Linux Sound Architecture  --->
 <*>       ALSA for SoC audio support  --->
 <M>       Intel ASoC SST drivers
 <M>         Intel ASoC SST driver for SKL/BXT/KBL/GLK/CNL
 -M-         Intel Audio machine drivers
 <M>           ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode
 <M>           ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode

In order to be able to get the ALSA drivers to work, you will need an ALSA topology firmware blob. The blob can be found at Download it to /lib/firmware:

wget -O /lib/firmware/dfw_sst.bin

If you boot up the Chromebook with functional audio, you should see something like the following in your dmesg output:

[    4.368172] nau8825 i2c-10508825:00: No 'mclk' clock found, assume MCLK is managed externally
[    4.380909] snd_soc_skl 0000:00:1f.3: bound 0000:00:02.0 (ops i915_audio_component_bind_ops)
[    4.419973] HDMI HDA Codec ehdaudio0D2: Max dais supported: 3
[    4.426297] snd_soc_skl 0000:00:1f.3: Direct firmware load for 9d70-CORE-COREBOOT-0-tplg.bin failed with error -2
[    4.426299] snd_soc_skl 0000:00:1f.3: tplg fw 9d70-CORE-COREBOOT-0-tplg.bin load failed with -2, falling back to dfw_sst.bin
[    4.429631] snd_soc_skl 0000:00:1f.3: ASoC: Parent card not yet available, widget card binding deferred
[    4.460998] HDMI HDA Codec ehdaudio0D2: hdac_hdmi_present_sense: disconnect for pin:port 5:0
[    4.461109] HDMI HDA Codec ehdaudio0D2: hdac_hdmi_present_sense: disconnect for pin:port 6:0
[    4.461220] HDMI HDA Codec ehdaudio0D2: hdac_hdmi_present_sense: disconnect for pin:port 7:0
[    4.461416] skl_n88l25_m98357a skl_n88l25_m98357a: snd-soc-dummy-dai <-> System Pin mapping ok
[    4.461445] skl_n88l25_m98357a skl_n88l25_m98357a: snd-soc-dummy-dai <-> System Pin mapping ok
[    4.461473] skl_n88l25_m98357a skl_n88l25_m98357a: snd-soc-dummy-dai <-> Reference Pin mapping ok
[    4.461497] skl_n88l25_m98357a skl_n88l25_m98357a: snd-soc-dummy-dai <-> DMIC Pin mapping ok
[    4.461522] skl_n88l25_m98357a skl_n88l25_m98357a: snd-soc-dummy-dai <-> HDMI1 Pin mapping ok
[    4.461547] skl_n88l25_m98357a skl_n88l25_m98357a: snd-soc-dummy-dai <-> HDMI2 Pin mapping ok
[    4.461577] skl_n88l25_m98357a skl_n88l25_m98357a: snd-soc-dummy-dai <-> HDMI3 Pin mapping ok
[    4.461589] skl_n88l25_m98357a skl_n88l25_m98357a: HiFi <-> SSP0 Pin mapping ok
[    4.462890] skl_n88l25_m98357a skl_n88l25_m98357a: nau8825-hifi <-> SSP1 Pin mapping ok
[    4.462900] skl_n88l25_m98357a skl_n88l25_m98357a: dmic-hifi <-> DMIC01 Pin mapping ok
[    4.462909] skl_n88l25_m98357a skl_n88l25_m98357a: intel-hdmi-hifi1 <-> iDisp1 Pin mapping ok
[    4.462917] skl_n88l25_m98357a skl_n88l25_m98357a: intel-hdmi-hifi2 <-> iDisp2 Pin mapping ok
[    4.462926] skl_n88l25_m98357a skl_n88l25_m98357a: intel-hdmi-hifi3 <-> iDisp3 Pin mapping ok

Install alsa-utils, alsa-lib and pulseaudio:

emerge -av alsa-utils alsa-lib pulseaudio

In addition, you will also need to set up ALSA UCM profiles in order to be able to switch between the speakers and the headphones. The UCM profiles can be found at Clone the Git repository and copy them to /usr/share/alsa/ucm/:

git clone
cp -r gentoo-chromebook-skylake/usr/share/alsa/ucm/* /usr/share/alsa/ucm/

Next depending on your device, you might have to create a symbolic link to the appropriate folder:

  • For Caroline, run: ln -s /usr/share/alsa/ucm/Google-Caroline-1.0-Caroline/ /usr/share/alsa/ucm/sklnau8825adi
  • For Chell, run: ln -s /usr/share/alsa/ucm/Google-Chell-1.0-Chell/ /usr/share/alsa/ucm/sklnau8825adi
  • For Cave, run: ln -s /usr/share/alsa/ucm/Google-Cave-1.0-Cave/ /usr/share/alsa/ucm/sklnau8825max
  • For Sentry, run: ln -s /usr/share/alsa/ucm/Google-Sentry-1.0-Sentry/ /usr/share/alsa/ucm/sklnau8825max
  • For Lars, run: ln -s /usr/share/alsa/ucm/Google-Lars-1.0-Lars/ /usr/share/alsa/ucm/sklnau8825max
  • For Asuka, run: ln -s /usr/share/alsa/ucm/Google-Asuka-1.0-Asuka/ /usr/share/alsa/ucm/sklnau8825max

Once booted up, run the following to use the speakers (replace sklnau8825max with sklnau8825adi if your device uses sklnau8825adi instead):

alsaucm -c sklnau8825max set _verb HiFi set _enadev Speaker

To use the headphones, run:

alsaucm -c sklnau8825max set _verb HiFi set _enadev Headphone

It is best to make sure you are not playing any audio using PulseAudio while switching between one of the two, as it will break the playback for running PulseAudio clients. Inserting a headphone in the jack works, but will also cause the playback to break for running PulseAudio clients. It is recommended to wait about five seconds after switching for the device to initialise properly. Hopefully, this will improve in the future. Unfortunately, this also affects jack detection. While ACPI events are registered whenever a headphone jack is plugged in or out, PulseAudio does not know how to handle these properly.