Skip to main content

Linux on Chromebooks

Booting Persistent USB

It is possible to boot into a 3.1 USB stick with persistent data saved between sessions. There are plenty of cheap options out there for ultra portable USBs that you'll hardly notice due to their low-profiles. Even better, if you have a chromebook with USB C ports. The main limiter on your system will often be read/write speed, as you are funnelling all of your data through a USB device opposed to internal storage. Be careful to choose the port on your device with the best speed, you will be glad you did later on.

If you boot this way, you won't have to run or use crouton, or even boot into ChromeOS (CrOS). You'll need to enable developer mode, and press CTRL+L when rebooting the chromebook and the warning is displayed for 'OS Detection' being disabled. To boot into CrOS instead, press CTRL+D. If you press nothing, a loud BEEP will happen and it will boot into CrOS.

If you have a windows machine handy, check out the links below to see how you can create a persistent USB for booting. This method does not install linux onto the USB, but rather creates a Live USB (Installation media) of your selected distribution. On this Live USB, if created following these directions, there exists a persistent filesystem, which allows you to retain settings and application data between reboots.

Windows ISO Writer

Normally, on a Live USB there is no persistence and all data will be lost between reboots, so be careful to follow the steps carefully when creating your USB.

Consider how much you plan to store on your system, for me 30GB storage is plenty to do all my programming and server administration from a Lubuntu installation.

My Toshiba 2 Chromebook is running on a massive 2GB of RAM, paired with a generation 6 Intel Duo ~2GhZ and 16GB internal storage. It ran me $100 in 2015 used off ebay and is still running strong. I run Lubuntu booting into a 3.1 USB, which uses i3wm and the bare minimum for packages installed / running. I have no issues in VS Code, Pycharm, LaTeX editors, and all office applications work fine. The main issue to note is web browsing. Chrome or any derivitive will consume nearly all of your RAM. Firefox does ok, and if you visit about:memory in your address bar it will allow you to 'Minimize Memory Usage' by clicking a button. Midori is my preferred browser when not dealing with personal accounts and just reading documentation.

Enable Developer Mode

Once you have the USB stick made with the linux distro you want to run, you can start your chromebook and open a terminal. For me, this is CTRL+ALT+t. Once in the console window, you'll see a crosh> prompt. Type the commands below and read the output.

Welcome to crosh, the Chrome OS developer shell.

If you got here by mistake, don't panic!  Just close this tab and carry on.

Type 'help' for a list of commands.

If you want to customize the look/behavior, you can use the options page.
Load it by using the Ctrl-Shift-P keyboard shortcut.

crosh> shell
chronos@localhost / $

Next, check the available settings by running the crossystem command. This output is useful if you want more information on what values you're setting, and why.

chronos@localhost / $ sudo crossystem
arch                    = x86                            # [RO/str] Platform architecture
backup_nvram_request    = 1                              # [RW/int] Backup the nvram somewhere at the next boot. Cleared on success.
battery_cutoff_request  = 0                              # [RW/int] Cut off battery and shutdown on next boot
block_devmode           = 0                              # [RW/int] Block all use of developer mode
clear_tpm_owner_done    = 0                              # [RW/int] Clear TPM owner done
clear_tpm_owner_request = 0                              # [RW/int] Clear TPM owner on next boot
cros_debug              = 1                              # [RO/int] OS should allow debug features
dbg_reset               = 0                              # [RW/int] Debug reset mode request
debug_build             = 0                              # [RO/int] OS image built for debug features
dev_boot_altfw          = 0                              # [RW/int] Enable developer mode alternate bootloader
dev_boot_signed_only    = 0                              # [RW/int] Enable developer mode boot only from official kernels
dev_boot_usb            = 0                              # [RW/int] Enable developer mode boot from external disk (USB/SD)
dev_default_boot        = disk                           # [RW/str] Default boot from disk, altfw or usb
dev_enable_udc          = 0                              # [RW/int] Enable USB Device Controller
devsw_boot              = 1                              # [RO/int] Developer switch position at boot
devsw_cur               = 1                              # [RO/int] Developer switch current position
diagnostic_request      = 0                              # [RW/int] Request diagnostic rom run on next boot
disable_dev_request     = 0                              # [RW/int] Disable virtual dev-mode on next boot
ecfw_act                = RW                             # [RO/str] Active EC firmware
post_ec_sync_delay      = 0                              # [RW/int] Short delay after EC software sync (persistent, writable, eve only)
fw_prev_result          = unknown                        # [RO/str] Firmware result of previous boot (vboot2)
fw_prev_tried           = A                              # [RO/str] Firmware tried on previous boot (vboot2)
fw_result               = unknown                        # [RW/str] Firmware result this boot (vboot2)
fw_tried                = A                              # [RO/str] Firmware tried this boot (vboot2)
fw_try_count            = 0                              # [RW/int] Number of times to try fw_try_next
fw_try_next             = A                              # [RW/str] Firmware to try next (vboot2)
fw_vboot2               = 0                              # [RO/int] 1 if firmware was selected by vboot2 or 0 otherwise
fwb_tries               = 0                              # [RW/int] Try firmware B count
fwid                    = Google_Swanky.5216.238.150     # [RO/str] Active firmware ID
fwupdate_tries          = 0                              # [RW/int] Times to try OS firmware update (inside kern_nv)
hwid                    = SWANKY E5A-E3P-A47             # [RO/str] Hardware ID
inside_vm               = 0                              # [RO/int] Running in a VM?
kern_nv                 = 0x0000                         # [RO/int] Non-volatile field for kernel use
kernel_max_rollforward  = 0x00000000                     # [RW/int] Max kernel version to store into TPM
kernkey_vfy             = sig                            # [RO/str] Type of verification done on kernel keyblock
loc_idx                 = 0                              # [RW/int] Localization index for firmware screens
mainfw_act              = A                              # [RO/str] Active main firmware
mainfw_type             = developer                      # [RO/str] Active main firmware type
nvram_cleared           = 0                              # [RW/int] Have NV settings been lost?  Write 0 to clear
display_request         = 0                              # [RW/int] Should we initialize the display at boot?
phase_enforcement       = (error)                        # [RO/int] Board should have full security settings applied
recovery_reason         = 0                              # [RO/int] Recovery mode reason for current boot
recovery_request        = 0                              # [RW/int] Recovery mode request
recovery_subcode        = 0                              # [RW/int] Recovery reason subcode
recoverysw_boot         = 0                              # [RO/int] Recovery switch position at boot
recoverysw_cur          = (error)                        # [RO/int] Recovery switch current position
recoverysw_ec_boot      = 0                              # [RO/int] Recovery switch position at EC boot
ro_fwid                 = Google_Swanky.5216.238.5       # [RO/str] Read-only firmware ID
tpm_attack              = 0                              # [RW/int] TPM was interrupted since this flag was cleared
tpm_fwver               = 0x00050003                     # [RO/int] Firmware version stored in TPM
tpm_kernver             = 0x00030001                     # [RO/int] Kernel version stored in TPM
tpm_rebooted            = 0                              # [RO/int] TPM requesting repeated reboot (vboot2)
tried_fwb               = 0                              # [RO/int] Tried firmware B before A this boot
try_ro_sync             = 0                              # [RO/int] try read only software sync
vdat_flags              = 0x00002c56                     # [RO/int] Flags from VbSharedData
wipeout_request         = 0                              # [RW/int] Firmware requested factory reset (wipeout)
wpsw_cur                = 1                              # [RO/int] Firmware write protect hardware switch current position

The settings we are interested in is dev_boot_usb and dev_boot_altfw, so run the following commands to enable developer mode -

chronos@localhost / $ sudo crossystem dev_boot_usb=1
chronos@localhost / $ sudo crossystem dev_boot_altfw=1

Now plug in the USB and reboot the chromebook. When you see the white screen warning about thrid party operating systems, press CTRL+ALT+L and you'll see a prompt to select the USB device to boot from. Since you installed your distribution to your USB with persistence, your data will be saved to the USB. You will need to keep the USB plugged in all the time, and it may not be the best - but it works, and it's better then being stuck in CrOS.

NOTE: The old command for this was dev_boot_legacy, but it has since changed. We can see this when trying to set the old variable name, which leads us to setting dev_boot_altfw.

chronos@localhost / $ sudo crossystem dev_boot_legacy=1
!!! PLEASE USE 'dev_boot_altfw' INSTEAD OF 'dev_boot_legacy'

Booting From USB

That's it! Now be sure the USB is plugged in when you boot up your chromebook, you'll see a warning that 'OS Detection' is disabled, press CTRL+L and select your USB. Alternatively, to boot into CrOS instead, press CTRL+D when you see this message. Since we never actually wrote to the laptop's storage media, CrOS is still just fine and you can hop between that and the linux distribution you've installed on your USB. I usually browsed the web during class on CrOS, then switched over to my linux USB if we started to do some programming.

Since you created the USB with persistent data, you won't need to install the distribution, you can just use it as-is right off the USB drive. It's not ideal, you will run much slower than installing on an SSD or HDD, but this method got me through college on a budget when all I had to use for a laptop was a chromebook.

Using Crouton

Crouton allows you to install linux alongside ChromeOS on a chromebook. Click here to grab the latest crouton installer directly, or alternatively visit Crouton's Repository and click the goo link in the description for the same.

To sync your Chromebook's local clipboard with your Linux install, grab the Crouton extension from the Chrome Web Store.

Once you have this file, be sure it is found in your Chromebook's ~/Downloads directory using the file browser and run the commands below to install Linux -

# Install the crouton binary for use within your chromebook's shell
sudo install -Dt /usr/local/bin -m 755 ~/Downloads/crouton
# Passing -e for encryption, we install all the dependencies for X11 and name(-n) it i3
sudo crouton -e -t core,keyboard,audio,cli-extra,gtk-extra,extension,x11,xorg -n i3
# Enter the chroot
sudo enter-chroot -n i3
# Install i3
sudo apt install i3
# Tell Xorg to start i3 automatically
echo "exec i3" > ~/.xinitrc
# Exit the chroot
# Add an alias for starting i3 in crouton using X
sudo echo "alias starti3='sudo enter-chroot -n i3 xinit'" >> /home/chronos/user/.bashrc

Want i3-gaps instead? See the i3-gaps GitHub for instructions, or run the commands below.

sudo apt-get install software-properties-common

If you're unsure which Distro or DE to install, see the below commands for lists of supported versions.

# List supported Linux releases
sudo crouton -r list

# List supported Linux desktop environments
sudo crouton -t list

# Update chroot (you will need this eventually)
sudo crouton -u -n chrootname

Removing / editing chroots is done via the edit-chroot CLI -

# Print help text
sudo edit-chroot

# Remove chroot named i3
sudo edit-chroot -d i3

# Backup chroot
sudo edit-chroot -b chrootname
# Restore chroot from most recent tarball
sudo edit-chroot -r chrootname
# Restore from specific tarball (new machine?)
sudo edit-chroot -f mybackup.tar.gz