Native GNU/Linux on a Toshiba Chromebook 2

Hardware

Two years ago I bought a Chromebook for my mom to replace her aging Windows laptop. It's a fanless Toshiba Chromebook 2 model CB-30-B-104, Bay Trail-based, with 4 GiB RAM, and a 1920x1080(!) IPS(!!) 13" screen. One of the nicest Chromebook's I've seen, especially considering the price.

I played around with it a bit and was so smitten by its simple operation that I bought one for myself as well.

I've been using this little machine as my travel and conference laptop, taking it to places I wouldn't want to bring a real laptop or, indeed, bring something with any sensitive data on it. It has worked quite well for this purpose.

I have to admit the real threat here is not that someone would waste something like a 0-day on insignificant little me; the real threat is that I would have a pint too many and forget the laptop somewhere. I'd rather lose this cheap piece of plastic than, say, a maxed out Macbook Pro.

Chrome OS

Most of the time I've been using the stock Chrome OS. Both SSH and mosh are available as free apps, so I can connect to some Real Machines if need be. Even mounting filesystems over SFTP works. It's been quite useful as a terminal, for general web browsing, and taking notes.

I tried a lot of Chrome app text editors, even some Emacs look-alike Chrome apps. They weren't that usable, I'm afraid, so I ended up using Caret and Txt or just moshing into a real server and using Emacs.

I also tried using the Native Client port of Emacs, which is part of webports but it wasn't really usable, so I tried using Crouton to get the real Emacs running. Crouton basically installs a GNU/Linux distribution in a chroot, using the Chrome OS Linux kernel but its own userland. You can install whatever packages you need as usual.

Crouton, however, can only be installed by enabling the Chromebook's Developer Mode and that means turning off verified boot. I thought that was a bit much for a locked-down conference computer, so I ditched Crouton and continued using ChromeOS apps for a while.

Fast forward to a recent trip to Berlin... Some acquaintances are hoarding old Thinkpad X60's for use as (more) secure and libre laptops. The X60 can run Coreboot and be used with Subgraph or Qubes. That got me thinking --- this Chromebook also uses Coreboot and it's possible to flash your own firmware... Can I run my own Linux kernel on the thing? It might be asking too much to run Subgraph or Qubes, but can it at least run some more normal distribution natively?

Installing

First, you need to be able too boot something else than ChromeOS at all. Turn on Developer Mode.

Thanks to John Lewis' great work it's possible to flash your own firmware in many Chromebooks. My model has a vacant RW_LEGACY slot in the flash, so I could flash just that slot with SeaBIOS, without touching the rest of the existing firmware. Small risk of bricking the device during my testing.

I thought about testing Void and Alpine, both using the small musl libc and being quite tiny, and got as far as booting to the installer in Void, but the installer crashed on the final steps. I also considered Arch and I might revisit one of these later.

In the meantime, I found GalliumOS, which is basically Xubuntu (the Ubuntu flavour with the XFCE desktop instead of Unity) with a specialized kernel for Chromebooks, swapping against zram, et cetera. The installer couldn't configure the network, however, but I changed to another virtual console and configured it manually so I could get on with the install. Everything work fine after that, including setting up full-disk encryption.

I chose not to touch the internal SSD and instead installed GalliumOS on an encrypted USB stick. It might wear down after little use, I guess, so I'm in the market for something like a small form-factor SSD with a USB 3.0 interface, if there is such an animal. Initial duckduckgoing seems to indicate they do exist.

Running GalliumOS and XFCE

At first, I used the XFCE desktop and tried things out.

XFCE screenshot

(Screenshot was actually taken after I had configured a lot of things, so not exactly what the GalliumOS desktop looked like at first.)

What works:

Development

I installed clang and golang and tried compiling a few things, for instance my fork of agl's xmpp-client. For smaller programs the Chromebook is quite sufficient for development, but the wear on the USB stick might be too much in the long run.

The Emacs package in GalliumOS, even emacs-nox, is linked with nasty stuff like libxml2. I don't want any of those in an Emacs where I might be editing something sensitive, so naturally I had to compile my own Emacs without at least the worst offenders.

Running without a desktop

Stop the graphical login:

# systemctl set-default multi-user.target

If you ever want the graphical login back you can set it back to graphical.target.

I set up a simple .xinitrc which calls my own window manager, mcwm, instead of the entire XFCE desktop. I now login to the Linux console and start X, if I want to, with plain old startx.

mcwm screenshot

I also experimented with the rather nice dwm tiling window manager. Julian Goldsmith rewrote dwm using XCB instead of Xlib: dwm-xcb, which feels snappier and eats less RAM. Either one feels completely natural on a laptop's small screen.

dwm screenshot

