Search This Blog

Tuesday, 4 March 2025

Running Linux on Microsoft Surface 2 RT


The Microsoft Surface 2 is an ARM32 based tablet which is largely defunct for many reasons which you can read all about online. The aim was to run Linux on this device to enable better application support and a modern web browser.

Journey 

The following openrt link was super helpful in understanding how feasible it is running Linux on the Microsoft Surface 2 instead of Windows RT 8.1 and how to go about jail breaking the secure boot. All was going well until when trying to boot linux from a USB drive where the EFI boot prompt would just hang for several minutes and not load, then continue and error out.



Initially I thought I had a Surface 1 tablet and wasnt aware it was a Surface 2 until i tried to access the UART serial port to do further debugging. The give away was when trying to disassemble that there are no screws as shown below (Surface 1) under the kickstand. Also I was probably using the wrong device tree file (dtb) which wouldn't help.




Knowing I had a Surface 2, limited details on the Open Surface RT website and the Discord server being down I started to think the hardware support just wasnt there. After reading this guide (and alot of trial and error) it seemed like the best or quickest path to success would be trying to load an EXT file system on the internal MMC by shrinking the Windows 8 RT file system (mmcblk3) and creating additional partitions with the free space. 

There is a bunch of items disabled in the tegra114-microsoft-surface-2.dtb which is getting around which likely due to people trying to get the surface2 working. You can download an updated dtb file here which enables the SD card and enables all disabled devices (though nothing else useful seems to work when enabling all)

Things that dont seem to work


At the time of writing and as far as i'm aware there seemed to be issues with USB support on the surface 2 in linux (wifi and SD works fine) which means it cant be used or can be used under certain cirmstances (e.g. USB boot and copy into RAM). It could be just a linux USB driver issue but haven't had time to look into it further. Sound seems to work but havent tested the microphone and the webcam doesnt seem to work.

Another thing worth a mention is the power and battery details don't appear to be working from the desktop. You can run upower to figure out if the device is plugged in or not, but can't seem to get the battery charge details displaying. Also when you shutdown the machine it doesnt seem to power off the device (screen just goes black) which means its still drawing power. Guessing ACPI isnt working as needed.

Method

The following assumes you have a jailbroken Surface 2 tablet with secure boot disabled, golden keys installed and a few USB keys (=>8gb). This method with the dtb file update could likely be modified to deploy to the SD card (mmcblk1p1) rather than internal MMC (mmcblk0p5)
  1. Download the following files from open-rt.party and copy to a USB drive
    1. https://files.open-rt.party/Linux/Other/surface-2-linux-resizepart-emmc.zip
    2. https://github.com/andrewjameslee/surface2/blob/main/tegra114-microsoft-surface-2-all.dtb
  2. Download Raspberian - 2022-09-22-raspios-bullseye-armhf
      1. Theres a bunch of work needed for this:
        1. pull out root partition from image using dd and partx
        2. fix /etc/fstab for /dev/mmcblk0p5 to be the / partition
        3. put kernel modules to the /lib/modules/ directory to get the wifi working
  3. Boot into Windows RT and load disk management
  4. Shrink the windows partition to the smallest size (~16GB) and delete the recovery partition
  5. Create two new FAT32 paritions 
    1. Partition 5 - FAT32 - ~6 GB
    2. Partition 6 - FAT 32 - ~5GB
  6. Copy the raspios-bullseye-root-image onto partition 6 (~4GB) and potentially kernel modules (used in later steps)
  7. Create Linux Bootable USB (Raspberian - 2022-09-22-raspios-bullseye-armhf using pi imager then copy boot files from surface-2-linux-resizepart-emmc.zip)
  8. Ensure the commandline.txt is configured correctly on USB (initrd=initrd.gz, root=/dev/ram0, init=/init.sh)
  9. Boot into Linux from USB
    1. mkdir /a
    2. mount /dev/mmcblk0p6 /a
    3. dd if=/a/raspios_armhf-2022-09-26/2022-09-22-raspios-bullseye-armhf-root.img of=/dev/mmcblk0p5 bs=1M status=progress
    4. mkdir /b
    5. mount /dev/mmcblk0p5 /b
    6. cp -Rp /a/lib/modules/* /b/lib/modules/
    7. nano /etc/fstab (add /dev/mmcblk0p5 / and hash out other entries)
    8. umount /a
    9. unmount /b
    10. sync
    11. CTRL-D (reboot)
    12. Ensure the commandline.txt is configured correctly on USB (root=/dev/mmcblk0p5) and a similar screen to the following should pop up

Once you've configured the setup you should get the usual desktop like the below

Confirmation the device is indeed a Surface 2


Boot from internal flash instead of USB

There is good background detail on the UEFI Boot Sequence on Open Surface RT. The following steps describe how to get Linux booting from the internal mmc drive without the need to boot from USB.
  • mount EFI partition (linux = mmcblk0p2 | windows disk 0 partition 1)
  • copy boot files to EFI partition (microsoft/boot, test.efi (shim to boot.efi), boot.efi (linux kernel), tegra114-microsoft-surface-2.dtb, commandline.txt, config.txt
  • rename microsoft/boot to microsoft/boot_win
  • copy in microsoft/boot to microsoft/boot which will load the test.efi policy to enable linux to boot
  • can edit boot sequence from EFI partion in linux (mount /dev/mmcblk0p2)
  • can edit boot sequence from EFI partion in windows (/dev/mmcblk0p2) diskpart, list disk, select disk 0, list partition, select partition 1, assign letter=b, exit

These steps allow for you to automatically reboot into your OS of choosing though it doesnt give you a nice menu selector with a time out like say GRUB does. Further consideration is to look into bcdedit to add a second boot menu option for test.efi though need to consider if you reboot the surface and you are prompted to choose a boot option this may not be possible if you are accessing remotely.

Other considerations 


Other options considered which could be of interest to people:
  • consider compiling ARM32 ext driver for windows 8 - seems like cygwin would need to be compiled first, no one has compiled to date based on list of arm windows software
  • other distributions like ubuntu 18 server seems to run on the surface2
  • cross compiling custom kernels
    • #apt install git make gcc g++ device-tree-compiler bc bison flex libssl-dev libncurses-dev python3-ply python3-git libgmp3-dev libmpc-dev gcc-arm-linux-gnueabihf

    • #export ARCH=arm

      #export CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf-

    • #make surface-2_defconfig

    • Confirm the following is in .config

      CONFIG_EFI=y

      CONFIG_EFI_STUB=y

    • #make

    • Compiled zImage will be in arch/arm/boot/zImage which can be renamed to boot.efi

  • initramfs attached to zImage (EFI Stub)
    • compile kernel with CONFIG_INITRAMFS_SOURCE="/initram/fs/root/directory"



No comments:

Post a Comment