Note

The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.

Funtoo Linux Installation on Chromebook Pixel 2015

From Funtoo
Revision as of 18:51, June 3, 2017 by Nethawk (talk | contribs)
Jump to navigation Jump to search

Introduction

This article is a collection of thoughts, knowledge and procedures discovered while installing Funtoo linux on the Google Chromebook Pixel 2015. It is aimed to provide a concise explanation as well as a walkthrough of the components and steps required. However it will not go into the details of the applications or technologies, leaving that to external documentation.

   Note

This is an ongoing effort, e.g Under Construction

   Note

While installing this machine I first wanted to just wipe everything and install Funtoo, but decided to dual boot at first to see how it behaves, identify possible optimizations etc., before wiping the rest of the ChromeOS installation. That being said, it might be worth noting that I did remove the firmware protection and set the flags as described in #Setting seaBIOS as default boot option before setting out on actually installing anything. So verification of certain parts of this article is required.

   Important

Do anything described here or in the linked articles at your own risk, you may damage or otherwise make your device unusable and might need to contact Google for support. Be sure to read this article and all linked articles carefully, and only proceed to do something when you are sure you know what it does.

Developer Mode

Putting the Chromebook in developer mode is a requirement. Also get accustomed to opening the shell and gaining root privileges. Note that changes to ChromeOS's root filesystem are not required for this, so no need to disable root filesystem verification.

Crouton

It was suggested that crouton is a viable alternative to installing a separate Linux distribution. The advantage is that it's simple and requires no partitioning. The downside are that your are limited in distribution choice.

Dual Booting vs. Funtoo only

There are some differences in how to install the system for either dual booting with ChromeOS or removing it. Most notably, it is reported that if the "Signed boot verification" is enabled and ChromeOS is replaced with a different system, "...then your system might become corrupted on empty battery, resetting dev_boot_usb dev_boot_legacy to their default values, forcing you to recover Chrome OS..."[ Arch linux wiki ].

To avoid this, you can either Dual Boot or #Setting seaBIOS as default boot option and install Funtoo only. Another way would be to extract the kernel from ChromeOS and use that.

   Note

I already disabled "Signed boot verification", so someone needs to try this without touching the firmware to confirm that dual boot works with unsigned kernels.

Preparing for Installation

To prepare an additional or alternative operating system we will need to do some common setup, like enabling usb and legacy boot and preparing the installation media, but it is also highly recommended to make a full #Backup of the system before beginning .

Enabling USB boot

To enable usb boot run the following on ChromeOS as root:

root # crossystem dev_boot_usb=1 dev_boot_legacy=1

Preparing and testing the installation media

Installation can occur from pretty much any linux live environment, however for this article we'll be using system rescue cd. In order to make sure you can boot to the live environment, reboot your device and press ctrl+d at the white screen just before ChromeOS boots. You should now be greeted by the SeaBIOS boot system from where you can boot your live environment. Please note that you might have to play with the resolution options, especially for early boot print messages. What works for me in that case is to set vga=340 as parameter.

Backup

After booting a live environment like system rescue cd and mounting a large enough USB key (stock machines require about 2.0GB) you can take a full backup with:

root # dd if=/dev/sda | gzip > /mnt/usb_key/chromebook_pixel_2015_dd_backup.gzip

Setting SeaBIOS as default boot option

   Important

This step is only required for removing ChromeOS and installing funtoo on the whole drive. The steps in this section are all done in ChromeOS not the installation medium environment.

   Warning

This may damage your system, do at your own risk. You have been warned. Follow the steps on Developer Information from Chromium to remove the firmware write protection]. After this is done, do not reassemble the Chromebook. Turn it around, put it on a non-conductive, clean, clutter free surface and follow the steps below.

The first thing we need to do is disable the software write protection. Open a root shell and run flashrom --wp-status which will output something similar to:

flashrom v0.9.4  : 1d2f41b : Nov 12 2015 16:39:03 UTC on Linux 3.14.0 (x86_64), built with libpci 3.1.10, GCC 4.9.x-google 20150123 (prerelease), little endian
WP: status: 0x0080
WP: status.srp0: 1
WP: status.srp1: 0
WP: write protect is enabled.
WP: write protect range: start=0x00000000, len=0x00000000

To disable it run flashrom --wp-disable and double check if the command was successful with flashrom --wp-status.

Now it's time to set the GBB Flags, enter /usr/share/vboot/bin, from there run set_gbb_flags.sh -h which will produce an output similar to the following:

