Asus Chromebook C201

From Gentoo Wiki
Jump to: navigation, search

The Asus C201 is a pretty fast and lightweight ARMv7-A (Cortex-A17) based chromebook. Its most distinguishing feature is that it is one of only a few devices already supported by Libreboot. That is, the factory firmware (coreboot) can optionally be replaced with entirely libre firmware. Instructions on how to do this can be found on the Libreboot website.

Specifications

  • SoC: Rockchip RK3288
  • CPU: Quad-core ARM Cortex-A17 @ 1.8 GHz
  • GPU: Mali T764
  • Board name: Veyron Speedy
  • Audio: Rockchip I2S
  • Screen: 11.6" @ 1366x768
  • Ram: 2gb/4gb
  • Firmware: coreboot
  • Coreboot payload: deptchcharge
  • Filename of device tree binary: rk3288-veyron-speedy.dtb

What works and what doesn't

On >=sys-kernel/gentoo-sources-4.20 On ChromeOS 3.14 or patched 4.12+
Suspend/Resume untested works
Built-in Wifi works with proprietary blobs works (on newer kernels, with patch)
X works (x11-wm/i3) works
X w/ randr untested works
HDMI untested untested
ACPI events untested works (lid, buttons, charger)
Audio works works
Touchpad works works
Bluetooth untested works (with issues)
GPU hardware acceleration no (WIP, cf. Panfrost) unknown

Mainline support is close to complete[1], so using sys-kernel/gentoo-sources should yield the best overall experience of all options.

Installing Gentoo

Additional hardware requirements

  • USB ethernet adapter
Note
Gentoo’s ARMv7-A stage3 tarballs don’t include net-wireless/wpa_supplicant. While it is possible to install Gentoo leveraging solely the built-in wifi, a USB ethernet adapter can spare a lot of effort. Otherwise net-wireless/wpa_supplicant needs to be installed on the installation media which probably involves a bit of cross-compilation.

Obtain installation media

Create the installation media manually. Alternatively have a look at Devsus.

Preparing the device

To be able to boot from external media like USB drives, the Asus C201 first needs to be switched into developer mode[2].

This can be achieved by pressing Esc+Refresh+Power when the device is switched off to enter the recovery mode screen.

Pressing Ctrl+D and then following subsequent on-screen instructions enables the developer mode.

Finally one of the verified boot parameters needs to be modified: Boot the device and enter Chrome OS' crosh shell, e.g. by opening Chromium Browser and hitting Ctrl+Alt+T. Enable booting from external media:

root #crossystem dev_boot_usb=1

Booting the installation media

Power on and when the boot screen is displayed press Ctrl+U to boot from the installation media. Log in (in case the installation media was manually created following the instructions referred to above the username is ‘root’ and the password is ‘gentoo’).

Configuring the Network

Important
Throughout these instructions the Gentoo Handbook for AMD64 (there is none for ARM) will be referenced a lot. In large parts the installation instructions from the Gentoo Handbooks are not too architecture specific. Nevertheless mind that discrepancy.

Begin with configuring the network.

Preparing the install media

Once a network connection is established make sure Portage is prepared:

root #emerge-webrsync

Then make sure the required tools (sys-block/parted and sys-boot/vboot-utils) are installed:

root #emerge --ask sys-block/parted sys-boot/vboot-utils

Backup the internal eMMC storage

Note
This step is highly recommended, although optional.
Important
The letter “X” in the following command needs to be replaced with the number corresponding to the internal eMMC storage.
root #dd if=/dev/mmcblkX of=/PATH/TO/ARBITRARY_BACKUP_LOCATION/c201backup.img


Preparing the disks

A GPT (GUID Partition Table) is mandatory.

Recommended partition layout and size:

/dev/mmcblkXp1 kernel partition (similar to a traditional boot partition) 64MiB
/dev/mmcblkXp2 root partition available space
Important
The letter “X” in the following commands needs to be replaced with the number corresponding to the internal eMMC storage.
Warning
This will delete all data on /dev/mmcblkX. Doublecheck e.g. with lsblk as on Google's 3.14 kernel, the eMMC storage is presented as mmcblk0, and the SD is presented as mmcblk2. On newer kernels, this can be reversed, with internal storage being mmcblk2.
root #parted /dev/mmcblkX mklabel gpt
root #parted -a optimal /dev/mmcblkX unit mib mkpart Kernel 1 65
root #parted -a optimal /dev/mmcblkX unit mib mkpart root 65 100%

Cf. Handbook: Preparing the disks

Depthcharge, the chromebooks’ bootloader, requires some specific parameters to be set. These signal the bootloader the presence of a valid kernel partition:

root # cgpt add -i 1 -t kernel -l Kernel -S 1 -T 5 -P 15 /dev/mmcblkX

Mount the root partition:

root #mkdir /mnt/gentoo
root #mount /dev/mmcblkXp2 /mnt/gentoo

Installing the Gentoo installation files

Choose an ARMv7a|HardFP stage3 from the main website's download section or consider going for an armv7a_hardfp-musl stage3 from the Hardened musl project. Follow Installing the Gentoo installation files from the Handbook.

Installing the Gentoo base system

Skip "Mounting the boot partition", apart from that follow the Handbook for Installing the Gentoo base system.

Configuring the Linux kernel

Install the tools required for deploying the kernel (dev-embedded/u-boot-tools, sys-apps/dtc and sys-boot/vboot-utils):

root #emerge --ask dev-embedded/u-boot-tools sys-apps/dtc sys-boot/vboot-utils

Configure sys-kernel/gentoo-sources as usual, cf. Configuring the Linux kernel. Alternatively refer to the RockMyy repository to include Mali GPU drivers.

Building the kernel and device tree binaries

user $make -j5 zImage dtbs modules

From the kernel build directory, copy the zImage and the target device's device tree binary to the desired working directory. Replace DTBINARY with the filename of the target device's device tree binary, e.g. rk3288-veyron-speedy.dtb for the Asus Chromebook C201 (which is based on Rockchip's RK3288 SoC and a board with the codename "Veyron Speedy").

user $cp -a arch/arm/boot/zImage /PATH/TO/ARBITRARY_WORKING_DIRECTORY
user $cp -a arch/arm/boot/dts/DTBINARY /PATH/TO/ARBITRARY_WORKING_DIRECTORY

Optional: Creating a Custom Initramfs

Follow instructions from the Custom Initramfs article. Embed the initramfs into the kernel or create it as a separate file (cf. Custom Initramfs - Creating a separate file):

user $find /PATH/TO/INITRAMFS/ -print0 | cpio --null --create --verbose --format=newc | gzip --best > /PATH/TO/ARBITRARY_WORKING_DIRECTORY/initrd.img

Creating the FIT image

Change to the directory where the kernel, the device tree binary and (optionally) the initramfs are located:

user $cd /PATH/TO/ARBITRARY_WORKING_DIRECTORY

Create the configuration file ("gentoo.its") for the Flattened Image Tree (FIT)[3] with the following content[4]. Again replace DTBINARY with the filename of the target device's device tree binary, e.g. rk3288-veyron-speedy.dtb for the Asus Chromebook C201.

Important
If there is no need for an initramfs or it's embedded into the kernel, make sure to create the FIT configuration file without the ramdisk@1 section and the following reference to that section.
FILE gentoo.its
/dts-v1/;

/ {
    description = "Linux kernel image with one or more FDT blobs";
    #address-cells = <1>;
    images {
        kernel@1{
            description = "vmlinuz";
            data = /incbin/("zImage");
            type = "kernel_noload";
            arch = "arm";
            os = "linux";
            compression = "none";
            hash@1{
                algo = "sha1";
            };
        };
        fdt@1{
            description = "dtb";
            data = /incbin/("DTBINARY");
            type = "flat_dt";
            arch = "arm";
            compression = "none";
            hash@1{
                algo = "sha1";
            };
        };
        ramdisk@1{
            description = "initrd.img";
            data = /incbin/("initrd.img");
            type = "ramdisk";
            arch = "arm";
            os = "linux";
            compression = "none";
            hash@1{
                algo = "sha1";
            };
        };
    };
    configurations {
        default = "conf@1";
        conf@1{
            kernel = "kernel@1";
            fdt = "fdt@1";
            ramdisk = "ramdisk@1";
        };
    };
};

Pack the FIT image:

user $sync
user $mkimage -f gentoo.its gentoo.itb

Preparing verified boot

Create a file ("kernel.flags") for the CMDLINE parameters:

FILE kernel.flags
console=tty1 root=/dev/ROOTFS_PARTITION rootfstype=ROOTFS_TYPE  rootwait rw

Sign and pack the kernel:

user $sync
user $futility --debug vbutil_kernel --arch arm --version 1 --keyblock /usr/share/vboot/devkeys/kernel.keyblock --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk --bootloader kernel.flags --config kernel.flags --vmlinuz gentoo.itb --pack vmlinuz.signed

Installing the kernel

Install the modules, keeping them small to save some space:

root #make INSTALL_MOD_STRIP=1 modules_install
Important
The letter “X” in the following command needs to be replaced with the number corresponding to the internal eMMC storage.

Install the kernel image to the kernel partition:

root #sync && dd if=vmlinuz.signed of=/dev/mmcblkXp1

Configuring the system

Consult the Handbook again for Configuring the system.

Installing system tools

Stick with the Handbook: Installing system tools

Important
Skip the chapter Configuring the bootloader (this one) in the Handbook, as the bootloader (depthcharge) is part of the C201's system firmware.

Finalizing

Finalize the new Gentoo installation according to the handbook. To use wifi remember to install net-wireless/wpa_supplicant:

root #emerge –ask net-wireless/wpa-supplicant

Also keep in mind that the built-in wifi requires proprietary firmware.

Built-in wifi

Built-in wifi requires the proprietary binary firmware blob brcmfmac4354-sdio.bin, provided by sys-kernel/linux-firmware):

root #emerge --ask sys-kernel/linux-firmware

Furthermore the aforementioned binary expects a nvram, /lib/firmware/brcm/brcmfmac4354-sdio.txt. Create it with the content provided by the ChromiumOS project: https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master/overlay-veyron/chromeos-base/chromeos-bsp-veyron/files/firmware/brcmfmac4354-sdio.txt

The ChromiumOS project considers this file belonging to the BSP (Board Support Package) and considers upstreaming the file to sys-kernel/linux-firmware as being pointless.[5]

For additional background information regarding this nvram, consult the Linux Wireless wiki.

Example configurations

make.conf

FILE /etc/portage/make.conf
CFLAGS="-O2 -pipe -march=armv7-a -mtune=cortex-a17 -mfpu=neon -mfloat-abi=hard -pipe -fomit-frame-pointer -fstack-protector-strong"
CXXFLAGS="${CFLAGS}"
CHOST="armv7a-unknown-linux-gnueabihf"
INPUT_DEVICES="libinput"
VIDEO_CARDS="fbdev"

ACPI

FILE /etc/acpi/default.sh
#!/bin/sh
# /etc/acpi/default.sh
# Default acpi script that takes an entry for all actions

set $*

group=${1%%/*}
action=${1#*/}
device=$2
id=$3
value=$4

log_unhandled() {
	logger "ACPI event unhandled: $*"
}

case "$group" in
	jack)
		case "$id" in
			'plug')
				amixer -D hw:0 cset name='Left Speaker Mixer Left DAC Switch' off
				amixer -D hw:0 cset name='Right Speaker Mixer Right DAC Switch' off
				amixer -D hw:0 cset name='Headphone Switch Left' on
                                amixer -D hw:0 cset name='Headphone Switch Right' on
				;;
			'unplug')
				amixer -D hw:0 cset name='Left Speaker Mixer Left DAC Switch' on
                                amixer -D hw:0 cset name='Right Speaker Mixer Right DAC Switch' on
				amixer -D hw:0 cset name='Headphone Switch Left' off
                                amixer -D hw:0 cset name='Headphone Switch Right' off
				;;
			*) uhd $+;;
		esac
		log_unhandled $*
	;;
	button)
		case "$action" in
			#power)
					#pm-suspend
			#		log_unhandled $*
			#	;;

			lid)
				case "$id" in
					close) if [ $(cat /sys/class/power_supply/gpio-charger/online) -eq 0 ]; then
                                                        pm-suspend
                                                fi;;
					open) :;;
					*) uhd $*;;
				esac
				log_unhandled $*
				;;

			*)	log_unhandled $* ;;
		esac
		;;

	*)	log_unhandled $* ;;
esac

This handles alternating between speaker and headphone jack when one is plugged in, as well as lid suspend when the charger is unplugged. Power button support can be added if desired, though keep in mind the device will simply turn on again when the lid is closed.

Note
It seems some mixer control names changed from 3.x to 4.x (i.e. Right Headphone Switch vs. Headphone Switch Right). If using a 3.x kernel, and this isn't working properly, ensure the names match up to what amixer says they should be.

Pulseaudio configuration

Add the following if using Pulseaudio:

FILE /etc/pulse/default.pa
load-module module-alsa-sink device=sysdefault
load-module module-alsa-source device=sysdefault

See InstallingDebianOn/Asus/C201#Audio for further information. VEYRON-I2S shipped with alsa, so it's unlikely to need to add Google's UCM files.

HDMI is not tested. It appeared under 3.14 as RockchipHDMI, but is missing under 4.13. Possibly a kernel config or UCM issue.

Keybinds

xbacklight doesn't work, however, a backlight device exists. This script can be used in tandem with xbindkeys as a replacement for xbacklight:

FILE c201_backlight.sh
#!/bin/bash
if [ "$(($(cat /sys/devices/platform/backlight/backlight/backlight/brightness)+$1))" -gt "255" ];then
        echo 255 > /sys/devices/platform/backlight/backlight/backlight/brightness
        exit
fi
if [ "$(($(cat /sys/devices/platform/backlight/backlight/backlight/brightness)+$1))" -lt "0" ]; then
        echo 0 > /sys/devices/platform/backlight/backlight/backlight/brightness
        exit
fi

echo $(($(cat /sys/devices/platform/backlight/backlight/backlight/brightness)+$1)) > /sys/devices/platform/backlight/backlight/backlight/brightness

Provide the delta for the backlight as an argument, positive or negative.

This file is read-only by default, add this script to the local service if desired:

FILE /etc/local.d/backlight-permissions.start
chmod 666 /sys/devices/platform/backlight/backlight/backlight/brightness

This script needs to be marked executable by doing chmod +x

If reassigning the function keys for another purpose is desired, edit the /usr/share/X11/xkb/symbols/pc file.

In the following example, the search key (LWIN) has been remapped to Caps and set some of the function keys to much-needed movement keys. Also, the power button was remapped to the Delete key:

FILE /usr/share/X11/xkb/symbols/pckeys added to "pc105" xkb_symbols
key <LWIN>   {      [ Caps_Lock             ]       };
    key <FK01>   {      [ Home                  ]       };
    key <FK02>   {      [ End                   ]       };
    key <FK03>   {      [ Page_Up               ]       };
    key <FK04>   {      [ Page_Down             ]       };
FILE /usr/share/X11/xkb/symbols/inetreplaced items
key <POWR>   {      [ Delete                ]       };

Restart X for these changes to take effect.

To remove old files in /var/lib/xkb:

root #rm -rf /var/lib/xkb/*

Tips and tricks

  • There is only 16GB of internal storage space available. Consider using an SD card for /home and to compile larger packages on.
  • Backing up the ChromeOS partition (mmcblk0) is highly recommended, however it is not difficult restore ChromeOS after a failure. Create a restore USB medium through desktop Chrome or download the files manually to write to a USB drive.
  • Do not disable cros' developer mode! If the kernel fails to boot, the machine will not be able to boot from the install medium and will be forced to "powerwash" the Chromebook. Even if the kernel boots, crossystem/mosys is needed to change these flags. This is the solution if this happens on Libreboot, though wait for partition 5 to complete instead.

Known issues

If the bluetooth module is loaded at any time and the system is suspended, both the bluetooth and wireless driver will stop working. A temporary fix is to blacklist the btsdio module:

root #echo "blacklist btsdio" > /etc/modprobe.d/blacklist-btsdio.conf

sys-apps/lm_sensors does not work here. Query /sys/devices/virtual/thermal/thermal_zoneX/temp to get temperatures. This will average the two CPU sensors up and output in a sane format:

user $echo "$((($(cat /sys/devices/virtual/thermal/thermal_zone1/temp)+$(cat /sys/devices/virtual/thermal/thermal_zone2/temp))/2000))"

sys-power/acpi does not display the correct discharge time. This can be obtained through upower:

user $upower -i /org/freedesktop/UPower/devices/battery_sbs_20_000b

External resources

References

  1. Status Matrix, Rockchip open source Document. Retrieved on February 26th, 2019
  2. Developer mode screen, Libreboot documentation on depthcharge. Retrieved on February 25th, 2019
  3. Joel A Fernandes, Flattened Image Trees: A powerful kernel image format (PDF), Embedded Linux Wiki, February 21, 2013. Retrieved on February 25th, 2019
  4. Installing Debian On ASUS C201, DebianOn. Retrieved on February 26th, 2019
  5. ChromiumOS Git at Google. Retrieved on February 25th, 2019