Michael's Daemonic Doodles

...blogging bits of BSD

Running FreeBSD on the Acer C720 Chromebook

This is about the original version of the Acer C720 (1.4GHz Celeron 2955U). There are other versions like the Acer C720p (touchscreen) or the faster Acer C720-3870 (1.7GHz Core i3). While some of these instructions might still work, they haven't been tested on those models.

This little machine is cheap and quite fast. Battery life is great. Installing FreeBSD required some effort though.

Enable legacy boot

Warning: This might void your warranty. It might break your machine. This is at your own risk.

The procedure below has been taken from the ArchLinux Wiki.

The short version is:

  1. Open laptop by removing all screws at the bottom (voids warranty)
  2. Remove write protect screw on mainboard
  3. Boot into start screen
  4. Press CTRL-ALT-F2
  5. Log in as "chronos"
  6. sudo bash
  7. crossystem dev_boot_usb=1 dev_boot_legacy=1
  8. set_gbb_flags.sh 0x489
  9. Power off
  10. Insert write protect screw
  11. Close laptop

Note

I'd recommend to use one of the many tutorials out there which give you detailed instructions on how to do this procedure correctly. It will void your warranty, but since you probably want to add a bigger SSD to the machine and it is dirt cheap that's probably a risk worth taking. If you're planning to replace the SSD, make sure to get the correct form factor (M.2 2242).

Installation media

As of r285883 (2015-07-25) all required patches are part of FreeBSD-CURRENT.

There is also a backported patch for FreeBSD 10.2-RELEASE.

Install the basic OS

Installing the OS is quite easy, simply put the USB stick and use the standard bsdinstall installer. I used encrypted ZFS on root in my experiments with great success.

System console

There is an unresolved issue when using root file system encryption and the vt(4) console driver, resulting in unreliable keyboard input. This can be mitigated by using the traditional syscons(4) console driver:

echo 'kern.vty=sc' >>/boot/loader.conf

Keyboard

You probably want to disable acpi power down (which is right above backspace) to avoid unintended shutdowns:

echo "hw.acpi.power_button_state=NONE" >>/etc/sysctl.conf

You then install a custom keymap:

kbdcontrol -d >/etc/c720.kbd
echo 'keymap="/etc/c720.kbd">>/etc/rc.conf'

Make sure you loaded your preferred keymap before doing this. Now modify /etc/c720.kbd, so that slock is mapped to something else (so you have scroll lock at the console), I used the last column of scan code 068 for this (so scroll lock is CTRL-ALT-SHIFT-F10).

Then add an additional line for scan code 109, that has an entry for pdwn in the alt-shift column, so that ALT-SHIFT-Power shuts the machine down. The resulting to lines should look like this:

068   fkey10 fkey22 fkey34 fkey46 scr10  scr10  scr10  slock   O
...
109   nop    nop    nop    nop    nop    pdwn   nop    nop     O

Sound

Sound is provided by snd_hda, which is part of the standard kernel. You need to modify /boot/device.hints for routing to work correctly. I used one of these two options:

  1. Keep speakers and headphone jack separate (two separate audio devices):

    cat >>/boot/device.hints <<EOF
    hint.hdaa.1.nid26.config="as=2"
    hint.hdaa.1.nid33.config="as=3"
    EOF
    
  2. Use headphone jack like most people do (recommended):

    cat >>/boot/device.hints <<EOF
    hint.hdaa.1.nid20.config="as=3 seq=0"
    hint.hdaa.1.nid26.config="as=2 seq=14"
    hint.hdaa.1.nid25.config="as=2 seq=15"
    hint.hdaa.1.nid33.config="as=3 seq=15"
    EOF
    

And reboot. You can also set those during runtime using sysctl. Testing sound:

pkg install xmp ca_root_nss
mixer vol 90
mixer pcm 90
fetch https://blog.grem.de/spacedeb.mod.gz
xmp spacedeb.mod.gz

Recording has been tested successfully using the second configuration option. The built-in microphone shows up as monitor, external microphones (e.g. part of a head set) as mic. It's best to record from mix.

Testing recording (built-in mic):

