Compiling kernel

Clone kernel

You should be able to use the latest kernel without problems.

wget tar -xf linux-5.12.3.tar.xz cd linux-5.12.3/

The commands above download the kernel source into the linux-5.12.3 directory, relative from your current path.

Configure the kernel

Adding a devicetree

Go to ./arch/arm/boot/dts, create a file with the name tegra30-microsoft-surfaceRT.dts and paste the contents of the code block in the devicetree sub-section.

Search for dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += in the Makefile (same directory), there you can see a few lines which begin with tegra30, add a line with the device tree file name you created above, but instead of the extension .dts use .dtb. Be aware that you will need to add a backslash (\) at the end of the previous line. Here is a picture how it should look like:

Apply patch to get ACPI working

As of 22. Feb 2021 ACPI Parking Protocol can't be upstreamed so you need to apply a patch yourself.

Open up a terminal and cd into your linux-5.12.3 directory. Then download the patch from bellow and run git apply 0001-Add-ACPI-Parking-Protocol-for-arm32-devices.patch This should add ACPI Parking Protocol to your kernel and allows you to use SMP.

The patch doesn't follow kernel coding conventions. This will eventually be fixed.

Why no upstreaming?

ACPI isn't implemented for arm32, which means that parsing the ACPI tables isn't possible.

For the ACPI Parking Protocol the MADT/APIC table is required, but can't be parsed at runtime because of the missing ACPI driver.

Right now the MADT table information is hardcoded. Change arch/arm/kernel/acpi_parking_protocol:acpi_parking_protocol_cpu_init as needed.

Editing kernel build configuration

First run the command make ARCH=arm tegra_defconfig This will create a standard kernel config for tegra soc's.

Open the file .config in the kernel source directory with your favorite text editor and past the following at the end of the file


Build the kernel

To build the kernel use the command make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j $(nproc) It will use all of your available cores. This command can take a while depending on your computer's speed. (5+ minutes)

Note: If you get asked what configuration you want to choose, just press enter, this will take the standard value.

The output image is arch/arm/boot/zImage The output device tree is arch/arm/boot/dts/tegra30-microsoft-surfaceRT.dtb


You will need secureboot disabled (yahallo applied) to boot uefi shell and then chainload the kernel

Place uefi shell onto your bootable usb drive (as efi/boot/bootarm.efi) and place the zImage and the tegra30-microsoft-surfaceRT.dtb files onto the root of your usb drive.

You will need to create a startup script for uefi shell:

# file: startup.nsh
# add initrd=<initrd.img-filename> if you want to boot a ramdisk image
zImage dtb=tegra30-microsoft-surfaceRT.dtb
# shutdown if something went wrong
reset -s

Note: You can also specify root=<device> instead if you want to boot to a root filesystem. You can use rpi os.

Now plug in your usb drive in and boot from it. You should see output from kernel on UART.

Boot from internal storage

To boot from internal storage, you need to have an EFI partition with correct files. To get your zImage, device tree and the startup.nsh there easily, you can use the following EFI shell script:

cp tegra30-microsoft-surfaceRT.dtb fs1: >> log.txt
cp zImage fs1: >> log.txt
cp startup-system.nsh fs1:\startup.nsh >> log.txt
reset -s

It will copy the device tree, zImage and the startup-system.nsh over to the EFI partition on the internal storage. Fill your startup-system.nsh with the linux boot commands. (The commands you normally have in your startup.nsh)