Skip to content

xjordanx/speedrun

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

Project Speedrun — i.MX 8M Mini Custom Firmware Build

Custom Yocto Linux image for the Project Speedrun board (NXP i.MX 8M Mini EVK) built on the Walnascar (6.12) BSP release. This build replaces the stock NXP imx-image-full demo image with a GNOME 48 desktop featuring hardware-accelerated Chromium, media playback, and game engines targeting the Vivante GC NanoUltra GPU.

Machine: imx8mmevk | Distro: fsl-imx-xwayland | Image: imx-image-multimedia | Layer: meta-quilter (priority 99)

Credit Where Credit is Due

Thanks especially to Brandin Claar of remodulate. for helping us put this recipe together.


What Differs from Stock NXP imx-image-full

The stock NXP image ships Weston as its compositor with Qt5/6 demos. This build replaces the entire desktop stack and adds significant customization:

Area Stock NXP Project Speedrun
Desktop Weston compositor + Qt demos GNOME 48 (Mutter 48 + GDM)
Init system systemd (NXP default) systemd with GNOME targets, GDM as display manager
Browser None Chromium 129 with V4L2 HW encode/decode, Firefox 147 (pre-built)
Media player GStreamer demos mpv with V4L2 M2M HW decode, ffmpeg with V4L2 codecs
Boot splash psplash (Yocto default) Plymouth (spinner theme) with Quilter logo watermark
U-Boot branding NXP/DENX logos Quilter splash logo, "Project Speedrun" device tree model string
Audio Basic ALSA PulseAudio with WM8524 codec config, Bluetooth A2DP
Package format RPM Debian (.deb) with apt package management on-device
Games None GZDoom (Freedoom 1 & 2), Quake GLES1 port
GPU renderer N/A (Weston direct) GSK Cairo + COGL GLES2 (Vivante workarounds)

Chromium — Graphics and Video Acceleration

Chromium 129.0.6668.100 runs on Wayland/Ozone with the Vivante GLES 2.0 GPU. NXP provides V4L2 video decode patches in meta-imx-sdk/dynamic-layers/chromium-browser-layer/ (22 patches for Amphion/Hantro decoders, HEVC, G2D, NV12 zero-copy). Three additional custom patches in meta-quilter enable encode and fix a GPU crash:

Custom Chromium Patches

Patch Purpose
chromium-v4l2-hw-encode-129.patch V4L2 MMAP hardware video encoding for the Hantro H1 encoder (WebRTC/Google Meet). Forces MMAP memory type, adds stride-aware buffer copy, removes VP9 SW encoder to force HW codec selection, prioritizes HW formats in WebRTC negotiation, disables low-resolution software fallback. Touches 8 source files.
chromium-v4l2-hw-encode-codec-filter-129.patch Debug CLI flags (--webrtc-disable-vp8, --webrtc-disable-h264, HW-only variants) for isolating codec issues during development.
chromium-gles2-glgetstringi-null-check-129.patch Fixes chrome://gpu SIGSEGV on GLES 2.0 drivers. The Vivante GC NanoUltra lacks glGetStringi (a GLES 3.0+ function); Chromium's extension enumeration calls a NULL function pointer. Patch installs a safe stub at init time in DriverGL::InitializeStaticBindings() — required because thin LTO inlines across compilation units, making call-site guards insufficient.

Chromium GN Build Flags

use_v4l2_codec=true  use_linux_v4l2_only=true
proprietary_codecs=true  ffmpeg_branding="Chrome"

Chromium Runtime Flags

--use-gl=egl --ozone-platform=wayland --enable-features=VaapiVideoEncoder
--video-capture-use-gpu-memory-buffer --ignore-gpu-blocklist

GNOME Desktop

GNOME 48 with Mutter 48.0 running on Wayland via the fsl-imx-xwayland distro. The upgrade from Scarthgap (Mutter 46.x) was driven by persistent screen flickering caused by Mutter's multi-GPU detection treating the i.MX 8M Mini's split DRM architecture (card0 = LCDIF display controller, card1 = Vivante GPU) incorrectly. Mutter 48 includes native triple buffering merged upstream, eliminating the issue.

Vivante GPU Workarounds

The Vivante GC NanoUltra only supports GLES 2.0. Several workarounds are required:

