Skip to content

Lassulus/pixel8-linux

Repository files navigation

Pixel 8 Linux

Minimal Linux environment on a Google Pixel 8 (shiba) with USB serial console.

Replaces the Android init with a custom static binary that boots to a root busybox shell accessible over USB-C serial (USB gadget ACM).

What it does

  1. Mounts essential filesystems (proc, sys, dev, configfs)
  2. Disables SELinux enforcement (required for USB gadget configfs)
  3. Loads all 209 vendor kernel modules from vendor_kernel_boot
  4. Feeds the hardware watchdog (Tensor G3 / Exynos s3c2410_wdt)
  5. Configures USB gadget ACM serial via configfs
  6. Creates /dev/ttyGS0 device node (major number from /proc/tty/drivers)
  7. Spawns a busybox root shell on the serial port

Requirements

  • Google Pixel 8 (shiba) with unlocked bootloader
  • GrapheneOS bootloader + vendor_boot + vendor_kernel_boot flashed
  • AVB verification disabled: fastboot flash vbmeta --disable-verity --disable-verification vbmeta.img
  • Stock GrapheneOS init_boot ramdisk extracted as stock_raw.cpio

Build & Flash

# Build the overlay
nix build .#initramfs

# Assemble and flash (requires stock ramdisk + avbtool + mkbootimg)
cat stock_raw.cpio result/overlay.cpio > combined.cpio
lz4 -l -9 combined.cpio ramdisk.lz4
mkbootimg --header_version 4 --ramdisk ramdisk.lz4 \
  --os_version 16.0.0 --os_patch_level 2026-02 --output init_boot.img
avbtool add_hash_footer --image init_boot.img \
  --partition_name init_boot --partition_size 8388608
fastboot flash init_boot init_boot.img
fastboot reboot

Connect

After ~55 seconds, /dev/ttyACM0 appears on the host:

picocom /dev/ttyACM0

You get a root shell (uid=0 gid=0) with busybox utilities.

Architecture

The boot image is an overlay CPIO concatenated after the stock GrapheneOS init_boot ramdisk. CPIO concatenation means later entries override earlier ones — our /init and /bin/ replace stock ones. Kernel modules at /lib/modules/ come from the vendor_kernel_boot partition (not modified).

init_boot.img
├── stock GOS ramdisk (base filesystem layout)
└── our overlay:
    ├── /init          (custom static C binary, PID 1)
    └── /bin/
        ├── busybox    (static aarch64 binary)
        ├── sh -> busybox
        ├── ls -> busybox
        └── ...        (40+ command symlinks)

Key technical details

  • Watchdog: Tensor G3 has s3c2410_wdt — must be fed or phone reboots at ~80s
  • SELinux: Must be disabled for configfs gadget mkdir/symlink/write operations
  • Module loading: Multi-pass finit_module() with kernel cmdline options (e.g., tcpci_max77759.conf_sbu=0) — matches AOSP Modprobe behavior
  • ttyGS0: devtmpfs does not auto-create the gadget serial device node; must mknod using the dynamically-assigned major from /proc/tty/drivers
  • USB IDs: 18d1:4ee7 (Google Nexus/Pixel charging + debug)
  • UDC: 11210000.dwc3 (Exynos DWC3 USB controller)
  • Boot time: ~55 seconds from power-on to USB serial available

Files

  • init.c — Custom init binary source (static C, musl cross-compiled)
  • initramfs.nix — Builds the overlay CPIO (init + busybox)
  • boot-img.nix — Assembles the flashable init_boot.img
  • mkbootimg.nix — AOSP mkbootimg tool
  • kernel.nix — GrapheneOS prebuilt kernel (reference, not used for init_boot)

About

vibecoded insanity for booting nixos on pixel 8

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors