Installing ChromeOS on Surface Go

Note: Hi from the past, everyone! This post is likely very out of date. There are new tools to replace Project Croissant, and new driver packs available for Surface products including the Go. This hasn’t been updated since February of 2019.

I’m a tablet hopper. I love the idea of a tablet, but they always seem to fall short in one way or another. I’ve had a ton of Surface devices, iPads, and even a few Galaxy Tabs. My favorite device of all time is probably the first generation ThinkPad 10, but it’s just slow enough at this point that it’s not as fun as it once was. My current primary is a 10.5″ iPad Pro.

I do love the Surface lineup, but Windows 10 is a surprising shortcoming. Don’t get me wrong, I really like Windows 10, but from a tablet perspective, it’s a huge step back from Windows 8. Do note, however, that’s the only nice thing I’ll say about Windows 8.

What I’ve really been waiting for is a really good 10-11″ ChromeOS tablet. ChromeOS has a great core, Android support, Linux support for the apps you need, all wrapped up in easy updates and elegant consistency. Usually. The only devices in this form factor are the Acer Chromebook Tab 10, and the clone tablets that are based on that form factor. The ARM chip is somewhat anemic, but I’m mostly okay with that. My concern is the lack of supporting hardware — namely, decent cases, and nicely integrated keyboard designs. Once something comes out that fits that niche, I’m first in line.

Until then? Haxxxxx.

Enter Project Croissant. Croissant, formerly Chromefy, is a tool to convert a ChromiumOS image to a full ChromeOS image. ChromiumOS is the open source version of ChromeOS, consisting of most of what makes ChromeOS good, but missing closed source bits, including Android support. By utilizing a ChromeOS recovery image, Croissant can generate a ChromeOS image that can be installed on most anything with some reasonable driver support. Armed with this, I’m hoping to make a Surface Go, arguably one of the best form factors out there right now, a much more useful tablet for me.


What definitely doesn’t work:

  • Front and Rear Cameras
  • Power button to wake, but other touch events or keys seem fine

What’s fiddly:

  • Touch response is odd, a press event occurs even on light touches or drags
  • The type cover function key icons do not correspond to their ChromeOS functionality
  • Sleep still burns some battery

What really works:

  • Wi-fi and bluetooth seem to work splendidly
  • The stylus responds well, and the pen icon appears
  • The type cover attaches and disconnects as one expects, backlight works, everything is fine
  • The SD card mounts just fine
  • USB-C devices work exactly as they should
  • Audio output
  • Lid sensor with Type Cover

To create this image, I used another machine running Linux. This can be done in a virtual machine, or using a Linux live image.

  1. To begin, we need to gather dependencies
    1. Obtain from GitHub
    2. Obtain the nocturne 71 recovery image
    3. Obtain the caroline 71 recovery image
    4. Obtain the ArnoldTheBat R72 Special image
  2. We’ll also need to grab updated firmware for wi-fi and bluetooth support within Chromium/Chrome
    1. Retrieve an up to date firmware-6.bin from ath10k firmware
    2. Retrieve updated board.bin from Killer Networking wireless firmware
  3. With all of our dependencies gathered, we can actually create our installation image
    1. Uncompress each image into a directory
    2. Copy into the same directory
    3. Execute chromefy to create the image, using something similar to sudo bash chromiumos_image.img chromeos_11151.113.0_nocturne_recovery_stable-channel_mp.bin chromeos_11151.113.0_caroline_recovery_stable-channel_mp.bin
  4. Write the updated chromiumos_image.bin to a USB stick using Etcher or similar
  5. Upon completion, remove and reinsert the USB stick
  6. Insert updated firmware and configuration to our ChromeOS image
    1. Find the partition containing the rootfs, which may have automounted under /media/your-username/, and contains directories like ‘bin’, and ‘lib’
    2. Remove [path-to-rootfs]/lib/firmware/ath10k/QCA6174/hw3.0/board-2.bin
    3. Replace [path-to-rootfs]/lib/firmware/ath10k/QCA6174/hw3.0/board.bin with the previously downloaded file
    4. Replace [path-to-rootfs]/lib/firmware/ath10k/QCA6174/hw3.0/firmware-6.bin with the previously downloaded file
    5. Create [path-to-rootfs]/etc/modprobe.d/ath10k.conf and add options ath10k_core skip_otp=yto the file
  7. Unmount the mounted USB filesystems
  8. Get your Surface Go and running
    1. Within Windows, go to Settings > Update and Recovery > Recovery
    2. Under Advanced Startup, select Restart Now
    3. Navigate to Troubleshoot > Advanced, and select UEFI Firmware Settings
    4. Under Boot Configuration, disable Secure Boot and set USB Storage to the top of the boot order
    5. Select Reboot to boot from USB stick

This is a bit of the test front for the image. One is able to log in and poke around a bit within the USB live image. The installation process got a little hairy, though, at least for ArnoldTheBat 72 + Eve 71. Note that the first command run will blow away the copy of Windows installed on the Surface Go. There are instructions available on the Project Croissant GitHub README for doing multiboot. As I have the 64gb Go, multiboot makes no sense for me. Also note that the 128gb Go uses SSD instead of eMMC, so the device name is going to change, likely to some derivative of /dev/nvme0n1.

  • Execute /usr/sbin/chromeos-install –dst /dev/mmcblk0 –skip_postinstall
  • Reboot into a live image of Linux
  • Using Gparted, or similar, resize /dev/mmcblk0p3 (H-STATE) down one gigabyte
  • Remove /dev/mmcblk0p12, the EFI_SYSTEM partition
  • Create a new partition, 1gb, fat32, with a partition name of EFI_SYSTEM
  • Apply
  • Right click the EFI_SYSTEM partition and then “Manage Flags”
  • Select legacy_boot, boot, esp
  • Open a terminal
  • sudo mkdir /mnt/cros /mnt/efi
  • Insert the USB stick containing your ChromeOS image
  • Find the device of the USB stick, likely /dev/sdb, and replace sdx with the device found, and execute mount /dev/sdb12 /mnt/cros to mount the Chrome image’s EFI partition
  • Execute mount /dev/mmcblk0p12 /mnt/efi to mount the installed EFI partition
  • Execute cp -Rp /mnt/cros/* /mnt/efi/ to copy the EFI partition over
  • Reboot and remove the USB stick

Welcome to your new ChromeOS installation!

  1. Thanks for through explanation, was easy to follow to try out this myself. One thing tough, once boot up usb image I feel touchpad behaves somewhat flaky such as tap to click doesn’t work / general responsiveness is odd (sometimes it work, sometimes cursor barely moves when try to move). Did you experienced similar or it just worked?

  2. I’m thinking about going this route, but would need the power button to wake. Any updates on this?

  3. Exactly the info i was looking for! Thanks to you i managed to boot from USB into chromeOSv72. And it works, but there are some annoying issues, espesially with touchscreen.

  4. Great guide!

    I’m using ArnoldTheBat’s R72 Special + eve 72 + software tpm. Haven’t been able to get a 73 recovery image working yet, but will keep trying.

    Doesn’t work:
    – Touch works, but is too eager to interpret taps
    – Stylus works, but has no pressure sensitivity
    – Bluetooth works, but is unusable with 4.2/LE devices (e.g. steam controller)
    – Smart Lock keeps saying it’ll work next login, but never does (probably bluetooth related)
    – Power button doesn’t sleep, but type cover does
    – No cameras

    Have also given nocturne 72 and soraka 72 a go, but had issues activating the Play Store.

    Everything else seems good. Type cover keys all work as intended too, maybe enabling “treat top-row keys as function keys” is a thing, so the chromebook-native layout only kicks in when you hold down the win key.

    After ~2 weeks, performance and battery life seems to have improved over similar usage with W10

  5. why I always meet an error that says ‘no free space on this device’ ,while I run ‘sudo bash xxxx’.

  6. Thanks – really appreciate the write up…got me motivated to move my surface go gathering dust to ChromeOS

  7. I have been able to dual-boot Windows-10 and Chromium OS on my 128GB Surface Go. I started with Nick’s post here and then followed the MultiBoot Chromium Guide, but will expand a little as some of the instructions were somewhat vague. The Project Crossant option 1 or 2 install options are automatic but erase your HD, so I went with their MultiBoot Guide.
    1. I shrunk my primary window’s 10 partition by 32GB, using Window 10’s Disk Management.
    2. Follow this post instructions thru step 8.5 and boot from your chromium USB stick.
    3. Follow the MultiBoot Chromium Guide’s instructions, I created an Ubuntu boot USB that I used to transfer Chromium from my USB to HD. Essentially you are copying three USB partitions to corresponding partitions on your HD (/dev/nvme0n1 for the 128GB model). I created 3 partitions in the free 32GB space from step 1. This results in STATE, ROOT-A, and EFI-SYSTEM partitions as instructed in the Guide.
    4. Modify the script. Chromium OS Hacker provides a better explanation under step 4 of his post. Utilize the fdisk command to get your drive’s partition sizes and then update and delete only the section below load_partiton_vars() and load_base_vars(). With the SSD drive you still only use the partition number and do not include the ‘p’ before it.
    5. Modify Chromium EFI_SYSTEM efi/boot/grub.cfg via Chromium OS Hacker instructions. You need to change the PARTUUID to your ROOT_A partition’s PARTUUID.
    Note: To find a partitions UUID use the command ‘blkid /dev/nvme0n1’ for PARTUUID execute ‘blkid /dev/nvme0n1’
    6. I installed Grub2 via my Ubuntu boot USB to my Window’s EFI partition. This then required me to chainload to the Chromium EFI_SYSTEM partition, edit /etc/grub.d/40_custom file.
    To the end of the file add:
    Menuentry “Chromium OS” {
    Search –fs-uuid –no-floppy –set=root Partition-UUID# (ex. 7875-AAB5)
    Chainloader (hd0,gpt5) /efi/boot/bootx64.efi (gpt# is your chromium efi partition #)
    7. (Optional) Modify Grub setup via /etc/default/grub file. Ubuntu documentation provides a good reference of grub2 setup options.
    8. Execute ‘sudo update-grub2 –o /bootwindowsefimount/EFI/ubuntu’
    You now have a dualboot bootable Chromium OS setup. One final tip if you step 8 results in a cow error run the following three steps
    1. dd if=/dev/zero bs=1M count=1 of=cowfile
    2. mkfs –t vfat cowfile
    3. mv cowfile /cow

    MultiBoot Chromium Guide:
    Project Crossant:
    Chromium OS Hacker:
    UUID information:
    Ubuntu Grub documenation:

  8. Well. That was a task and a half!! Getting No Bootable Device after last reboot. ChromeOS usb boots but can’t enable boot from

  9. Thank you for the great information.

    Lots of people refer to your blog on how to setup the device.

    Do you still use the device as of recent? Or changed devices?

    1. I’ve changed devices, unfortunately. It’s so close to the machine I want it to be, but just not quite.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.