(Here with the Terminus pixel font and a small status script that show battery charge and current date & time.)

The .xinitrc looks something like this at the moment:

eval `ssh-agent`
xsetroot -solid grey15 -cursor_name plus -fg white -bg black
xrdb -load .Xresources

# Better keyboard repeat.
xset r rate 270 40

# Load my own keymap.
xkbcomp -I$HOME/lib/xkb $HOME/lib/xkb/chrome.xkb $DISPLAY

# Hide mouse pointer after idling.
unclutter -idle 5 &

# Keep sanity at night
redshift &

# If I'm using my trackball I want no mouse acceleration at all.
# xset m 1/1 1

# Set the touchpad to use decent scrolling.
xinput --set-prop 'Elan Touchpad' 'Australian Scrolling' 1

# Write some status stuff to X's root window name to be displayed by
# dwm's status bar. 
bin/status.sh &

#mcwm -b 2 -s 10 -f darkred &
dwm &
urxvt -T console

Not running the XFCE desktop meant some special keys on my keyboard suddenly didn't do anything, for instance the backlight and volume keys.

I installed xbacklight to be be able to handle the monitor's backlight under X. I also installed redshift to be able to sleep at night. redshift sets the white balance towards the red when it's dark, similar to the slightly famous f.lux program for OS X.

Under the Linux console or in Wayland, the way to change the backlight level is to write to the file:

/sys/class/backlight/intel_backlight/brightness

I re-used my old program from when I was using a Genesi Efika MX Smartbook which basically does the same thing.

Pulseaudio is the standard on GalliumOS. The way to change volume is to run the obvious command:

% pactl set-sink-volume @DEFAULT_SINK@ +2%

I did some shell aliases for this command.

xbindkeys might help in binding the media keys on the Chromebook's keyboard to these commands, but I haven't tried it yet. It would be nice to be able to make they keys work in the console and Wayland as well.

Since neither mcwm nor dwm have an EWMH-compliant system tray I could no longer use Network Manager's nm-applet like XFCE does. nm-tui worked, though. I also found nmcli-dmenu. It pops up a small dmenu window which lets me choose the wifi network. Really neat!

The biggest surprise was that the power button now instantly turns off the laptop instead of popping up a dialogue window! The power button is dangerously close to the Backspace key, so I bet you can guess what happened... To turn the power button off (holding it down for 10 seconds still forces powerdown), add this to /etc/systemd/logind.conf:

HandlePowerKey=ignore

Another thing that was needed was screen locking. When I last used to run mcwm and X11 at all a couple of years ago I used the small slock program. It still exists. There's also i3lock which seems to be a more feature-filled fork.

However, both of these only lock the current X server and since I'm running several X servers, a Wayland compositor and some Linux consoles at the same time, they won't do. Using them leaves all but the current X server unprotected. Instead, I found physlock, which locks all Linux consoles. Just what I needed.

Running without X11

I did a few experiments without using X11 at all, both running Wayland and using the Linux console.

I tried the Weston compositor under Wayland, which was a bit configurable, but not much. I had earlier tried the Sway compositor on another machine and it was much nicer, but it isn't available in Ubuntu's packages yet. Sway is meant to behave like the i3 X window manager. Velox, a dwm-inspired compositor, also looks nice.

However, last time I tried Sway you had to manually configure your external monitors and restart it when attaching or detaching! On the other hand, this machine can't drive my external 27" monitor at its native resolution anyway, so I might end up using only the internal monitor.

When running in the console, the first thing that bugs me is that I can't easily see what's happening in other terminals/consoles or even be notified if something happens in them.

One way around that that I found is to use dvtm, a text-based tiling window manager. It basically does what the combination of X-server + dwm + urxvt does for me under X11. Like dwm, it also has tags that a window can belong too. It's all very, very impressive.

Using dvtm in combination with tmux on each host I connect to gives me pretty much the same screen I'm using in X, most of the time, but in text mode.

The console driver itself doesn't have very nice colours, but that's changeable with ESC]P<n><rrggbb in hex>. Note that it seems you have to switch away and then back to the VC for it to take effect.

If fancy anti-alias fonts is your thing you can get it in the console with fbterm that runs in the Linux framebuffer. Here's fbterm with dvtwm using anti-aliased Inconsolata:

For some reason line-drawing characters didn't work in fbterm.

Here's basically the same thing without fbterm in an ordinary virtual console with the Terminus pixel font:

(Screenshots in console made with fbgrab.)

I could probably live with dvtm + tmux on remote machines (and possibly fbterm) for most of what I do. Combined with fbpdf and friends everything but the most advanced web browsing could be done directly from the console.

Keyboard under X11

Of course I'd like my own keyboard mapping. It's based on the standard se map but with some modifications:

And the usual stuff like a Control key next to "A" and an ESC key next to "1".

Load it with something like

xkbcomp -I$HOME/lib/xkb $HOME/lib/xkb/chrome.xkb $DISPLAY

chrome.xkb:

xkb_keymap {
	xkb_keycodes  { include "evdev+aliases(qwerty)"	};
	xkb_types     { include "complete"	};
	xkb_compat    { include "complete"	};
	xkb_symbols   { include "pc+se(se)+chrome(se)"	};
	xkb_geometry  { include "pc(pc105)"	};
};

symbols/chrome:

// MC's Swedish keymap for use with Chrome laptops with Swedish
// physical geometry.
default partial alphanumeric_keys modifier_keys
xkb_symbols "se" {
    include "latin(type2)"
    include "se(se)"

    key <TLDE>	{ [ Escape ] };
    key <AE04> { [ 4, dollar ] };
    key <AD11> { [ aring, Aring, braceright, bracketright ] };
    key <AD12> { [ asciitilde, asciicircum, dead_diaeresis, dead_circumflex] };
    key <AC10> { [ odiaeresis, Odiaeresis, bar, backslash ] };
    key <AC11> { [ adiaeresis, Adiaeresis, braceleft, bracketleft ] };

    key <AE12> { [ grave, at, dead_acute, dead_grave ] };

    key <LWIN> { [ Control_L ] }; // This is the search key to the right of "A".
    key <LALT> { [ Meta_L ] };

    key <RALT> {
        type= "ONE_LEVEL",
        symbols[Group1]= [ ISO_Level3_Shift ]
    };

    key <RCTL> { [ Super_R ] };

    modifier_map Control { <LWIN> };
    modifier_map Mod1 { Meta_L, Meta_R };
    modifier_map Mod4 { Super_R };
    modifier_map Mod5 { ISO_Level3_Shift };
};

Keyboard in console

My old mc-latin1 keyboard mapping from the time, many years ago, when I lived in the Linux console still works. More than that, it gives me UTF-8 these days (despite the filename)!

I had to change the keycode 125 (the Search key) to Control, but that was it.

Sound

GalliumOS uses pulseaudio, but for my usage where I'm switching between Linux consoles all the time, this wasn't working the way I wanted to. Sound stopped some of the time I switched console and seemed to be garbled at times.

I uninstalled pulseaudio and used plain ALSA instead, which worked the way I wanted.

Security

I wasn't too thrilled to be back in the X11 security nightmare, although I admit that I've missed using mcwm and a decent tiling manager.

I tried a few methods to make X a bit safer to use. One of the methods involved running two X servers, each one on its own Linux virtual console:

  1. X server for my own purposes using trusted(?) X programs, mostly a number of urxvt's, a window manager, and some small utilities.

  2. Separate X server as another user for general web browsing and other unsafe practices, like watching PDF's from external sources, et cetera.

    This other user doesn't have any access to my ordinary home directory. It also has no access to my ordinary user's X server.

Of course, cutting and pasting between these two X servers is impossible. For now I've been using xsel >>foo.txt which adds the current selection to a file readable by my ordinary user to get stuff from the unsafe X to the safer X. I've been thinking about writing some sort of simple client/server to automate this, only allowing plain text to travel from selection to selection. I need to think about this.

One thing I haven't tested yet is to use x11vnc to export the existing unsafe X server over VNC to the safer side. Might work OK for casual browsing if not for watching movies and the like.

This setup is a sort of poor man's alternative to Subgraph's use of xpra, or Qubes' use of Xen virtual machines to isolate things from each other. Not quite as thorough as them, but perhaps better than nothing. Given the weak hardware of this Chromebook perhaps it's the best I can do.

I also experimented a bit with the Weston Wayland compositor. It's possible to run it without Xwayland but a lot of programs won't work. I didn't find any way of starting a new Xwayland per X program either, but that seems like an interesting idea.

Chromium still runs under Xwayland and when I tried using Firefox with GTK_BACKEND=wayland it just crashed. The crash window was a Wayland window, though, so at least some progress!

I've seen noise about a Wayland-enabled Chromium, but haven't been able to try it yet. Anyone with experience running it?

I might consider running my 'safer' side under Wayland or Linux console (with dvtm) since it's mostly a set of terminals anyway.

Out of the box, GalliumOS runs way too many network exposed daemons. I turned off at least these:

Camera

It works. I keep it taped over most of the time. I don't know how hard it would be to physically remove it, but a couple of layers of duct tape should be enough.

Microphones

It works, too. This might be a problem. I don't know how easy it is to remove the microphones and the speakers. I'll have to look into that. I'll have to open the box anyway if I want to totally re-flash the firmware.


Last updated: <2016-08-10 21:12:15 MEST>