Package What It Does
gsk-cairo-config Sets GSK_RENDERER=cairo globally — GTK4's GL renderer calls GLES 3.0 functions unsupported by Vivante
gles-env Sets COGL_DRIVER=gles2, CLUTTER_DRIVER=gles2, GDK_GL=gles via /etc/profile.d/
mutter_%.bbappend Injects stub EGL/eglmesaext.h into sysroot — Mutter 48 unconditionally includes this Mesa-specific header which Vivante EGL doesn't provide
gnome-session_%.bbappend Relaxes -Werror=incompatible-pointer-types — Vivante EGL native types differ from Mesa's
mpv_%.bbappend Disables egl-drm/gbm (Vivante EGL types are Wayland-only, incompatible with GBM surfaces); forces gpu-api=opengl in /etc/mpv/mpv.conf

GNOME Desktop Packages

packagegroup-gnome-desktop, gnome-terminal, nautilus, gedit, evince, eog, gnome-tweaks, cantarell-fonts, networkmanager

Display Manager

GDM replaces NXP's default Weston service. The imx-image-multimedia.bbappend masks Weston systemd units and enables gdm.service under graphical.target. A Weston session .desktop file is also installed for GDM's session chooser.


U-Boot and Device Tree Modifications

The u-boot-imx_%.bbappend makes two changes at compile time:

  1. Splash logo: Replaces the DENX logo bitmap (tools/logos/denx.bmp and drivers/video/u_boot_logo.bmp) with a Quilter logo BMP
  2. Device tree model string: sed replaces the model = property in imx8mm-evk.dts and imx8mm-evk-u-boot.dtsi with "Project Speedrun"

No other U-Boot configuration (boot commands, environment variables, memory layout) is modified. However, U-Boot 2025.04 in Walnascar dropped legacy environment variables (mmcargs, mmcroot) that previously passed root= to the kernel. The kernel CONFIG_CMDLINE fragment compensates for this (see Boot Sequence below).


Kernel Modifications

Two kernel config fragments applied via DELTA_KERNEL_DEFCONFIG in linux-imx_%.bbappend:

rfkill.cfg

  • CONFIG_RFKILL=y — enables Bluetooth/WiFi RF kill switch management

plymouth.cfg

  • CONFIG_CMDLINE_EXTEND=y with CONFIG_CMDLINE_FROM_BOOTLOADER explicitly unset (Kconfig choice conflict resolution)
  • CONFIG_CMDLINE="root=/dev/mmcblk1p2 rootwait rw loglevel=0 quiet splash plymouth.ignore-serial-consoles plymouth.persist-splash vt.global_cursor_default=0" — provides root device (U-Boot 2025.04 no longer sets bootargs), enables Plymouth, suppresses serial console fallback
  • CONFIG_CONSOLE_LOGLEVEL_DEFAULT=1 / CONFIG_CONSOLE_LOGLEVEL_QUIET=1 — suppresses kernel messages for clean boot splash
  • CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y — prevents fbcon from clearing the screen before Plymouth attaches to DRM

Boot Sequence

  1. U-Boot: Quilter splash logo displayed, device tree reports "Project Speedrun"
  2. Kernel: Boots with built-in CONFIG_CMDLINE (root on mmcblk1p2), fbcon deferred, console quiet
  3. Plymouth: Spinner theme with Quilter watermark logo on DRM/KMS (card0/LCDIF). systemd drop-ins delay plymouth-quit until display-manager.service is ready
  4. GDM: Login screen. Default user speedrun, hostname speedrun
  5. GNOME 48: Mutter/Wayland desktop with GLES2 rendering

Additional Customizations

System Configuration

  • Hostname: speedrun
  • User account: speedrun (groups: video, audio, input, render)
  • Timezone: America/Los_Angeles
  • Locale: en_US.UTF-8
  • Packaging: Debian .deb format with apt on-device package management
  • First-boot resize: resize-rootfs service expands rootfs partition to fill SD card, then disables itself

Power Management

  • CPU governor: performance mode set at boot via cpu-performance-mode systemd service
  • Suspend disabled: systemd sleep/suspend/hibernate targets masked, GNOME power settings overridden via GSettings schema override (90_disable-suspend.gschema.override)

