Skip to content

Latest commit

 

History

History
91 lines (67 loc) · 25.5 KB

01-boot-path.md

File metadata and controls

91 lines (67 loc) · 25.5 KB

Pixel 6a (bluejay) boot-path research

Desk research only; no device commands were run. VERIFIED-FROM-SOURCE means a cited source states the fact directly. INFERRED means it is a compatibility conclusion, extrapolation from shared GS101 hardware, or a recommendation. Unknowns are called out instead of filled from the Redmi Note 10 Pro reference port.

Findings at a glance

  • VERIFIED-FROM-SOURCE: Bluejay is a 6 GB GS101/Tensor G1 device. The upstream GS101 enablement names Pixel 6a as a GS101 device, while the first mainline DTS/patch series added the Oriole board, not a bluejay board DTS. Google Pixel 6a specifications, upstream GS101 series cover letter, mainline Google DT binding
  • VERIFIED-FROM-SOURCE: Bluejay uses Android boot-image header v4 in the documented postmarketOS experiment; its stock vendor_boot contained two vendor ramdisks and the DTB. Android's v4 vendor_boot layout includes ramdisk fragments, DTB, table, and bootconfig. Pixel 6a postmarketOS port notes, AOSP vendor boot partitions
  • UNKNOWN: Public sources located do not establish that bluejay ABL accepts fastboot boot for an arbitrary unsigned v4 image, nor its exact kernel staging address, maximum transfer size, or exact entry EL. The documented bluejay pOS experiment used fastboot flash boot, not fastboot boot; an unlocked-bootloader report said its flashed image needed an AVB footer. Treat temporary boot of the shim as a first hardware gate.
  • INFERRED: The most defensible shim path is to preserve a standard boot image wrapper and ARM64 Image header, use the bootloader's current bluejay DTB/DTBO and handoff if its temporary-boot path supports it, and make the shim position-independent with respect to the address ABL selects. Do not carry over the Redmi v2 header, Qualcomm memory map, or framebuffer address by assumption.

1. Bootloader, Android image format, and mainline precedents

What is established

  • VERIFIED-FROM-SOURCE: Bluejay's bootloader can be unlocked with fastboot flashing unlock; this wipes data. The postmarketOS wiki documents the unlock procedure. postmarketOS bluejay page
  • VERIFIED-FROM-SOURCE: A first-person bluejay port rebuilt an Android boot.img with --header_version 4, signed it with a generated AVB key/footer, then installed it using fastboot flash boot. The author reports that an unsigned image was refused even while unlocked. This is evidence about that firmware and flash path only; it does not prove temporary fastboot boot follows the same AVB check. Porting report, image packing/signing/flashing
  • VERIFIED-FROM-SOURCE: AOSP boot header v4 stores kernel and ramdisk sizes and the boot signature size; it no longer stores the DTB address. In Android 11+ GKI, vendor-specific information and DTB move to vendor_boot. vendor_boot v4 includes the ramdisk fragments, DTB, ramdisk table, and bootconfig. The bootloader must consult both boot and vendor_boot. AOSP boot image header, AOSP vendor boot partitions
  • VERIFIED-FROM-SOURCE: The 2023 bluejay port report unpacked boot.img as GKI + first-stage ramdisk and vendor_boot as two vendor ramdisks; the latter included kernel modules. This agrees with the v4/GKI split. Bluejay launched on Android 12. AOSP says init_boot is for devices launching with Android 13; an Android 12 device upgraded to Android 13 does not acquire that layout requirement simply by upgrading. Check the actual factory image/release being targeted because later image sets can evolve. Porting report, AOSP generic boot partition
  • VERIFIED-FROM-SOURCE: AOSP's fastboot boot protocol command downloads an image and boots it through the normal boot.img path; the protocol does not define one universal size limit. Available download RAM is implementation-dependent. AOSP fastboot protocol
  • VERIFIED-FROM-SOURCE: The ARM64 Linux Image begins with a 64-byte header containing branch instructions, text_offset, image_size, flags, and magic ARM\x64. The boot protocol requires an aligned usable-RAM placement, Image at base plus text_offset, at least image_size free, x0 set to the physical DTB address, MMU off, and either non-secure EL2 (recommended) or EL1. The MMU must be off; I-cache may be on or off if stale lines are absent. The protocol requires image cache maintenance to PoC but does not say all caches must be off. Linux ARM64 boot protocol

