Skip to content

Latest commit

 

History

History
173 lines (118 loc) · 6.84 KB

File metadata and controls

173 lines (118 loc) · 6.84 KB

Building Linux for the PS Vita

The kernel builds locally on macOS (LLVM/Clang) or Linux (Bootlin GCC cross-compiler). The Makefile detects your platform and uses the right toolchain automatically.

Prerequisites

macOS

brew install llvm lld libelf make findutils gnu-sed
Package Why
llvm Clang compiler + LLVM tools (llvm-nm, llvm-objcopy, etc.)
lld LLVM linker (ld.lld)
libelf ELF type definitions for host tool compilation
make GNU Make >= 4.0 (gmake) — macOS ships 3.81
findutils GNU find/xargs — kernel build expects GNU behavior
gnu-sed GNU sed — some build scripts are incompatible with BSD sed

Linux

Install the Bootlin ARMv7 cross-compiler:

# Download and extract (anywhere you like)
BOOTLIN_VERSION=2025.08-1
mkdir -p ~/toolchains
curl -fsSL "https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--glibc--bleeding-edge-${BOOTLIN_VERSION}.tar.xz" | \
  tar -xJC ~/toolchains

# Add to PATH (add to your .bashrc/.zshrc for persistence)
export PATH="$HOME/toolchains/armv7-eabihf--glibc--bleeding-edge-${BOOTLIN_VERSION}/bin:$PATH"

You also need standard build dependencies:

sudo apt install bc flex bison libssl-dev libelf-dev

Build

From the outer repo (vita-linux-port/):

make config   # apply vita_defconfig → linux_vita/.config (first time or after config changes)
make build    # compile zImage + DTB

Or make deploy to build, upload to Vita, and boot in one step.

Output:

  • linux_vita/arch/arm/boot/zImage — kernel image
  • linux_vita/arch/arm/boot/dts/vita1000.dtb — device tree blob

What the Makefile does

On macOS, it runs:

gmake ARCH=arm LLVM=1 HOSTCFLAGS="-Iscripts/macos-include -I..." zImage -j<ncpu>

On Linux, it runs:

make ARCH=arm CROSS_COMPILE=arm-linux- zImage -j<ncpu>

The CROSS_COMPILE prefix defaults to arm-linux- (Bootlin). Override if using a different toolchain:

make build CROSS_COMPILE=arm-linux-gnueabihf-   # Debian package

Deploying to the Vita

After building, copy the artifacts to the Vita via FTP:

make push     # upload zImage + DTB to Vita via FTP
make boot     # launch Linux on Vita, stream serial output

Or manually:

curl -s -T linux_vita/arch/arm/boot/zImage "ftp://<VITA_IP>:1337/ux0:/linux/zImage"
curl -s -T linux_vita/arch/arm/boot/dts/vita1000.dtb "ftp://<VITA_IP>:1337/ux0:/linux/vita1000.dtb"

The Vita must be running VitaOS (not Linux) for FTP to be available.

Kernel config

  • vita_defconfig (linux_vita/arch/arm/configs/vita_defconfig) is a minimal defconfig (~100 lines, only non-default options)
  • make config applies it via the kernel's defconfig mechanism (toolchain-agnostic — works with both GCC and Clang)
  • After changing config (e.g. via menuconfig), run make savedefconfig to update vita_defconfig

Buildroot (initramfs)

The root filesystem is built locally using Buildroot, included as a git submodule. A br2-external tree (buildroot-vita/) holds the Vita-specific configuration, rootfs overlay, and post-build scripts.

First-time setup

# Initialize the buildroot submodule (if not already done)
git submodule update --init buildroot

# Set up local overlay with your credentials (not committed to git)
mkdir -p buildroot-vita/board/vita/local/etc
mkdir -p buildroot-vita/board/vita/local/etc/ssh
mkdir -p buildroot-vita/board/vita/local/root/.ssh

# WiFi config
cat > buildroot-vita/board/vita/local/etc/wpa_supplicant.conf <<EOF
ctrl_interface=/var/run/wpa_supplicant
update_config=1

network={
    ssid="YourNetworkName"
    psk="YourPassword"
}
EOF

# SSH public key for root login
cp ~/.ssh/id_ed25519.pub buildroot-vita/board/vita/local/root/.ssh/authorized_keys

# Optionally pre-generate SSH host keys (avoids slow generation on Vita)
ssh-keygen -t ed25519 -f buildroot-vita/board/vita/local/etc/ssh/ssh_host_ed25519_key -N ""
ssh-keygen -t ecdsa -f buildroot-vita/board/vita/local/etc/ssh/ssh_host_ecdsa_key -N ""
ssh-keygen -t rsa -b 4096 -f buildroot-vita/board/vita/local/etc/ssh/ssh_host_rsa_key -N ""

Building the rootfs

Note: Buildroot requires a Linux host. On macOS, use a Linux VM or container for make rootfs. The kernel build itself works natively on macOS.

make rootfs

This runs buildroot with the vita_defconfig, builds the rootfs, and copies rootfs.cpio.zst into linux_vita/. The post-build script automatically downloads the WiFi firmware. Your local overlay files (WiFi config, SSH keys) are applied by buildroot's overlay mechanism.

The kernel config embeds this as CONFIG_INITRAMFS_SOURCE="rootfs.cpio.zst". The file must be present in linux_vita/ at build time for the initramfs to be included in the zImage.

Modifying the rootfs

  • Add/change overlay files: edit buildroot-vita/board/vita/overlay/
  • Add packages: make rootfs-menuconfig, then make rootfs-savedefconfig
  • Rebuild: make rootfs (incremental — only rebuilds changed packages)

Rootfs overlay

Non-sensitive overlay files live in buildroot-vita/board/vita/overlay/ (committed). Sensitive files (WiFi credentials, SSH keys) go in buildroot-vita/board/vita/local/ (gitignored) — see local/README.md.

WiFi firmware

The Marvell SD8787 WiFi chip requires sd8787_uapsta.bin from linux-firmware. The post-build script (board/vita/post_build.sh) downloads it automatically from git.kernel.org on the first build. The firmware is loaded by the mwifiex driver when WiFi powers on at boot.

macOS compatibility patches

macOS lacks Linux-specific headers (<elf.h>, <byteswap.h>) and has a conflicting uuid_t typedef. The patches only affect host build tools in scripts/, not the kernel itself:

  • scripts/macos-include/elf.h — Wraps Homebrew's libelf/gelf.h (which provides the ELF struct types) and adds relocation constants (R_ARM_*, R_386_*, etc.), machine type constants (EM_AARCH64, EM_RISCV, etc.), and ARM ELF flag macros (EF_ARM_EABI_VERSION) that Homebrew's ancient libelf (0.8.13) is missing. These are all standard constants from glibc's <elf.h>.

  • scripts/macos-include/byteswap.h — Maps bswap_16/32/64 to __builtin_bswap* compiler intrinsics.

  • scripts/mod/file2alias.c — Works around macOS system headers defining uuid_t as unsigned char[16], which conflicts with the kernel's struct uuid_t. Uses #define uuid_t int / #undef uuid_t around the system header include.

Notes

  • The sorttable host tool emits ~16 pointer type warnings due to libelf using unsigned long where uint64_t is expected. These are harmless (same size on 64-bit macOS) and don't affect the build.
  • CONFIG_DEBUG_INFO_BTF must remain disabled — the BTF generation step uses GNU-only dd options.