pkg install sox
mixer rec 100 speaker 0 monitor 100 mic 0 mix 100 igain 0 =rec mix
rec -c 2 out.wav
(Ctrl-C)
play out.wav

Testing recording (external mic):

pkg install sox
mixer rec 100 speaker 0 monitor 0 mic 100 mix 100 igain 0 =rec mix
rec -c 2 out.wav
(Ctrl-C)
play out.wav

USB and SD card reader

USB works out of the box. In case you've built a stripped down kernel, load the ehci module:

kldload ehci

SD cards show up as umass(4) devices on insert and can be mounted like any other USB device.

Battery life

In general, battery life is very good on this device, I enabled powerd to make it even better (results were OK):

echo 'powerd_enable="YES"' >>/etc/rc.conf
echo 'powerd_flags="-a hiadaptive -b adaptive"' >>/etc/rc.conf

You can save a bit of power by shutting down various devices using usbconfig:

[root ~]# usbconfig
ugen0.1: <EHCI root HUB Intel> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.2: <product 0x8000 vendor 0x8087> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen1.1: <XHCI root HUB 0x8086> at usbus1, cfg=0 md=HOST spd=SUPER (5.0Gbps) pwr=SAVE (0mA)
ugen1.2: <HD WebCam SunplusIT Inc> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA)

[root ~]# usbconfig -d ugen1.2 power_off
[root ~]# usbconfig
ugen0.1: <EHCI root HUB Intel> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.2: <product 0x8000 vendor 0x8087> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen1.1: <XHCI root HUB 0x8086> at usbus1, cfg=0 md=HOST spd=SUPER (5.0Gbps) pwr=SAVE (0mA)
ugen1.2: <HD WebCam SunplusIT Inc> at usbus1, cfg=255 md=HOST spd=HIGH (480Mbps) pwr=OFF (500mA)

You can also use acpiconf -i batt | grep rate to check power consumption.

Touchpad

To load the touchpad driver you've got to load the following kernel modules:

kldload ig4
kldload cyapa

To load the touchpad driver at boot time do:

echo 'ig4_load="YES"' >>/boot/loader.conf
echo 'cyapa_load="YES"' >>/boot/loader.conf

The easiest way to enable the touchpad in X11 is to use moused:

echo 'moused_enable="YES"' >>/etc/rc.conf
echo 'moused_port="/dev/cyapa0"' >>/etc/rc.conf
service moused start

See man 4 cyapa for details on the touchpad driver and its configuration options.

Light sensor

The inbuilt Digital Ambient Light and Proximity Sensor can be used by loading the isl module:

kldload isl
kldload ig4

You can get readings by using sysctl:

sysctl dev.isl.0

The driver doesn't provide any useful features beyond this right now.

To load the light sensor driver at boot time do:

echo 'ig4_load="YES"' >>/boot/loader.conf
echo 'isl_load="YES"' >>/boot/loader.conf

Wireless LAN

WiFi works out of the box using the menu. The resulting /etc/rc.conf looks like this:

wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"
ifconfig_wlan0_ipv6="inet6 accept_rtadv"

The last line was added manually to use IPv6 on my home LAN. In general it's easier to use bsdinstall, otherwise you'll have to deal with /etc/wpa_supplicant.conf manually.

Customizing X11 keyboard

I use the following in my ~/.xinitrc to customize the keyboard for my needs:

# set German keyboard and relocate modifiers
setxkbmap -model pc105 -layout de -option "altwin:swap_alt_win" -option "lv3:ralt_switch"

# load xmodmap
xmodmap $HOME/.Xmodmap

~/.Xmodmap contains:

keycode 145 = Delete Delete Delete Delete

so that power (above backspace) serves as forward delete.

Customizing X11 keyboard even more (PgUp/PgDown)

Note

The exact configuration required depends on your specific keyboard layout.

If you want to further customize the keyboard, you can do so by using xkbcomp. Running your desired keyboard layout do:

xkbcomp $DISPLAY ~/.keymap.xkb

Edit this file and add the following to the xkb_keycodes section:

<DELE> = 145;

and this to the xkb_symbols section:

replace key <UP> {
      type[Group1]= "THREE_LEVEL",
      symbols[Group1]= [ Up, Up, NoSymbol ],
      actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<PGUP>, clearMods=Mod5) ]
};
replace key <DOWN> {
      type[Group1]= "THREE_LEVEL",
      symbols[Group1]= [ Down, Down, NoSymbol ],
      actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<PGDN>, clearMods=Mod5) ]
 };

In my case the complete file looks like this:

xkb_keymap {
        xkb_keycodes  { include "xfree86+aliases(qwertz)"
                <DELE> = 145;
        };
        xkb_types     { include "complete"      };
        xkb_compat    { include "complete"        };
        xkb_symbols   { include "pc+de+inet(pc105)+altwin(swap_alt_win)+level3(ralt_switch)"
                replace key <UP> {
                        type[Group1]= "THREE_LEVEL",
                        symbols[Group1]= [ Up, Up, NoSymbol ],
                        actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<PGUP>, clearMods=Mod5) ]
                };
                replace key <DOWN> {
                        type[Group1]= "THREE_LEVEL",
                        symbols[Group1]= [ Down, Down, NoSymbol ],
                        actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<PGDN>, clearMods=Mod5) ]
                };
        };
        xkb_geometry  { include "pc(pc105)"        };
};

Finally, replace the lines calling setxkbmap and xmodmap in ~/.xinitrc with:

xkbcomp $HOME/.keymap.xkb $DISPLAY

Now you can use ISO_Level3_Shift (AltGr) + Up/Down to emit PgUp/PgDown and power (above backspace) as forward delete.

Fix X11 screen resolution

The VESA driver uses a resolution of 1368x768 by default, even though the panel's physical resolution is only 1366x768. You can change this in different ways, one easy way is to add this to ~/.xinitrc before the window manager is started:

xrandr --output default --mode 1366x768

Backlight control

Backlight can be controlled using graphics/intel-backlight.

Installation:

pkg install intel-backlight

You can then control brightness using:

intel_backlight <percent>
intel_backlight incr
intel_backlight decr

Percent is a number between 1 and 100, incr will increase brightness, decr will lower brightness. Depending on your desktop environment used, you can easily map a modifier + F6/F7 (which are labeled as brightness up/down) to execute intel_backlight decr / intel_backlight incr.

Using the isl driver described above, you can adjust screen brightness automatically based on lighting conditions. graphics/intel-backlight installs an example script /usr/local/share/examples/intel-backlight/isl_backlight.sh. See also man 4 isl for further details.

Screensaver

An effective way to save power is to turn off the backlight automatically if the system isn't used. One way to accomplish this is to use xset in ~/.xinitrc:

xset dpms 60

This turns off the display after 60 seconds without user input and cuts power consumption by about 30%.

For proper locking of your screen use a screensaver like xautolock, I'm using this line in my ~/.xinitrc:

xautolock -locker 'sh -c "xset dpms 10 && slock && xset dpms 0"' \
-corners +000 -time 2 -cornerdelay 1 -cornerredelay 10 &

This locks the screen after two minutes of inactivity and turns off the screen 10 seconds later. It also allows immediate locking by moving the mouse pointer to the upper left corner. It requires xautolock and slock, which both can be installed using pkg:

pkg install xautolock slock

Starting X

If you did all the steps above, no xorg.conf is required and you can start X simply by calling startx. This uses the VESA driver, unfortunately Haswell graphics support is still not there.

HDMI Output

Connecting an external screen works in VESA mode and mirrors the built-in panel. As it doesn't show up in xrandr, there doesn't seem to be a way to change its output to anything else. Good enough for presentations or watching a video. There's no HDMI audio, even though the snd_hda device does show up in /dev/sndstat.

Webcam

The webcam works if USB is enabled. Install webcamd and enable/start it:

pkg install webcamd
echo 'webcamd_enable="YES"' >>/etc/rc.conf
service webcamd start
kldload cuse4bsd

# testing
pwcview

Suspend

Right now suspend doesn't work. I suspect that this might start working once Haswell graphics support becomes available.

Questions?

If you have questions, remarks, ideas for improvements etc. feel free to contact me.