Skip to content

fix: handle variable stage2.bin file sizes across firmware versions #166

fix: handle variable stage2.bin file sizes across firmware versions

fix: handle variable stage2.bin file sizes across firmware versions #166

Workflow file for this run

name: Build PPPwn Live v2 ISO Images
on:
push:
branches:
- main
- dev
paths:
- '.github/workflows/ci.yaml'
- 'scripts/**'
- 'firmware/**'
- 'configs/**'
pull_request:
branches:
- main
paths:
- '.github/workflows/ci.yaml'
- 'scripts/**'
- 'firmware/**'
- 'configs/**'
permissions:
contents: write
discussions: write
jobs:
# Determine available firmware versions and build matrix
prepare_matrix:
name: Prepare Build Matrix
runs-on: ubuntu-latest
outputs:
firmware_matrix: ${{ steps.matrix.outputs.firmware_matrix }}
firmware_versions: ${{ steps.matrix.outputs.firmware_versions }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Determine firmware matrix
id: matrix
run: |
# Extract supported firmware versions from firmware-manager.sh
FIRMWARE_VERSIONS=$(awk '/^declare -A FIRMWARE_MAP=/,/^\)/' scripts/firmware-manager.sh | \
grep '^\s*\[' | sed 's/.*\["\([^"]*\)"\].*/\1/' | sort -n | tr '\n' ' ')
echo "Detected firmware versions: $FIRMWARE_VERSIONS"
# Create JSON array for matrix
FIRMWARE_ARRAY="["
FIRST=true
for version in $FIRMWARE_VERSIONS; do
if [ "$FIRST" = "true" ]; then
FIRST=false
else
FIRMWARE_ARRAY="$FIRMWARE_ARRAY,"
fi
FIRMWARE_ARRAY="$FIRMWARE_ARRAY\"$version\""
done
FIRMWARE_ARRAY="$FIRMWARE_ARRAY]"
echo "firmware_matrix=$FIRMWARE_ARRAY" >> $GITHUB_OUTPUT
echo "firmware_versions=$FIRMWARE_VERSIONS" >> $GITHUB_OUTPUT
# Build x86_64 ISOs first (primary architecture)
build_x86_64:
name: Build x86_64 ISOs
runs-on: ubuntu-latest
needs: prepare_matrix
strategy:
matrix:
firmware_version: ${{ fromJson(needs.prepare_matrix.outputs.firmware_matrix) }}
fail-fast: false
max-parallel: 4
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Cache kernel build artifacts
uses: actions/cache@v4
with:
path: |
build/linux-*
build/kernel-*
build/kernel-config-*
key: kernel-x86_64-${{ hashFiles('scripts/kernel-*.sh', 'configs/*', 'scripts/kernel-config-generator.sh') }}
restore-keys: |
kernel-x86_64-
- name: Cache busybox and build dependencies
uses: actions/cache@v4
with:
path: |
build/busybox-*
build/deps-*
build/toolchain-*
key: deps-x86_64-${{ hashFiles('scripts/initramfs-*.sh', 'scripts/build-minimal-kernel.sh') }}
restore-keys: |
deps-x86_64-
- name: Cache firmware assets
uses: actions/cache@v4
with:
path: |
firmware/
build/firmware-cache/
key: firmware-assets-${{ hashFiles('scripts/firmware-*.sh') }}-${{ github.run_id }}
restore-keys: |
firmware-assets-${{ hashFiles('scripts/firmware-*.sh') }}-
firmware-assets-
- name: Cache PPPwn binaries
uses: actions/cache@v4
with:
path: |
build/pppwn-*
build/binaries-*
key: pppwn-binaries-x86_64-${{ hashFiles('scripts/firmware-downloader.sh') }}
restore-keys: |
pppwn-binaries-x86_64-
pppwn-binaries-
- name: Cache ccache
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-x86_64-${{ github.sha }}
restore-keys: |
ccache-x86_64-
- name: Set up build environment
run: |
# Optimize package installation
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
build-essential \
bc \
kmod \
cpio \
flex \
bison \
libelf-dev \
libssl-dev \
xorriso \
isolinux \
syslinux-utils \
grub-pc-bin \
grub-efi-amd64-bin \
mtools \
dosfstools \
p7zip-full \
curl \
wget \
jq \
ccache
# Set up ccache for faster compilation
echo "/usr/lib/ccache" >> $GITHUB_PATH
ccache --set-config=max_size=2G
ccache --set-config=compression=true
# Optimize build environment
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
- name: Download and prepare firmware binaries
env:
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
run: |
echo "Preparing firmware binaries for version $FIRMWARE_VERSION"
chmod +x scripts/*.sh
# Create firmware directory structure manually (bypass potential init issues)
mkdir -p firmware/$FIRMWARE_VERSION firmware/.metadata
# Download firmware binaries for this version (includes validation)
./scripts/firmware-downloader.sh "$FIRMWARE_VERSION"
# Note: Validation is already performed during download with file size and checksum verification
- name: Build minimal kernel
env:
ARCH: x86_64
run: |
echo "Building minimal kernel for $ARCH with optimizations"
# Enable parallel compilation and ccache
export MAKEFLAGS="-j$(nproc)"
export CC="ccache gcc"
./scripts/kernel-builder.sh "$ARCH"
- name: Build firmware-specific initramfs
env:
ARCH: x86_64
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
run: |
echo "Building initramfs for $ARCH firmware $FIRMWARE_VERSION"
./scripts/initramfs-builder.sh --firmware "$FIRMWARE_VERSION" "$ARCH"
- name: Build firmware-specific ISO
env:
ARCH: x86_64
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
run: |
echo "Building ISO for $ARCH firmware $FIRMWARE_VERSION"
./scripts/iso-builder.sh --firmware "$FIRMWARE_VERSION" --arch "$ARCH"
- name: Validate build artifacts
env:
ARCH: x86_64
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
run: |
echo "Validating build artifacts for $ARCH firmware $FIRMWARE_VERSION"
./scripts/build-validator.sh validate-iso "$ARCH" "$FIRMWARE_VERSION"
- name: Report build metrics
if: always()
run: |
echo "=== Build Metrics Report ==="
echo "Architecture: x86_64"
echo "Firmware: ${{ matrix.firmware_version }}"
echo "ccache stats:"
ccache --show-stats || echo "ccache not available"
echo "Build artifacts:"
ls -lh build/output/ || echo "No output directory"
echo "Disk usage:"
du -sh build/ || echo "No build directory"
- name: Upload firmware ISO artifact
uses: actions/upload-artifact@v4
with:
name: pppwn-live-x86_64-fw${{ matrix.firmware_version }}-iso
path: build/output/pppwn-fw${{ matrix.firmware_version }}-x86_64.iso
retention-days: 30
# Build aarch64 ISOs only if x86_64 builds succeed (fallback architecture)
build_aarch64:
name: Build aarch64 ISOs
runs-on: ubuntu-latest
needs: [prepare_matrix, build_x86_64]
if: success()
strategy:
matrix:
firmware_version: ${{ fromJson(needs.prepare_matrix.outputs.firmware_matrix) }}
fail-fast: false
max-parallel: 2
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Cache kernel build artifacts
uses: actions/cache@v4
with:
path: |
build/linux-*
build/kernel-*
build/kernel-config-*
key: kernel-aarch64-${{ hashFiles('scripts/kernel-*.sh', 'configs/*', 'scripts/kernel-config-generator.sh') }}
restore-keys: |
kernel-aarch64-
- name: Cache busybox and build dependencies
uses: actions/cache@v4
with:
path: |
build/busybox-*
build/deps-*
build/toolchain-*
key: deps-aarch64-${{ hashFiles('scripts/initramfs-*.sh', 'scripts/build-minimal-kernel.sh') }}
restore-keys: |
deps-aarch64-
- name: Cache firmware assets
uses: actions/cache@v4
with:
path: |
firmware/
build/firmware-cache/
key: firmware-assets-${{ hashFiles('scripts/firmware-*.sh') }}-${{ github.run_id }}
restore-keys: |
firmware-assets-${{ hashFiles('scripts/firmware-*.sh') }}-
firmware-assets-
- name: Cache PPPwn binaries
uses: actions/cache@v4
with:
path: |
build/pppwn-*
build/binaries-*
key: pppwn-binaries-aarch64-${{ hashFiles('scripts/firmware-downloader.sh') }}
restore-keys: |
pppwn-binaries-aarch64-
pppwn-binaries-
- name: Cache cross-compilation toolchain
uses: actions/cache@v4
with:
path: |
/usr/aarch64-linux-gnu/
build/cross-*
key: cross-toolchain-aarch64-${{ runner.os }}
restore-keys: |
cross-toolchain-aarch64-
- name: Cache ccache
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-aarch64-${{ github.sha }}
restore-keys: |
ccache-aarch64-
- name: Set up cross-compilation environment
run: |
# Optimize package installation
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
build-essential \
bc \
kmod \
cpio \
flex \
bison \
libelf-dev \
libssl-dev \
xorriso \
isolinux \
syslinux-utils \
grub-pc-bin \
grub-efi-amd64-bin \
grub-efi-arm64-bin \
mtools \
dosfstools \
p7zip-full \
curl \
wget \
jq \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
ccache
# Set up ccache for faster cross-compilation
echo "/usr/lib/ccache" >> $GITHUB_PATH
ccache --set-config=max_size=2G
ccache --set-config=compression=true
# Optimize build environment for cross-compilation
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
echo "CROSS_COMPILE=aarch64-linux-gnu-" >> $GITHUB_ENV
- name: Download and prepare firmware binaries
env:
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
run: |
echo "Preparing firmware binaries for version $FIRMWARE_VERSION"
chmod +x scripts/*.sh
# Create firmware directory structure manually (bypass potential init issues)
mkdir -p firmware/$FIRMWARE_VERSION firmware/.metadata
# Download firmware binaries for this version (includes validation)
./scripts/firmware-downloader.sh "$FIRMWARE_VERSION"
# Note: Validation is already performed during download with file size and checksum verification
- name: Build minimal kernel
env:
ARCH: aarch64
CROSS_COMPILE: aarch64-linux-gnu-
run: |
echo "Building minimal kernel for $ARCH with cross-compilation optimizations"
# Enable parallel compilation and ccache for cross-compilation
export MAKEFLAGS="-j$(nproc)"
export CC="ccache aarch64-linux-gnu-gcc"
./scripts/kernel-builder.sh "$ARCH"
- name: Build firmware-specific initramfs
env:
ARCH: aarch64
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
CROSS_COMPILE: aarch64-linux-gnu-
run: |
echo "Building initramfs for $ARCH firmware $FIRMWARE_VERSION"
./scripts/initramfs-builder.sh --firmware "$FIRMWARE_VERSION" "$ARCH"
- name: Build firmware-specific ISO
env:
ARCH: aarch64
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
run: |
echo "Building ISO for $ARCH firmware $FIRMWARE_VERSION"
./scripts/iso-builder.sh --firmware "$FIRMWARE_VERSION" --arch "$ARCH"
- name: Validate build artifacts
env:
ARCH: aarch64
FIRMWARE_VERSION: ${{ matrix.firmware_version }}
run: |
echo "Validating build artifacts for $ARCH firmware $FIRMWARE_VERSION"
./scripts/build-validator.sh validate-iso "$ARCH" "$FIRMWARE_VERSION"
- name: Report build metrics
if: always()
run: |
echo "=== Build Metrics Report ==="
echo "Architecture: aarch64"
echo "Firmware: ${{ matrix.firmware_version }}"
echo "ccache stats:"
ccache --show-stats || echo "ccache not available"
echo "Build artifacts:"
ls -lh build/output/ || echo "No output directory"
echo "Disk usage:"
du -sh build/ || echo "No build directory"
- name: Upload firmware ISO artifact
uses: actions/upload-artifact@v4
with:
name: pppwn-live-aarch64-fw${{ matrix.firmware_version }}-iso
path: build/output/pppwn-fw${{ matrix.firmware_version }}-aarch64.iso
retention-days: 30
create_release:
if: github.ref == 'refs/heads/main'
needs: [prepare_matrix, build_x86_64, build_aarch64]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: iso_images
- name: Organize ISO files and calculate checksums
id: organize
run: |
echo "Organizing ISO files and calculating checksums..."
# Create organized directory structure
mkdir -p release_files/x86_64 release_files/aarch64
# Initialize checksum files
echo "# PPPwn Live v2 - SHA256 Checksums" > release_files/checksums.txt
echo "# Generated: $(date -u)" >> release_files/checksums.txt
echo "" >> release_files/checksums.txt
# Process x86_64 ISOs
echo "## x86_64 Architecture" >> release_files/checksums.txt
for artifact_dir in iso_images/pppwn-live-x86_64-fw*-iso; do
if [ -d "$artifact_dir" ]; then
for iso_file in "$artifact_dir"/*.iso; do
if [ -f "$iso_file" ]; then
filename=$(basename "$iso_file")
cp "$iso_file" "release_files/x86_64/$filename"
# Calculate checksum
checksum=$(sha256sum "release_files/x86_64/$filename" | cut -d' ' -f1)
echo "$checksum x86_64/$filename" >> release_files/checksums.txt
echo "Processed x86_64 ISO: $filename ($checksum)"
fi
done
fi
done
echo "" >> release_files/checksums.txt
# Process aarch64 ISOs (if available)
echo "## aarch64 Architecture" >> release_files/checksums.txt
aarch64_count=0
for artifact_dir in iso_images/pppwn-live-aarch64-fw*-iso; do
if [ -d "$artifact_dir" ]; then
for iso_file in "$artifact_dir"/*.iso; do
if [ -f "$iso_file" ]; then
filename=$(basename "$iso_file")
cp "$iso_file" "release_files/aarch64/$filename"
# Calculate checksum
checksum=$(sha256sum "release_files/aarch64/$filename" | cut -d' ' -f1)
echo "$checksum aarch64/$filename" >> release_files/checksums.txt
echo "Processed aarch64 ISO: $filename ($checksum)"
((aarch64_count++))
fi
done
fi
done
if [ $aarch64_count -eq 0 ]; then
echo "# No aarch64 ISOs available (build may have failed or been skipped)" >> release_files/checksums.txt
fi
# Count total ISOs
x86_64_count=$(find release_files/x86_64 -name "*.iso" | wc -l)
total_count=$((x86_64_count + aarch64_count))
echo "iso_count_x86_64=$x86_64_count" >> $GITHUB_OUTPUT
echo "iso_count_aarch64=$aarch64_count" >> $GITHUB_OUTPUT
echo "iso_count_total=$total_count" >> $GITHUB_OUTPUT
- name: Generate release notes
id: release_notes
run: |
cat > release_notes.md << 'EOF'
# PPPwn Live v2 - Multi-Firmware Release
This release includes firmware-specific ISO images for multiple PS4 firmware versions.
Each ISO is optimized for its target firmware and includes only the necessary binaries.
## Features
- ✅ Offline operation (no internet required during runtime)
- ✅ Ultra-minimal footprint (~7MB per ISO)
- ✅ Automatic PS4 exploitation and shutdown
- ✅ Support for multiple firmware versions
- ✅ Architecture prioritization (x86_64 primary, aarch64 fallback)
## Architecture Support
- **x86_64**: ${{ steps.organize.outputs.iso_count_x86_64 }} firmware ISOs
- **aarch64**: ${{ steps.organize.outputs.iso_count_aarch64 }} firmware ISOs
- **Total**: ${{ steps.organize.outputs.iso_count_total }} ISOs
## Supported Firmware Versions
This release supports the following PS4 firmware versions:
EOF
# Add firmware version list
for iso in release_files/x86_64/pppwn-fw*.iso; do
if [ -f "$iso" ]; then
fw_version=$(basename "$iso" | sed 's/pppwn-fw\([0-9]*\)-.*/\1/')
case $fw_version in
900) echo "- 9.00 (fw900)" >> release_notes.md ;;
960) echo "- 9.60 (fw960)" >> release_notes.md ;;
1000) echo "- 10.00 (fw1000)" >> release_notes.md ;;
1001) echo "- 10.01 (fw1001)" >> release_notes.md ;;
1050) echo "- 10.5 (fw1050)" >> release_notes.md ;;
1070) echo "- 10.7 (fw1070)" >> release_notes.md ;;
1071) echo "- 10.71 (fw1071)" >> release_notes.md ;;
1100) echo "- 11.00 (fw1100)" >> release_notes.md ;;
esac
fi
done
cat >> release_notes.md << 'EOF'
## Usage
1. Download the ISO for your PS4 firmware version and system architecture
2. Burn to USB drive or CD/DVD
3. Boot your computer from the USB/CD
4. Connect ethernet cable between computer and PS4
5. The system will automatically run the exploit and shutdown
## File Naming Convention
- `pppwn-fw{version}-{arch}.iso`
- Example: `pppwn-fw1100-x86_64.iso` (PS4 firmware 11.00, x86_64 architecture)
## Changelog
EOF
echo "${{ github.event.head_commit.message }}" >> release_notes.md
# Set output for release body
{
echo 'release_body<<EOF'
cat release_notes.md
echo 'EOF'
} >> $GITHUB_OUTPUT
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ github.run_number }}
name: PPPwn Live v2 - Release v${{ github.run_number }}
body: ${{ steps.release_notes.outputs.release_body }}
files: |
release_files/x86_64/*.iso
release_files/aarch64/*.iso
release_files/checksums.txt
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}