# SPDX-License-Identifier: GPL-2.0-or-later # # Kernel SRPM for the AYANEO Pocket DS (Snapdragon 8 Gen 2 / SM8550 / qcs8550). # # Aggressively trimmed from upstream Fedora's multi-arch / multi-variant # kernel.spec: this build is aarch64-only, single-variant (stock), single # device (Pocket DS), and uses one config (rocknix-linux.aarch64.conf). # # Boot artefact: /boot/Image — Android boot.img v0 (ANDROID! magic + # header + gzip(arch/arm64/boot/Image) ++ qcs8550-ayaneo-pocketds.dtb + # cmdline) produced by mkbootimg. The ROCKNIX-signed ABL on the # Pocket DS expects this format on the \boot\Image probe slot — raw # arm64 Image at the same path triggers a hard reset shortly after # "Booting Linux", confirming the ABL only knows the boot.img layout # for this slot. # # DTBs: built from the in-tree arch/arm64/boot/dts/qcom/qcs8550-*.dts files # already present on the linux-pocketds:pocketds/v7.0 branch (the rocknix # patches are upstream of that branch — no patch application needed here). %global package_name kernel %global tarfile_release 7.0 # Don't generate kernel-debuginfo / kernel-debugsource subpackages. The kernel # is built with -g but we ship it as-is in /boot/Image; producing debuginfo # RPMs requires a -debuginfo subpackage definition with %files, which we # deliberately don't carry. Without these stubs rpmbuild's auto-debugsource # step fails with "Empty %files file debugsourcefiles.list". %global debug_package %{nil} %global _enable_debug_packages 0 %global _build_id_links none %global build_timestamp %(date -u +%Y%m%d%H%M%S) Name: %{package_name} Version: 7.0.0 # `.pocketds` suffix bumps NVR above Fedora's vanilla kernel-7.0.0-62.fc44 # so that mkosi (and dnf in general) installs our rocknix-patched + # boot.img-wrapped kernel rather than the upstream Fedora signed build. Release: 100.%{build_timestamp}.pocketds%{?dist} Summary: Linux kernel for the AYANEO Pocket DS (SM8550) License: GPL-2.0-only WITH Linux-syscall-note URL: https://gitlab.com/linux-pocketds/linux ExclusiveArch: aarch64 ExclusiveOS: Linux # Pre-patched kernel tree (rocknix patches + qcs8550-*.dts files already in tree) Source0: https://gitlab.com/linux-pocketds/linux/-/archive/pocketds/v%{tarfile_release}/linux-pocketds-v%{tarfile_release}.tar.gz#/linux-%{tarfile_release}.tar.gz Source1: rocknix-linux.aarch64.conf # JELOS-style busybox initramfs (boot=, disk=, kernel-overlays merge, fs-resize) # extracted into the kernel's usr/ tree at %prep time and baked in via # CONFIG_INITRAMFS_SOURCE — no separate boot.img ramdisk needed. Source2: initramfs.tar.zst BuildRequires: bash bc bison binutils diffutils elfutils-devel findutils flex BuildRequires: gawk gcc gcc-c++ gettext-devel git-core hostname kmod make BuildRequires: ncurses-devel net-tools openssl openssl-devel patch perl-interpreter BuildRequires: python3-devel rsync tar which xz zlib-devel BuildRequires: dtc BuildRequires: android-tools BuildRequires: zstd tar Requires: coreutils Requires: systemd >= 203 Requires: linux-firmware Provides: kernel-uname-r = %{version}-%{release}.%{_arch} Provides: kernel-modules = %{version}-%{release} Provides: kernel-modules-core = %{version}-%{release} Provides: kernel-modules-extra = %{version}-%{release} Provides: kernel-core = %{version}-%{release} Provides: installonlypkg(kernel) %define KernelVer %{version}-%{release}.%{_arch} %define image_install_path boot %define hdrarch arm64 %define asmarch arm64 %description The Linux kernel built for the AYANEO Pocket DS handheld. Single-variant, aarch64-only, configured from rocknix-linux.aarch64.conf. Installs an Android boot.img v0 at /boot/Image (kernel + DTB + cmdline in one ANDROID!-magic file); the ROCKNIX-signed ABL chain-loads it directly off the FAT ROCKNIX partition. %package devel Summary: Development files for building modules against the Pocket DS kernel Provides: kernel-devel = %{version}-%{release} Provides: kernel-devel-uname-r = %{KernelVer} Requires: kernel-uname-r = %{KernelVer} %description devel Headers, Makefiles, and scripts for building external modules against the Pocket DS kernel. # ---------------------------------------------------------------- prep ---- %prep %setup -q -n linux-pocketds-v%{tarfile_release} # Drop the .config in place cp %{SOURCE1} .config # Substitute ROCKNIX build-system placeholders that their image-builder # normally fills in via sed: # @INITRAMFS_SOURCE@ — path to a cpio source for an embedded initramfs. # We don't ship one (raw /boot/Image boot, no initrd # in the kernel image), so blank it out. # @DEVICENAME@ — the device hostname baked into the kernel. # Extract the JELOS busybox initramfs payload to the kernel build dir # so CONFIG_INITRAMFS_SOURCE can point at it. The tarball ships a # top-level `initramfs/` dir; we land at $PWD/initramfs/. tar --zstd -xf %{SOURCE2} [ -d initramfs ] || { echo "ERROR: initramfs/ missing after extract"; exit 1; } # Substitute ROCKNIX build-system placeholders. INITRAMFS_SOURCE points # at the absolute path of the tree we just extracted — Kbuild's # usr/Makefile uses gen_initramfs.sh to walk that directory and emit # usr/initramfs_data.cpio, which gets embedded as a section in the # final Image. INITRAMFS_DIR="$(pwd)/initramfs" sed -i \ -e "s|\"@INITRAMFS_SOURCE@\"|\"${INITRAMFS_DIR}\"|" \ -e 's|"@DEVICENAME@"|"pocketds"|' \ .config # Fix Makefile typo in upstream linux-pocketds tree: `dtb-y` entries must # reference the *compiled* .dtb name, not the .dts source. With `.dts` the # build invokes dtc but `dtbs_install` copies the source instead of the # compiled blob. sed -i 's|qcs8550-ayaneo-pocketds\.dts$|qcs8550-ayaneo-pocketds.dtb|' \ arch/arm64/boot/dts/qcom/Makefile # Make sure setlocalversion can't append a +/-dirty suffix. touch .scmversion rm -f localversion-next localversion-rt # --------------------------------------------------------------- build ---- %build make ARCH=%{asmarch} olddefconfig # Pin the build salt so module signatures and modules.builtin reference KernelVer perl -p -i -e "s/^CONFIG_BUILD_SALT.*/CONFIG_BUILD_SALT=\"%{KernelVer}\"/" .config make %{?_smp_mflags} ARCH=%{asmarch} \ KCFLAGS="$KCFLAGS" \ KERNELRELEASE=%{KernelVer} \ Image modules dtbs # ------------------------------------------------------------- install ---- %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/boot mkdir -p $RPM_BUILD_ROOT/lib/modules/%{KernelVer} # Raw kernel kept under /lib/modules//Image for diagnostics and # recovery flows that want an unwrapped Image matching the module tree. install -m 0644 arch/arm64/boot/Image $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/Image # /boot/Image — Android boot.img v0. ROCKNIX-signed ABL parses the # ANDROID! header, gunzips the kernel section to get arm64 Image, scans # the residual bytes (after the gzip stream) for FDT magic to find our # appended DTB, patches /chosen/bootargs with the cmdline carried in # the header (merged with its own androidboot.* tokens), and jumps. # # Earlycon is in the cmdline so any kernel panic before display init # at least reaches the SoC's debug UART (which the AYANEO chassis # might or might not expose — without a serial bring-out cable we # don't see it, but the kernel logs it). _abltmp=$(mktemp -d) # Match ROCKNIX's image-builder mkbootimg invocation byte-for-byte: # gzipped kernel + appended DTB, all offsets zero (mkbootimg's default # --base 0x10000000 — irrelevant on this ABL which uses platform-fixed # load addresses), header_version 0, cmdline using boot=LABEL/disk=LABEL. # A real (non-empty) ramdisk is mandatory: ABL writes # linux,initrd-start/initrd-end into /chosen for the kernel and a # 5-byte "dummy" trips up FDT path-walking on some ABL revisions. gzip -c arch/arm64/boot/Image > ${_abltmp}/kernel.gz cat arch/arm64/boot/dts/qcom/qcs8550-ayaneo-pocketds.dtb \ >> ${_abltmp}/kernel.gz # Empty-file ramdisk → mkbootimg writes ramdisk_size=0 in the boot.img # header and skips writing a ramdisk section. ROCKNIX's working KERNEL # is shaped this way: ABL never writes linux,initrd-start/end into # /chosen, so the kernel doesn't try to find an initramfs. Anything # non-empty here (including a 512-byte empty cpio archive) makes ABL # point /chosen/initrd-start at random memory, which the kernel then # mis-parses as initramfs and watchdog-resets. : > ${_abltmp}/ramdisk mkbootimg \ --kernel ${_abltmp}/kernel.gz \ --ramdisk ${_abltmp}/ramdisk \ --kernel_offset 0x00000000 \ --ramdisk_offset 0x00000000 \ --tags_offset 0x00000000 \ --os_version 12.0.0 \ --os_patch_level "$(date '+%%Y-%%m')" \ --header_version 0 \ --cmdline "rdinit=/init root=PARTLABEL=STORAGE rw boot=LABEL=ROCKNIX disk=LABEL=STORAGE quiet rootwait console=tty0 allow_mismatched_32bit_el0 fw_devlink.strict=1 pcie_ports=compat irqaffinity=0-2 cgroup.memory=nokmem,nosocket nosoftlockup usbcore.interrupt_interval_override=045e:028e:2" \ -o $RPM_BUILD_ROOT/boot/Image rm -rf ${_abltmp} # Config + System.map — diagnostic + module dep resolution install -m 0644 .config $RPM_BUILD_ROOT/boot/config-%{KernelVer} install -m 0644 .config $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/config install -m 0644 System.map $RPM_BUILD_ROOT/boot/System.map-%{KernelVer} install -m 0644 System.map $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/System.map # DTBs — install ALL DTBs the kernel built, then prune to keep only the # Pocket DS one. The rocknix .config has CONFIG_ARCH_QCOM=y which makes # Kbuild compile every Qualcomm DTB (~700 of them, ~30MB) — we only need # qcs8550-ayaneo-pocketds.dtb on the FAT ROCKNIX partition. Mirror the # trimmed tree under /lib/modules//dtb/ for any consumer that # walks the modules dir. mkdir -p $RPM_BUILD_ROOT/boot/dtb-%{KernelVer} make ARCH=%{asmarch} INSTALL_DTBS_PATH=$RPM_BUILD_ROOT/boot/dtb-%{KernelVer} dtbs_install find $RPM_BUILD_ROOT/boot/dtb-%{KernelVer} -type f \ ! -name 'qcs8550-ayaneo-pocketds.dtb' -delete find $RPM_BUILD_ROOT/boot/dtb-%{KernelVer} -type d -empty -delete mkdir -p $RPM_BUILD_ROOT/boot/dtb-%{KernelVer}/qcom cp -r $RPM_BUILD_ROOT/boot/dtb-%{KernelVer} $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/dtb # Kernel modules make %{?_smp_mflags} ARCH=%{asmarch} \ INSTALL_MOD_PATH=$RPM_BUILD_ROOT \ KERNELRELEASE=%{KernelVer} \ modules_install mod-fw= # Drop module symlinks pointing at the build root (rebuilt by kernel-devel) rm -f $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/build rm -f $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/source # kernel-devel: headers + Makefile / Kconfig / scripts to build out-of-tree mkdir -p $RPM_BUILD_ROOT/usr/src/kernels/%{KernelVer} DEVEL=$RPM_BUILD_ROOT/usr/src/kernels/%{KernelVer} cp --parents $(find -type f \( -name "Makefile*" -o -name "Kconfig*" \)) $DEVEL/ cp Module.symvers $DEVEL/ cp System.map $DEVEL/ cp .config $DEVEL/ cp -a include $DEVEL/ cp -a scripts $DEVEL/ mkdir -p $DEVEL/arch/arm64 cp -a arch/arm64/include $DEVEL/arch/arm64/ cp -a arch/arm64/Makefile $DEVEL/arch/arm64/ cp -a arch/arm64/Kconfig $DEVEL/arch/arm64/ 2>/dev/null || : # Symlink build/source -> kernel-devel tree ln -s /usr/src/kernels/%{KernelVer} $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/build ln -s /usr/src/kernels/%{KernelVer} $RPM_BUILD_ROOT/lib/modules/%{KernelVer}/source # Run depmod against the staged tree /sbin/depmod -aeF $RPM_BUILD_ROOT/boot/System.map-%{KernelVer} \ -b $RPM_BUILD_ROOT %{KernelVer} # No %post / %postun. The vanilla Fedora kernel.spec calls # `kernel-install add` to copy kernel + initrd into /boot// # and write a BLS entry under /boot/loader/entries/. We don't run an # initramfs and the ROCKNIX-signed ABL doesn't read BLS — those files # would just bloat the FAT and shadow our /boot/Image. # --------------------------------------------------------------- files ---- %files %defattr(-,root,root) /boot/Image /boot/config-%{KernelVer} /boot/System.map-%{KernelVer} /boot/dtb-%{KernelVer} /lib/modules/%{KernelVer} %files devel %defattr(-,root,root) /usr/src/kernels/%{KernelVer} %changelog * Wed May 06 2026 Pocket DS Maintainers - Release auto-stamped from build_timestamp + .pocketds suffix; full history in git log