#!/usr/bin/python import fileinput, re, sys # # It turns out the "Trusty Secure OS" Crippleware on the Nexus 9 is # good for least something. It is thankfully pretty chatty, meaning # you can use it for logging from code where it's inconvenient # or impossible to write to the UART directly, like MMU bringup code ;-). # # A sequence like: # mov x0, #'V' # smc #0xFFFF # # ...will result in the following getting emitted. I am guessing x1...x3 # get printed here as param0..2 but I am too lazy to check. # # smc_undefined:67: Undefined monitor call! # smc_undefined:67: SMC: 0x56 (Stdcall entity 0 function 0x56) # smc_undefined:67: param0: 0xf77c2e69 # smc_undefined:67: param1: 0xf77c2e68 # smc_undefined:67: param2: 0x0 # # Now you can do basic logging to debug early bring-up. The following # Python will turn your giant Minicom capture into something more # sensible. # def process(line): m = re.match('\s*smc_undefined:67: SMC: (0x[0-9a-f]+)', line) if m: sys.stdout.write(chr(int(m.groups(), 16))) for line in fileinput.input(): process(line) print("\n");
Friday, November 28, 2014
Sunday, November 23, 2014
64-bit ARM OS/Kernel/Systems Development on a Nexus 9The Nexus 9 is based on a 64-bit nVidia K1 chip. At the moment it is the most affordable (price wise) and accessible (unit-wise) platform for exploring OS work on an AArch64 platform. The Nexus 9 allows performing an unlock via "fastboot oem unlock", allowing custom Android images to be booted.
What this isThis is a small demo, demonstrating how to build and boot arbitrary code on your Nexus 9 and do some basic I/O. The demo demonstrates serial I/O and draws two black diagonal lines on the framebuffer.
What you need - required
- A Nexus 9, unlocked. Search Youtube for walkthroughs
- GNU Make
- An AArch64 GNU toolchain
- ADB/Fastboot tools
- Booting tools from https://github.com/pbatard/bootimg-tools somewhere in your path
What you need - optional
- A headset to RS232 adapter. I've used a cable I've had from the Motorola Xoom project (the first...errr, Nexus, before the devices got called a "Nexus"). You can try http://www.accuvant.com/blog/building-a-nexus-4-uart-debug-cable
How it worksHBOOT, the Nexus bootloader, expects images to be in a certain format. The booted kernel/code must:
- Be 64-bit
- Be binary (not ELF)
- Be linked at 0x80080000
- Be compressed using "gzip"
- Be followed by the binary FDT
- Be contained in an "ANDROID!" boot image.
- The link address appears to be hardcoded in HBOOT. The Android boot image bases and the AArch64 kernel header fields appear to be ignored.
- The boot image can contain an additional ramdisk/initrd/payload.
- The FDT is patched by HBOOT to contain correct linux,initrd-start and linux,initrd-end addresses.
How to build
$ CROSS_COMPILE=aarch64-linux-gnu- make
How to bootConnect your Android tablet via a USB cable. Optionally connect the UART headphone jack adapter to your computer. The settings are 115200 8-n-1.
$ adb reboot-bootloader $ fastboot boot nexus9_demo
Actual output of the demo
Hello! CurrentEL = 0000000000000001 SCTLR_EL1 = 0000000010C5083A Bye!
Where to go from here
"nexus9_dts" is the decompiled "nexus9_dtb". "nexus9_dtb" was extracted from the Android boot.img.
Final thoughtsFrom studying the Tegra K1 TRM, the K1 should have virtualization support (i.e. EL2). However, the HTC firmware does not allow booting an EL2-enabled OS. All kernels are booted in EL1. This is rather unfortunate and prevents playing around with KVM and Xen on this platform. Perhaps there are some problems with EL2 support. Or perhaps HTC/nVidia/Google were too myopic to allow EL2 access. It's unclear if the "oem unlock" allows reflashing custom unsigned firmware. "nvtboot" seems to enforce signed "Trusted OS" payloads, at least from dumping the strings. The boot flow looks something like this:
- "nvtboot" (32-bit) runs on the AVP/COP.
- "nvtboot" loads "tos" (64-bit) (Trusty aka Secure OS) on the AArch64 chip.
- "tos" loads HBOOT (32-bit).
- HBOOT loads Android and implements the fastboot protocol.