Audio

  • PulseAudio: Configured as default sound server (NXP's BSP removes it; re-enabled via DISTRO_FEATURES_BACKFILL_CONSIDERED:remove)
  • WM8524 codec: Default audio sink configured for the EVK headphone jack
  • Bluetooth A2DP: packagegroup-tools-bluetooth for wireless audio

Media

  • mpv: Video player with V4L2 M2M hardware decode, forced OpenGL API (Vivante Vulkan ICD is broken)
  • ffmpeg: Built with v4l2 and gpl PACKAGECONFIG, --enable-v4l2-m2m for Hantro VPU encode/decode
  • Firefox 147: Pre-built ARM64 binary installed to /opt/firefox with GNOME desktop integration

Games

  • GZDoom: With Freedoom WADs (Episode 1 and 2)
  • Quake GLES1: SDL-based port, patched for GCC 14 (-Wno-error=implicit-function-declaration)

Dev/Debug Tools

  • glmark2, kmscube, mesa-demos, es2-info (GLES2 capability query)
  • weston, weston-examples (alternate compositor for debugging)
  • htop, git, curl, lsof

BSP Bug Fixes in meta-quilter

These bbappends fix issues in the Walnascar NXP BSP when building with GNOME:

Recipe Fix
systemd_%.bbappend Removes 0001-binfmt-Don-t-install-dependency-links-at-install-tim.patch — incompatible with systemd 257.6
unicode-ucd_%.bbappend Updated license checksum (upstream unicode.org changed the file)
libcanberra_%.bbappend Removes GTK2 module (no X11 support on Vivante)
xserver-xorg_%.bbappend Removes obsolete GL_BGRA_EXT patch (merged upstream in xserver 21.1.18); adds libxshmfence dep for DRI3
gtk+3_%.bbappend Re-enables X11 backend (NXP incorrectly removes it, breaking GNOME XWayland components)
libdisplay-info_git.bbappend Bumps 0.1.1 → 0.2.0 (Mutter 48 requires >= 0.2)
webkitgtk_%.bbappend Limits parallel compile to -j 4 (OOM prevention on 16GB build hosts)
imx-image-multimedia.bbappend Removes broken NXP audio packages (packagegroup-fsl-tools-audio), disables Weston, enables GDM
packagegroup-fsl-gstreamer1.0.bbappend Removes gstreamer1.0-rtsp-server (freedesktop.org fetch failures)
gnome-tweaks_%.bbappend Skips buildpaths QA (Python .pyc embeds TMPDIR)
gzdoom_%.bbappend Skips buildpaths QA (generated C source debug info)

Required Source Patches (Outside meta-quilter)

Two NXP BSP source files must be patched directly because they use :remove which cannot be overridden from a layer:

# Re-enable pulseaudio (GNOME requires it)
sed -i 's/^DISTRO_FEATURES:remove = "pulseaudio"/# &/' \
    sources/meta-imx/meta-imx-sdk/conf/distro/include/fsl-imx-base.inc

# Re-enable X11 in GTK3 (GNOME needs gtk+-x11-3.0 for XWayland)
sed -i 's/^PACKAGECONFIG:remove:imxgpu = "x11"/# &/' \
    sources/meta-imx/meta-imx-bsp/recipes-gnome/gtk+3/gtk+3_%.bbappend

Layer Stack

poky/meta, poky/meta-poky
meta-openembedded (meta-oe, meta-gnome, meta-multimedia, meta-python, meta-networking, meta-filesystems, meta-perl)
meta-freescale, meta-freescale-3rdparty, meta-freescale-distro
meta-imx (meta-imx-bsp, meta-imx-sdk)
meta-arm, meta-arm-toolchain
meta-clang
meta-qt6
meta-browser/meta-chromium
meta-virtualization
meta-security (meta-parsec, meta-tpm)
meta-nxp-connectivity (meta-nxp-matter-baseline, meta-nxp-openthread)
meta-doom
meta-quilter  ← Project Speedrun customizations (priority 99)

Build Instructions

See yocto-imx/walnascar/sources/meta-quilter/BUILD_GUIDE.md for the full step-by-step build guide.

Quick reference:

# Source environment
cd yocto-imx/walnascar
MACHINE=imx8mmevk DISTRO=fsl-imx-xwayland source imx-setup-release.sh -b build-gnome

# Copy meta-quilter configs
cp sources/meta-quilter/conf/build-gnome/local.conf  build-gnome/conf/local.conf
cp sources/meta-quilter/conf/build-gnome/bblayers.conf build-gnome/conf/bblayers.conf

# Build
bitbake imx-image-multimedia

# Flash to SD card
zstdcat tmp/deploy/images/imx8mmevk/imx-image-multimedia-imx8mmevk.wic.zst | dd of=/dev/sdX bs=1M conv=fsync

Detailed Build Notes

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors