Running Linux on the Series 3 Chromebook

Last month Google and Samsung released the first commercially available product using the ARM® Cortex™-A15 SoC design: the new Series 3 Chromebook. Not only does the Chromebook have the new Samsung Exynos 5250 providing the core compute power, but it also has the new ARM Mali™-T604 providing the power to move all those pixels around. As with previous Chromebooks, it uses a custom operating system known as ChromeOS (which is based loosely on Gentoo Linux). If you've ever used either the Chrome or Chromium browser from Google you'll have no issues, as everything is orientated around the browser.

I'm not going to be doing a review of the new Chromebook, there are plenty of those available. What I am going to talk about is getting a full blown Linux environment onto the Chromebook. Why would someone wish to do this, instead of just using Chrome OS? The reasons will be wide and varied, my own reasons for doing so are for development and testing of applications and other items on the ARM architecture. ARM Cortex-A15 introduces some new extensions to the ARM architecture that many developers would find interesting, like support for hardware virtualization. To be able to leverage these extensions and to explore what the hardware can do, one needs to have a development environment that can facilitate such work. This is where having a full Linux environment comes in.

At the end of last month Linaro held their European conference in Copenhagen where many developers met to discuss ARM support for a number of open source projects. I spent some time with Marcin Juszkiewicz (a Canonical engineer seconded to Linaro) and Olof Johansson (a Chrome OS developer and a kernel maintainer for the arm-soc tree) in getting Linux running on the new Chromebook. Several developers have already succeeded in doing this, running a variety of Linux distributions – openSUSE/Ubuntu/Fedora/Debian are all reported to work well on the device (with some minor caveats).  My intention here is to provide the steps needed to get a more traditional Linux distribution running on the Chromebook. These include the initial steps that Olof provided with some additional input from members of the ARM community like Marcin (thanks!).

There are a few pre-requisites needed to get the job done:

On your Chromebook
1.  In order to boot another operating system on your Chromebook you first need to enable the "Developer Mode", the Chromium project has the required steps needed.  Please note that enabling "Developer Mode" will effectively re-format your device so ALL DATA WILL BE LOST.

2.  Create a recovery image for the Chromebook (just in case).  In a browser head to 'chrome://imageburner' and follow the steps.

3.  Create a tarball of the Chrome OS root filesystem. This will come in handy as you will need  some components from it and also serves as a good reference point.
On the Chromebook open a terminal either in the browser with 'Ctrl+Alt+T' or a virtual terminal with 'Ctrl+Alt+->' (forward arrow, 3rd key from the left, top row, near the esc key).

Start a shell (not needed if using a virtual terminal)
shell
Move to a write enabled directory
cd /home
Create the tarball
sudo tar --one-file-system -cvf chromeos-rootfs.tar.gz /


There are numerous ways one can get the tarball off like scp'ing the tarball from Chrome OS to your desktop/laptop, I found the easiest way was copying to external media on the Chromebook.

On your desktop/laptop
This is all done on a Linux machine (sorry I've not tried it on Windows or OSX)
4. Make sure you have the 'gdisk' utility installed 

  • On openSUSE a simple zypper in gptfdisk
  • On Ubuntu & Debian a simple apt-get install gdisk
  • On Fedora a simple yum install gdisk

5. Get your target root filesystem. Make sure that your target Distribution is built for Hard Float.

6.  Extract the Chrome OS tarball.

mkdir /tmp/chromeos-rootfs
cd /tmp/chromeos-rootfs
sudo tar -xvf /media/chromeos-rootfs.tar.gz


7.  Obtain a target SD Card (I am using a 32GB class 10 micro-SD card with adapter)
  
Now that the pre-requisites are completed, it's time to move onto preparing the target SD card. Insert the card into your desktop/laptop and note the device id, running 'dmesg' from a terminal after inserting the card will show you something along the lines of
'sd 6:0:0:0: [sdX] Attached SCSI removable disk'

Replace 'sdX' with the correct id for your card. Ensure the target card is un-mounted and not ejected.

8.  The first thing that needs to be done is to create a GPT partition table on the target card, from a terminal run

sudo  parted /dev/sdX
Then at the parted prompt create the GPT table
mktable gpt
Confirm you wish to destroy the existing data
yes
Then exit parted
quit


9.  Using gdisk we set the sector alignment to 4M

  sudo gdisk /dev/sdX
  At the gdisk prompt
  x
  l
  8192
  m


10.  Then create the  target partitions, the first two are for the kernels, and the third is for the root file system. We are using two kernel partitions to make it easier  to have a one kernel always working and another for testing, so should the testing kernel be fundamentally broken one can still boot the system with a working kernel.

n
1
<press enter>
+16M
7f00
n
2
<press enter>
+16M
7f00
n
3
<press enter>
<press enter>
<press enter>
w
y


11.  We now need to create a filesystem for the root partition. 

sudo mkfs.ext4 /dev/sdX3


12.  Now that we have  the target card almost ready we need to extract our filesystem to the root partition. Mount the correct partition somewhere (in this case we are  using '/mnt') 

sudo mount /dev/sdX3 /mnt
cd /mnt


Replace the path to the root filesystem below with the correct one for your choice

sudo tar xvpf
~/Downloads/target_rootfs.tar.bz2


13.   As we are initially going to use the same kernel as Chrome OS, we will need to copy over the contents of '/lib/firmware' and '/lib/modules' to the root filesystem to get things working. 

sudo cp -r /tmp/chromeos-rootfs/lib/firmware/* lib/firmware
sudo cp -r /tmp/chromeos-rootfs/lib/modules/* lib/modules


To get everything working under your Linux distribution some additional steps are needed as there may be a few items that do not work straight "out of the box" like Xorg, Touchpad & Sound.

14.  The touchpad  requires an additional configuration file called 50-touchpad.conf placed into /etc/X11/xorg.conf.d/   Using your preferred text editor create the required file

(I'm using Vim) 
sudo vi etc/X11/xorg.conf.d/50-touchpad.conf
Add the contents below
Section "InputClass"
Identifier "touchpad"
MatchIsTouchpad "on"
Option "FingerHigh" "5"
Option "FingerLow" "5"

EndSection

15.  To get audio  working copy the contents of '/usr/share/alsa/ucm' from Chrome OS 

sudo cp -r /tmp/chromeos-rootfs/usr/share/alsa/ucm/*
usr/share/alsa/ucm


Then from within your new Linux powered Chromebook run: (DO NOT run it on your desktop/laptop)

alsaucm -c DAISY-I2S
Try and not manually adjust ALSA as it could result in blowing a speaker if you're not careful.


16.  We can now unmount the SD card

cd
sudo umount /dev/sdX3


The next exercise is to get the kernel onto the SD card. This task is carried out on the Chromebook under Chrome OS. You will need to be very careful as it is possible to destroy the installed system and will need to re-install using the recovery image.

17.  The kernel command line is going to be different to what is used for the installed ChromeOS, so the kernel blob will need to be repacked.  Follow the earlier steps to get a terminal with a shell up.

cd /tmp
echo "console=tty1 debug verbose root=/dev/mmcblk1p3 rootwait rw"\
> /tmp/config
vbutil_kernel --pack /tmp/newkern –keyblock\
/usr/share/vboot/devkeys/kernel.keyblock --version 1 –signprivate\
/usr/share/vboot/devkeys/kernel_data_key.vbprivk\
--config=/tmp/config --vmlinuz /boot/vmlinuz-3.4.0 --arch arm


18.  Now move the target SD card to the Chromebook and write the kernel to the prepared kernel partitions 

dd if=/tmp/newkern of=/dev/mmcblk1p1
dd if=/tmp/newkern of=/dev/mmcblk1p2


19.  To be able to boot from your new SD card USB boot needs to be enabled (this also covers SD cards). From the terminal shell run 

crossystem dev_boot_usb=1


20.  The last step is to mark the kernel partitions as known to be god so that the firmware will attempt to use them when you boot up. This marks both partitions as successful, and gives the first partition a priority of 10 and the second a priority of 5. Technically both creating a label and marking as successful aren't needed but it is good practice. 

cgpt add -i 1 -S 1 -T 5 -P 10 -l KERN-A /dev/mmcblk1
cgpt add -i 2 -S 1 -T 5 -P 5 -l KERN-B /dev/mmcblk1


Once that is all done you are ready to boot into your preferred Linux distro. When you reboot the Chromebook you will be presented with the devmode screen, press Ctrl+U to boot from the SD card or Ctrl+D to boot Chrome OS from the internal disk.

Most distributions are now packaging up all the required components to make things slightly easier and also make things work better. So check your distribution's package archives for things like an updated alsa (to correctly provide the Daisy I2S profiles), xf86-video-armsoc (to provide better un-accelerated graphical support). xf86-input-cmt (to provide better touchpad performance), and possibly a few others.

Do you happen to run a Linux distribution that I've not mentioned, maybe you run a different operating system to Linux like FreeBSD? If you do, we'd love to hear from you. We'd also like to hear about how you use the Chromebook, especially if it isn't in a more traditional laptop scenario.

  • Just looking for a little clarification.I assume the chrome://imageburner step is done *before* enabling developer mode?Additionally, once you've enabled dev mode, how do you *disable* it, and boot normally?
  • Good point, you can actually create the backup image either before or after entering developer mode, it doesn't make any difference.To disable developer mode, just press the space bar when the machine boots up (at the same point you would press CTRL+U or CTRL+D).
  • Excellent, thanks for the clarification.
  • Nice post and motive. A couple of L plate questions.1. Am I correct in concluding that step 15 requires the SD card OS to be established in an active chroot environment?2. Please briefly expand your explanation for step 17. I would like to know more of what the commands and options are doing so that I can adapt the process as and when.
  • Nice post and motive. A couple of L plate questions.1. Am I correct in concluding that step 15 requires the SD card OS to be established in an active chroot environment?2. Please briefly expand your explanation for step 17. I would like to know more of what the commands and options are doing so that I can adapt the process as and when.


    1. No it shouldn't be chroot'ed. One copies the UCM profiles over much in the same way as you do with the modules & firmware. Basically just mount the SD Card on your computer and copy the UCM profiles from the ChromeOS filesystem tarball. You would run the 'alsaucm' command once you have booted into your desired distro on the Chromebook.

    2. OK if we break the commands down it means the following:
    echo "console=tty1 debug verbose root=/dev/mmcblk1p3 rootwait rw" > /tmp/config
    # This is the root command passed to the kernel, much like on any other ARM device. It is created in the file /tmp/config for use in the next steps.

    vbutil_kernel --pack /tmp/newkern --keyblock /usr/share/vboot/devkeys/kernel.keyblock --version 1 --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk\
    --config=/tmp/config --vmlinuz /boot/vmlinuz-3.4.0 --arch arm
    # vbutil_kernel creates, signs and verifies the kernel blob. --pack creates the blob, --keyblock is the keyblock to use for signing, --version is the version to use, --signprivate is the private key to sign the kernel data, --config is the root command file to use, --vmlinuz is the kernel bzImage file to use, --arch is the target CPU architecture

  • This was a great write-up.  I now have Ubuntu installed and running on my new Samsung Chromebook S3. 

    A couple of minor things to note that I ran into: 

    1. the chromeos-rootfs.tar.gz file you create and use above is not actually compressed, so the .gz suffix should not be there.  This confused me for a bit as I wasn't simply cutting and pasting the commands. 

    2. the Ubuntu alip tarball I downloaded was not organized as described in the instructions.  Rather the files were actually buried a couple of directories deeper in the extracted tar ball.  I simply moved them from the nested directories to the soon-to-be-root directory on the SD card (mounted at /mnt).  I am not sure if this issue was unique to the Ubuntu tarball or if the other distro tarballs had similar issues.

    3. getting the Ubuntu window manager to work as expected was a little tricky as the Linaro image defaulted to a different one (I needed to install gnome and a bunch of other packages). 

    I noticed that the Ubuntu 12.10 release is available as a distribution upgrade.  However, after testing, this update is not ready as the system hangs on boot.

    Thanks for an excellent post.
  • Thank you.I've installed ALIP system to SD by your description and used debootstrap to build normal debian system.I'll make a tarball and put it somewhere.
  • Great write up. Thank you for taking the time to provide a consolidated process.
  • Here's another approach that doesn't require repartitioning, but does provide access to a package manager, LAMP stack, and pretty much any of the command-line linux tools, while still retaining all ChromeOS functionality.

    [url="http://solvitor.com/2013/01/02/lamp-stack-on-an-arm-chromebook/"]http://solvitor.com/2013/01/02/lamp-stack-on-an-arm-chromebook/[/url]
  • Thanks for the writeup!   I believe step 17 is not quite correct.  Shouldn't all the "-" be "--"?  Not to be picky, but vbutil_kernel wouldn't accept it otherwise!   Also, the directions are for a SD card; is it possible to use a USB stick instead?  I tried that, but at the very end the /dev/mmcblk1* files didn't exist, but is there a different block device that one can use instead for a USB stick?
  • Nevermind on the questions, I inserted a SD card, and see the /dev/mmcblk1* files.  So that answers my questions.  So is there a way to use a USB stick instead?  Are there different named block devices I can use?  Or is this SD card only?

    [As an aside, I tried to edit my post instead of a reply, but got an error: "[#10683] Incorrect use of one of the board files. "  Weird.]
  • Thanks for the writeup!   I believe step 17 is not quite correct.  Shouldn't all the "-" be "--"?  Not to be picky, but vbutil_kernel wouldn't accept it otherwise!   Also, the directions are for a SD card; is it possible to use a USB stick instead?  I tried that, but at the very end the /dev/mmcblk1* files didn't exist, but is there a different block device that one can use instead for a USB stick?


    Yes, you are quite correct. For some reson the formatting of the post somehow obfuscates the correct command, I'll try and get it fixed.

    As for booting from a USB stick, the process should be the same, although I have not tried it myself. The block device may well be different, so the best thing to do is confirm what the device is by using dmesg in ChromeOS.
  • Hi, I've followed the steps and when I boot from the sd card it hangs, the final line on the output is [2.983203] sd 0:0:0:0: [sda] Attached SCSI removable disk.I believe this is the card with the system to mount. Any ideas what I may have missed? If it has any effect I am using a micro sd mounted through the usb portCheers,
  • Can this method be applied for setting up an android system? I am currently attempting to setup android on a chromebook, I am attempting it using this method.
  • Not sure if you have seen this, but my colleagues have published how to run Android on the Chromebook