root # ./set_gbb_flags -h
Changes ChromeOS Firmware GBB Flags value.

  Usage: /usr/share/vboot/bin/set_gbb_flags.sh [option_flags] GBB_FLAGS_VALUE
  
  Defined flags (some values may be not supported by all systems):

  GBB_FLAG_DEV_SCREEN_SHORT_DELAY            0x00000001
  GBB_FLAG_LOAD_OPTION_ROMS                  0x00000002
  GBB_FLAG_ENABLE_ALTERNATE_OS               0x00000004
  GBB_FLAG_FORCE_DEV_SWITCH_ON               0x00000008
  GBB_FLAG_FORCE_DEV_BOOT_USB                0x00000010
  GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK         0x00000020
  GBB_FLAG_ENTER_TRIGGERS_TONORM             0x00000040
  GBB_FLAG_FORCE_DEV_BOOT_LEGACY             0x00000080
  GBB_FLAG_FAFT_KEY_OVERIDE                  0x00000100
  GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC          0x00000200
  GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY           0x00000400
  GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC          0x00000800
  GBB_FLAG_DISABLE_LID_SHUTDOWN              0x00001000
  GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP  0x00002000
  GBB_FLAG_ENABLE_SERIAL                     0x00004000

  To get a developer-friendly device, try 0x11 (short_delay + boot_usb).
  For factory-related tests (always DEV), try 0x39.
  For early development (disable EC/PD software sync), try 0xa39.

flags:
  -d,--[no]debug:  Provide debug messages (default: false)
  -f,--file:  Path to firmware image. Default to system firmware. (default: '')
  --[no]check_wp:  Check write protection states first. (default: true)
  -h,--[no]help:  show this help (default: false)

The options we are interested in are:

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

These options will set your device to boot to SeaBIOS by default. If we put these together we get 489, so the command we need to run becomes ./set_gbb_flags.sh 0x489. Note that ChromeOS is still available, but now the booting is reversed ( e.g. ctrl+d on the white screen is now ChromeOS).

Once this is complete, re-enable the write protection with flashrom --wp-enable. Check if it still turns on, boots to SeaBIOS by default and to ChromeOS via ctrl+d. Finally turn the device completely off shutdown -h now. Proceed to putting the write protection back into place and reassemble the device.

Preparing the hard drive

There are two distinct ways in which you can prepare the hard drive, either for dual booting purpouses or for installing Funtoo only. The later option should be easier, but will require you to #Setting SeaBIOS as default boot option. In both scenarios your data on the ChromeOS's State drive will be lost. This is the local data, not the one synced with Google's cloud system. Nonetheless it is recommended to make a backup of the files you hold dear at this point.

Preparing for Dual-Boot

Chrome OS has a distinct partition layout that it depends on. For more information on the specifics of the ChromeOS boot and partition layout visit the Chromium documentation. Fortunately there is a partition that is unused for now (as described in the drive partition documentation on Chromium.org). The KERN-C and ROOT-C partitions are "Minimal-size partition for future third kernel. There are rare cases where a third partition could help us avoid recovery mode (AU in progress + random corruption on boot partition + system crash). We decided it's not worth the space in V1, but that may change". The space for our new Funtoo installation will come from the STATE drive of ChromeOS (" User's browsing history, downloads, cache, etc. Encrypted per-user."), which means we'll shrink this partition and allocate the newly gained space to KERN-C and ROOT-C. While it will be explained how to do this manually, you can use the chromeShrinkState script to simplify this process. Simply put this script onto a USB key for now.

It is recommended to fully shutdown the chromebook and restart it at this point. Do not login to ChromeOS, press ctrl+alt+f2 at the login prompt to be taken to VT2, and login as the "chronos" user and run sudo to gain root privileges. Turn off powerd to stop the display timing out, the ui and cryptohomed to stop processed from using the state partition:

root # initctl stop ui

Note that stopping the "ui" will log you out and you will have to log back in and gain root privileges.

root # initctl stop  cryptohomed
root # initctl stop powerd

Check where /dev/sda1 is mounted with:

root # mount | grep /dev/sda1
/dev/sda1 on /mnt/stateful_partition type ext4 (rw,nosuid,nodev,noexec,relatime,commit=600,data=ordered)
/dev/sda1 on /home type ext4 (rw,nosuid,nodev,noexec,relatime,commit=600,data=ordered)
/dev/sda1 on /usr/local type ext4 (rw,nodev,relatime,commit=600,data=ordered)

Check if anything is using these mounts and kill any processes using them:

root # lsof | grep /home
root # lsof | grep /home
root # lsof | grep /usr/local

You can now proceed to run chromeShrinkState from the USB drive. Make sure to boot into ChromeOS after the script finishes to rebuild it's state partition. The rest of this section will explain how this is done manually, so read on if you'd like to do it that way or know what the script is doing.