Answers for this shim

  • VERIFIED-FROM-SOURCE (community use report): A Pixel 6a root guide documents fastboot boot magisk_patched.img as a temporary RAM boot, then fastboot flash boot for persistence. This supports the practical answer that bluejay ABL exposes the temporary-boot path for an Android boot image. UNKNOWN: no Google ABL source or bluejay-specific spec confirms arbitrary image handling, and this is not evidence that a custom shim image is accepted. Pixel recovery-as-boot images are specifically documented by AOSP as not bootable with fastboot boot, so recovery instructions are not a valid counterexample. Pixel 6a temporary boot guide, AOSP recovery note
  • VERIFIED-FROM-SOURCE: A community Pixel 6a kernel-build question tried fastboot boot Image.lz4 and failed, then moved to packaged boot.img; that compressed kernel was not a valid Android boot image, so it does not show that ABL lacks the command. Attempted raw Image.lz4 boot
  • INFERRED: An arbitrary bare-metal payload still needs a valid Android image container that ABL accepts and an ARM64 Image header it will load and branch into. The shim can be non-Linux after entry, but the bootloader does not know how to execute a generic ELF or raw Mach-O. fastboot boot is not an address-independent jump primitive: normal boot-image parsing, memory placement, DTB handling, and security policy still apply.
  • UNKNOWN: Pixel-specific kernel load address, text_offset treatment, staging addresses for the boot/vendor ramdisks and DTB, image-size ceiling, and whether a temporary boot command uses current flashed vendor_boot/dtbo are not established in the sources reviewed. Android's vendor boot header contains kernel/ramdisk/DTB load-address fields, but those generic fields do not prove exactly what this ABL uses for the temporary image path. Obtain the exact firmware image layout and verify with a live boot before using fixed addresses.
  • VERIFIED-FROM-SOURCE (generic contract): Respect Linux text_offset and image_size; the protocol states that the bootloader places the image at a 2 MiB-aligned base plus text_offset. UNKNOWN (bluejay ABL): whether ABL follows that exact calculation for a temporary v4 image. The Reddit/StackOverflow report above is not sufficient evidence.
  • INFERRED: Unlocked AVB behavior is not uniform enough to assume “unsigned is always accepted.” AOSP's general AVB unlocked mode is permissive, but the bluejay first-person report says a custom flashed image still needed a valid AVB footer. Test fastboot boot separately from fastboot flash; a randomly generated footer accepted on the reported firmware should not be mistaken for Google's trusted signing key or for proof of all ABL versions. AOSP AVB README, bluejay report

Mainline and postmarketOS evidence

  • VERIFIED-FROM-SOURCE: The initial 20-patch upstream series added GS101 SoC support and Pixel 6 / Oriole board support, enough to boot a BusyBox initramfs. The author explicitly said GS101 is shared by Pixel 6a, but that submission included DT for GS101 and Oriole, not bluejay. Linux mailing-list v5 series
  • VERIFIED-FROM-SOURCE: A later Linaro series added a simple framebuffer and moved common GS101 Pixel 6/6 Pro data into gs101-pixel-common.dtsi; its cover letter says the common pieces can apply to Pixel 6a while board-specific differences (for example display) still need distinguishing. Linux's arch/arm64/boot/dts/exynos/google/ has GS101/Oriole/Raven sources; do not treat it as a completed bluejay DTS. Linaro patch series, mainline DTS directory
  • VERIFIED-FROM-SOURCE: The AOSP Pixel-kernel guide documents an android-mainline upstream build for Pixel 6 and 6 Pro using fastboot flash boot, fastboot flash dtbo, and vendor_boot:dlkm; it explicitly limits the upstream build instructions to Oriole/Raven. It does not list Pixel 6a as a supported upstream-mainline board. AOSP Pixel kernel guide
  • VERIFIED-FROM-SOURCE: The postmarketOS wiki labels bluejay “console only,” says its experimental mainline proof of concept was based on Google's 5.15 kernel with downstream Android driver modifications, and says installation was not packaged. The detailed port report reached userspace using stock GKI, custom initramfs, and vendor modules; it needed USB network/SSH because display was not driven in that configuration. postmarketOS bluejay page, port report
  • INFERRED: There is precedent for loading alternate software on bluejay, but no cited source demonstrates a standalone non-Linux shim or fully upstream mainline kernel boot on bluejay. The most relevant report is downstream GKI + userspace changes, not a reusable bare-metal loader recipe. I found no bluejay U-Boot chainloading precedent in the sources reviewed.

2. Entry state, EL2, and pKVM

  • VERIFIED-FROM-SOURCE (ARM64 ABI): AArch64 Linux supports entry at non-secure EL2 or EL1, prefers EL2 for virtualization extensions, requires the MMU off and interrupts masked, and passes the DTB physical address in x0. Linux ARM64 boot protocol
  • VERIFIED-FROM-SOURCE: Android's AVF documentation says its generic kernel is entered at EL2 and initializes pKVM there. The bluejay postmarketOS report exposes fastboot oem pkvm enable as a control for pKVM. This establishes that Pixel 6a firmware/kernel has a pKVM option; it does not establish the EL or MMU state of an arbitrary fastboot boot payload. AOSP AVF architecture, bluejay port report
  • INFERRED: Expect EL2 to be relevant when the normal Android/pKVM path is active, but do not hardcode that for a temporary custom image or assume ABL enabled/disabled pKVM identically. A shim should read CurrentEL, SCTLR_EL1/2, HCR_EL2, and caches at its first instructions, and support the actual entry level. x0=DTB is the Linux ABI contract; ABL could pass a merged FDT there, but that exact handoff for bluejay fastboot boot remains unverified.

3. DRAM and reserved regions

  • VERIFIED-FROM-SOURCE: Bluejay has 6 GB LPDDR5. The mainline generic GS101 DTS defines peripherals but does not provide a complete bluejay physical DRAM bank map; the bootloader supplies RAM information in the boot DT. Google specs, GS101 DTS, Linux ARM64 boot protocol
  • VERIFIED-FROM-SOURCE (historical GS101 tree, not bluejay's live map): An early Google gs101.dts declared four 2 GiB banks at 0x80000000, 0x880000000, 0x900000000, and 0x980000000. Later common DTS sources omit a memory node, leaving the bootloader to describe actual memory. Pinned early gs101.dts
  • UNKNOWN: Which banks/portions ABL enables on the 6 GB bluejay SKU, the exact live memory bank starts/sizes and holes, and firmware-specific secure carve-outs remain unverified. Do not translate “6 GB” into an assumed contiguous [base, base+6 GiB) mapping. Capture and parse the live merged FDT before selecting XNU physBase/memSize or creating page tables.
  • VERIFIED-FROM-SOURCE (GS101 SoC DTS, applicability to bluejay inferred): Google’s downstream common GS101 reserved-memory source has no-map regions including GSA protected RAM at 0x90200000 (4 MiB), TPU firmware at 0x93000000 (16 MiB), AOC at 0x94000000 (48 MiB), ABL reservation at 0xf8800000 (32 MiB), logs, and modem carve-outs at 0xf0000000, 0xf6200000, 0xe8000000, and 0xee000000. These are SoC/common DTS values, not verified measurements of the exact bluejay boot FDT. no-map means do not include them in the normal linear mapping; they are not free RAM. GS101 dts/gs101-rmem.dtsi
  • VERIFIED-FROM-SOURCE: GS101 DTS enumerates S2MPUs for peripherals including CPU cluster, DPU, GPU, UFS, USB, and media devices. These are system MMU / second-stage protection units for bus masters. GS101 S2MPU DTS
  • INFERRED: S2MPU is not evidence of the Qualcomm XPU CPU speculative-read fault described by the Redmi source. It is still a reason to leave DMA clients quiesced and preserve Trusty/GSA, TPU, modem, AOC, ABL, display, and firmware reserved regions. Public sources do not show that CPU cacheable aliases to all such memory fault; the safe initial shim policy is conservative: map only verified usable RAM cacheable, preserve every live FDT reservation, and map device registers as Device.

4. Bootloader framebuffer and display

  • VERIFIED-FROM-SOURCE (mainline Oriole/common DTS patch): Linaro's simple-framebuffer change describes a chosen node (framebuffer-0) backed by cont_splash_mem; the Oriole display values are 1080x2400, stride 4320 bytes, a8r8g8b8, at physical 0xfac00000, with the splash reserved no-map. The series states shared pieces may apply to GS101 Pixels, but explicitly warns board-specific display differences require handling. Treat the address/format as an Oriole/mainline reference, not confirmed bluejay ABL state. Simple framebuffer patch
  • UNKNOWN: No source found establishes bluejay's bootloader framebuffer physical address, stride, pixel byte order, or that ABL leaves display scanout live for a non-Linux kernel. The pOS bluejay experiment did not drive the display. Do not reuse the Redmi framebuffer 0x9c000000, or infer bluejay uses the Oriole 0xfac00000 without checking its live FDT/bootloader state.
  • VERIFIED-FROM-SOURCE (Pixel 6/6 Pro; bluejay applicability inferred): Linaro's simple-framebuffer series says the stock bootloader disables the DECON hardware trigger before jumping to Linux, so framebuffer writes do not reach the display; its earlier v2 design described common GS101 Pixel DT data for Pixel 6, 6 Pro, and 6a, while the submitted v4 DTS changes target Oriole and Raven. This is strong evidence for a GS101 display handoff issue, but not a direct bluejay ABL measurement. Linaro patch cover letter
  • INFERRED: A simple framebuffer only updates memory; it does not initialize the panel, DPU, clocks, or refresh mode. Bluejay likely needs the DECON trigger restored, but the required register value and whether clocks/panel remain live are not established here. Validate with a small solid-color write and preserve the splash memory as reserved until scanout behavior is known.

5. Reset and return to bootloader

  • VERIFIED-FROM-SOURCE: Mainline GS101 DTS describes the Pixel reboot controller with PS_HOLD and software-reset registers (0x3e9c and 0x3a00 offsets from PMU syscon) and reboot command at offset 0x0810 (SYSIP_DAT0). A downstream pixel reboot driver writes reboot mode both to SYSIP_DAT0 and Google's persistent GBMS storage. GS101 DTS, downstream pixel reboot driver
  • VERIFIED-FROM-SOURCE: GS101 mainline Linux registers a syscon reboot handler for warm/soft reset and uses PMU SYSTEM_CONFIGURATION (0x3a00) bit 1; hard/cold reset and power-off use PAD_CTRL_PWR_HOLD (0x3e9c) bit 8. The reboot handler takes priority over PSCI in Linux. GS101 PMU documentation says PMU_ALIVE writes are EL3-only and are performed through SMC 0x82000504; this means a direct EL1 MMIO write is not the documented reset mechanism. Linux GS101 syscon reboot driver, GS101 PMU driver
  • VERIFIED-FROM-SOURCE: Mainline GS101 reboot-mode definitions include bootloader 0xfc, fastboot 0xfa, recovery 0xff, and rescue 0xf9 in SYSIP_DAT0 (0x0810). A separate cold-reset path stores the requested mode in a MAX77759 NVMEM cell; the patch describes that cell as communicating the requested boot mode to the bootloader on cold reset. Which source bluejay ABL checks on each reset path is not established. GS101 reboot-mode patch, NVMEM reboot-mode patch
  • UNKNOWN: Whether PSCI SYSTEM_RESET or SYSTEM_RESET2 works on bluejay was not established; Linux's GS101 syscon choice means the shim should not assume it. INFERRED: To request bootloader, set the mode using a tested platform path before reset; stock Android's fastboot reboot bootloader is preferable when available. An XNU shim should not assume an untested PSCI/SMC reset will leave fastboot selected.
  • VERIFIED-FROM-SOURCE: Pixel bootloader mode can be reached cold with Power + Volume Down. postmarketOS bluejay wiki

6. Debug, persistent logs, and storage

  • VERIFIED-FROM-SOURCE: Bluejay's USB-C SBU pins expose a 1.8 V UART. The documented enable is fastboot oem uart enable; the report uses a USB-C breakout or Google's USB-Cereal adapter, a 1.8 V USB-UART adapter, and 115200 8-N-1. Disable with fastboot oem uart disable. Check connector orientation/pin assignment rather than assuming TX/RX. Pixel 6a UART instructions
  • VERIFIED-FROM-SOURCE: Mainline GS101 DTS sets earlycon=exynos4210,mmio32,0x10A00000 console=ttySAC0,115200n8; UART MMIO is 0x10a00000, compatible google,gs101-uart, IRQ 634. GS101 DTS, GS101 UART binding/example
  • INFERRED: The earlycon string and address are a Linux UART starting point, not proof that pins/clocks are routed to the USB-C SBU UART in the shim's first instructions. A bare-metal shim needs to enable/route the UART itself, or initialize it through known firmware state. The vendor-kernel command fastboot oem uart enable configures the debug path but should be verified on the exact ABL version.
  • VERIFIED-FROM-SOURCE (common GS101 DTS): The reserved map declares a ramoops area at 0xfd3ff000, size 4 MiB, with 2 MiB console and 2 MiB pmsg buffers; it separately reserves 1 MiB of bootloader logs beginning at 0xfd800000 (bl_log and bl_old_log subregions). Android init reads /sys/fs/pstore/console-ramoops-0 and console-ramoops. GS101 reserved memory DTS, GS101 init script
  • INFERRED: Ramoops is designed for persistent RAM across a warm reset, but its exact survival depends on reset type and firmware reuse; it's not a guaranteed cold-boot log disk. Reserve the range exactly and don't use it for XNU heap or cacheable RAM. A custom shim can keep its own ring in a separately reserved region, or persist to userdata; after reboot use Android/recovery to read pstore or mount/pull the ring from userdata. Do not count on Android pstore to expose a custom ring unless it is wired through the ramoops/pstore driver.
  • VERIFIED-FROM-SOURCE: Bluejay is sold with 128 GB UFS storage. Android boot/vendor-boot slots are small boot artifacts; they are not viable places for a ~16 GB root image. Google Pixel 6a specifications
  • INFERRED: userdata is the only plausible existing partition for a ~16 GB iOS root image and persistent file log while leaving bootloader, modem, persist, and other calibration partitions intact. It is not non-destructive: using it as a raw HFS+ volume erases Android user data and encryption. A/B slot B is not a 16 GB storage pool; do not overwrite boot_b, vendor_boot_b, dtbo_b, vbmeta_b, modem, persist, or secure partitions as root storage. Verify the live partition table and retain full backups before any later write.

7. Biggest risks, ranked

  1. Critical — shim-specific temporary ABL handoff is not proven. fastboot boot is available for temporary Android boot images, but no source confirms bluejay accepts this custom shim image, its AVB handling, merged FDT inputs, addresses, or size ceiling. The pOS experiment's successful path was signed fastboot flash boot. This can block the entire no-flash design.
  2. Critical — no complete bluejay upstream DTS or exact memory map. Mainline GS101 support is SoC + Oriole/Raven. Firmware-specific memory banks, protected regions, display reservations, and DT overlays must come from the live bluejay FDT. A broad cacheable map can corrupt firmware or DMA state.
  3. High — entry-level and pKVM state. Linux allows EL1 or EL2, and Android's pKVM kernel uses EL2; the exact temporary boot state is unknown. EL2 traps, GIC security state, timers, and firmware-owned services can differ from the reference Redmi/XNU bring-up.
  4. High — display handoff. Oriole simplefb patch values provide a starting point, but there is no verified bluejay framebuffer handoff and the bluejay pOS test did not get a display. Scanout could stop or need DPU/panel initialization.
  5. High — XNU board port breadth. The reference shim/XNU setup depends on Redmi/Qualcomm PSCI, interrupt, UFS, framebuffer, and memory behavior. GS101's S2MPUs, ACPM, secure co-processors, UFS, reset mode, and peripheral clocks are different. Only boot-path/debug primitives are covered here; no reusable SoC drivers are implied.
  6. Medium — recovery/logging. UART works only after firmware enablement and correct SBU wiring. Ramoops survives only some reset paths and overlaps specifically reserved memory. A separate userdata log is persistent but destroys Android data if the whole partition is repurposed.

Reference checkout notes

The requested upstream/README.md, upstream/NOTES.md sections, upstream/shim/*.c, upstream/shim/build.sh, and upstream/tools/mkpayload.py were read as the Redmi sweet reference. Its shim is packed as Android boot image v2 and implements a Linux ARM64 Image header; its loader expects x0=DTB, EL1/MMU off in that environment, and its MMU avoids Qualcomm XPU-protected ranges. Those are source facts about SM7150 only. The sweet framebuffer 0x9c000000, header v2, PSCI calls, bank map, and XPU/cache mapping rules are not Pixel 6a facts and must not be ported without new evidence.