Manually repartitioning

First it is recommended to check if ROOT-C and KERN-C are size 1 cgpt show -i 6 -s /dev/sda and cgpt show -i 7 -s /dev/sda. Make sure this is the case as otherwise it means that there is something already on those partitions.

To repartition the state drive we'll need some info, specifically we'll need to know the current size and start of the state partition cgpt show -i 1 -s /dev/sda and cgpt show -i 1 -b /dev/sda. To help with the calculations we can assign variables to this values state_size=cgpt show -i 1 -s -q /dev/sda and state_start=cgpt -i 1 -b -q /dev/sda .

We need the size of the root filesystem in sectors, which are 512B in size. We can use the simple formula "N*1024*1024*2" where N is the number of GigaBytes or "N*1024*2" in the case of MegaBytes root_size=$((GB*1024*1024*2)) . We will also do the same for kern_size: kern_size=$((MB*1024*2)) which will host our boot partition. To calculate the new state size, we need to substract both root and kern size from the current state size: state_size_new=$(($state_size - $kern_size -$ root_size)). The last things we need are the new start sectors for kern and root, which can be found by adding the state_size to state_start for kern_start and later add kern_start and kern_size to form root_start: kern_start=$(($start_start + $state_size_new)) and root_start=$(($kern_start + $kern_size)).

Now we can proceed to write the new partition table:

root # cgpt add -i 1 -b $state_start -s $state_size_new -l STATE /dev/sda
root # cgpt add -i 6 -b $kern_start -s $kern_size -l KERN-C -t "kernel" /dev/sda
root # cgpt add -i 7 -b $root_start -s $root_size -l ROOT-C /dev/sda

Once finished you will need to reboot, make sure to boot into ChromeOS first for it to rebuild it's state partition before continuing.

Preparing for Funtoo only

Preparing for a single operating system, or even multiple linux systems is easy, as long as your willing to remove ChromeOS completely. Make sure to read #Setting SeaBIOS as default boot option and be sure you understand the risks of disabling the firmware write protection. Once SeaBIOS is set as the default boot option you can boot into the live environment and partition the drive as per the Installation guide.

Installation

The installation generally follows the Funtoo installation guide, however some of the steps need to be amended for the device to work properly.

Profile Settings

Once you have successfully booted into the system you should set up the Funtoo profile settings for consequent builds. First select the intel64-broadwell subarch profile using the ego tool.

root # ego profile subarch intel64-broadwell

Next, select appropriate mix-ins depending on required functionalities. Select X for running Xorg server and WM or Desktop environments. Another option is no-systemd for an OpenRC based init-system (default for Gentoo/Funtoo).

root # ego profile mix-ins X no-systemd

You can list all available profile settings:

root # ego profile list

=== flavor: ===

    core*, desktop, hardened, minimal, server, workstation

=== build: ===

    (current*), experimental, stable

=== arch: ===

    arm-32bit, pure64, x86-32bit, (x86-64bit*)

=== subarch: ===

    amd64-bulldozer, amd64-excavator, amd64-jaguar, amd64-k10
    amd64-k8, amd64-k8+sse3, amd64-piledriver, amd64-steamroller
    atom_64, btver1_64, core-avx-i, core2_64, corei7, generic_64
    intel64-broadwell*, intel64-haswell, intel64-ivybridge, intel64-nehalem
    intel64-sandybridge, intel64-silvermont, intel64-westmere
    native_64, nocona, opteron_64, xen-pentium4+sse3_64

=== mix-ins: ===

    X*, audio, cinnamon, console-extras, dvd, gnome, gnome-3.16-fixups
    hardened, kde, kde-plasma-5, lxde, lxqt, mate, media, media-pro
    mediadevice-audio-consumer, mediadevice-audio-pro, mediadevice-base
    mediadevice-video-consumer, mediadevice-video-pro, mediaformat-audio-common
    mediaformat-audio-extra, mediaformat-gfx-common, mediaformat-gfx-extra
    mediaformat-video-common, mediaformat-video-extra, no-emul-linux-x86
    no-systemd*, openvz-host, print, python3-only, vmware-guest
    xfce

Kernel choice and Configuration

Although current Funtoo Linux stage3's include a prebuilt sys-kernel/debian-sources kernel which should boot the Pixel fine, there may be issues with it as not all drivers for the pixel are available yet. The other option is to use the linux-samus kernel from https://github.com/raphael/linux-samus. Clone the repository to your /usr/src/ folder. Create a link from the linux-samus kernel to /usr/src/linux:

user $ cd /usr/src/linux
user $ git clone https://github.com/raphael/linux-samus
user $ ln -snf /usr/src/linux-samus /usr/src/linux

Before building/configuring the kernel, you might want to branch the repository and then patch it with genpatches from: https://dev.gentoo.org/~mpagano/genpatches/ . This will add the gentoo/funtoo required options in a top level category and select them.

user $ git branch linux-samus-<version>-genpatches
user $ git checkout linux-samus-<version>-genpatches
user $mkdir genpatches
user $cd genpatches
user $ wget https://dev.gentoo.org/~mpagano/genpatches/tarballs/genpatches-<version>.base.tar.xz
user $ wget https://dev.gentoo.org/~mpagano/genpatches/tarballs/genpatches-<version>.extras.tar.xz
user $wget https://dev.gentoo.org/~mpagano/genpatches/tarballs/genpatches-<version>.experimental.tar.xz
user $ for x in $(ls); do tar xf $x; done
user $cd ../linux/
user $for patch in $(find /usr/src/linux-samus/genpatches/ -iname *.patch

After you have successfully patched the kernel sources, you can follow the typical kernel installation:

user $ cd linux-samus/build/linux
user $ make nconfig
user $ make -j4
user $ sudo make modules_install
user $ sudo make install

Assuming GRUB is installed and MBR boot is working as per article Funtoo Install Guide - Installing Bootloader Once the kernel is built and copied to /boot, entry must be added to /etc/boot.conf eg:

root #  printf "\"Funtoo linux-samus 4.4.2\" { \n  kernel vmlinuz-4.4.2ph \n }"  >> /etc/boot.conf
   Note

If you wish to select this kernel as default option you can change default setting in /etc/boot.conf

Then run boot-update

root # boot-update
boot-update 1.7.3 /
Copyright 2009-2015 Funtoo Technologies

 [use option "-l" for license info, "-h" for help]

 * Generating config for grub...

           Funtoo Linux - Kernel-4.5.3-Chromebook_pixel_2015
           Funtoo 4.4.4 Linux - Kernel-4.4.4-Chromebook_pixel_2015
 DEFAULT >  Funtoo linux-samus 4.4.2 - vmlinuz-4.4.2ph

 * NOTE : Detected MBR boot. Configuring for Legacy MBR booting.
 * Completed successfully.

Graphics

In order to run X with hardware acceleration supported by the HD Graphics 5500 GPU first set VIDEO_CARDS in /etc/portage/make.conf.

   /etc/portage/make.conf - Add the following line
VIDEO_CARDS="intel i965"

When No results and No results are installed, the VIDEO_CARDS USE_EXPAND flag will ensure installation of correct drivers. Additional USE flags for intel drivers can also be used.

   /etc/portage/package.use/xf86-video-intel - Use flags
x11-drivers/xf86-video-intel dri3
   /etc/portage/package.use/xorg-server - Use flags
x11-base/xorg-server glamor

Touchpad

Once you have booted in the linux-samus kernel you should run the linux-samus/scripts/setup/touchpad/enable-atmel.sh script.

user $  cd linux-samus/scripts/setup/touchpad
user $  ./enable-atmel.sh

This will setup the Atmel touchpad and touchscreen devices. Although No results will use x11-drivers/xf86-input-synaptics drivers for the touchpad, this configuration seems to work. Config file /etc/X11/xorg.conf.d/25-touchpad.conf can be edited for preferred behavior.

   /etc/X11/xorg.conf.d/25-touchpad.conf - This is a sample config that enables some capabilities of the touchpad
Section "InputClass"
    Identifier "touchpad"
    MatchIsTouchpad "on"
    MatchDevicePath "/dev/input/event*"
    Driver "synaptics"
        Option "TapButton1" "1"
        Option "TapButton2" "3"
        Option "TapButton3" "2"
        Option "VertEdgeScroll" "on"
        Option "VertTwoFingerScroll" "on"
        Option "HorizEdgeScroll" "on"
        Option "HorizTwoFingerScroll" "on"
        Option "CircularScrolling" "on"
        Option "CircScrollTrigger" "2"
        Option "EmulateTwoFingerMinZ" "40"
        Option "EmulateTwoFingerMinW" "8"
        Option "CoastingSpeed" "0"
        Option "FingerLow" "30"
        Option "FingerHigh" "50"
        Option "MaxTapTime" "175"
	Option "VertScrollDelta"          "-50"
        Option "HorizScrollDelta"         "-50"
EndSection

You can refer to man pages to see all available options.

user $  man synaptics
   Note

If you wish to use xf86-input-cmt driver follow the steps below. You'll have to build it yourself with additional libraries ported from ChromeOS

   Important

If you wish to use ported drivers you should remove the default Synaptics package and its configuration file.

There is a script touchpad-cmt.sh included in linux-samus/scripts/setup/touchpad/. It will attempt to download libraries libgestures, libdevc and xf86-input-cmt X11 ChromiumOS touchpad driver ported to Linux from Hugh Greenberg's repositories. Requirement for libgestures is No results so let's install that first:

root # emerge -a jsoncpp

Then we run the setup script:

root #  cd linux-samus/scripts/setup/touchpad
root #  ./touchpad-cmt.sh

It will copy 40-touchpad-cmt.conf and 50-touchpad-cmt-samus.conf to /etc/X11/xorg.conf.d/. Both files contain relevant settings for this particular touchpad. Because this scripts removes working directories after it is done, you can find other configurations in the xf86-input-cmt repo.

   /etc/X11/xorg.conf.d/50-touchpad-cmt-samus.conf - Useful options
Option          "Australian Scrolling" "1" # Enables inverse scrolling with two fingers

Audio

In order to have fully functional audio on Pixel, ALSA and No results are needed.

   Note

ALSA support must be enabled in kernel. Linux-samus kernel config already has all the necessary options enabled.

Before necessary packages are emerged, we can set some useful global USE flags in /etc/portage/make.conf. Needed flags are alsa sound pulseaudio acpi. Then emerge No results along with three needed ALSA packages: No results, No results, No results.

root # emerge -a pulseaudio alsa-utils alsa-plugins alsa-lib

For headphone/speaker automatic switching to work sys-power/acpid is needed as well. If it is not yet installed this is a good time to run

root # emerge -a acpid

and then

root # rc-update add acpid default

to have the service start at boot time.

   Note

Pulseaudio also requires No results for permission management. For more information about Pulseaudio please check the wiki.

Next step is to run setup.sh script found in linux-samus/scripts/setup/sound.

user $  cd linux-samus/scripts/setup/sound
user $  ./sound.sh

This script attempts (as is documented in the readme of the linux-samus repository) to execute the next steps:

1. Copy firmware from linux-samus/firmware/ to /lib/firmware/

2. Set card order so that rt5677 is in the first slot (copies linux-samus/scripts/setup/sound/modprobe.d/alsa-bdwrt5677.conf to /etc/modprobe.d/)

   /etc/modprobe.d/alsa-bdwrt5677.conf - alsa-bdwrt5677.conf file
options snd slots=snd_soc_sst_bdw_rt5677_mach,snd-hda-intel

3. Set ALSA UCM verb

ALSA Use Case Manager (UCM) allows applications to access the hardware in an abstracted manner so that the applications don't need to be tailored for each hardware product separately. The system is designed especially for embedded systems, where the amount of different mixer controls for routing and volume is massive. The idea is that an application tells UCM that it needs to do e.g. voice call, and UCM then takes care of adjusting the mixer controls appropriately. UCM also tells the application which PCM device to use and how to do volume control for that use case.

   Important

It seems this is not really needed, as it breaks Pulseaudio automatic detection of the soundcard via udev module. If this happens just remove the directory bdw-rt5677 from /usr/share/alsa/ucm

4. Set the microphone device by statically loading the driver in Pulseaudio config file /etc/pulse/default.pa. Lines added are:

load-module module-alsa-source device=hw:0,1
load-module module-alsa-source device=hw:0,2
   Important

Those lines must be added before the line

load-module module-udev-detect

5. Restore ALSA state (config) for speakers from linux-samus/scripts/setup/sound/alsa/speakers.state

6. Setup ACPI hooks for switching between headphones and speakers. It does this by copying event and action handlers from linux-samus/scripts/setup/sound/events/ and linux-samus/scripts/setup/sound/actions/ to /etc/acpi/respectively.

   Important

The action script for headphone plug/unplug event does not work correctly because the PULSE_RUNTIME_PATH variable is not correctly set. For this to work correctly the file /etc/acpi/actions/samus.sh must be corrected.

Open the file in a text editor and replace lines 20 and 21:

PULSE_RUNTIME_PATH=$(find /tmp -name "pulse-*" -type d -readable -prune)
PULSE_RUNTIME_PATH=${PULSE_RUNTIME_PATH:-"/run/user/$(id -u $USER)/pulse/"}

with lines

PULSE_RUNTIME_PATH=$(find /tmp -name "xdg-*" -type d -readable -prune)
PULSE_RUNTIME_PATH=${PULSE_RUNTIME_PATH}/pulse

If you decide to run the sound.sh script provided, go over steps 3. and 6. if you encounter any issues. This should guarantee working sound on Funtoo system.