Skip to main content

Overview

The PKG creation tools allow you to package your PS3 homebrew applications into installable PKG files. These packages include your application executable, metadata, icons, and additional resources.
PKG files created with these tools are for homebrew use on custom firmware only.

Package Components

PARAM.SFO

System File Object containing application metadata, title, ID, and version information.

EBOOT.BIN

The main application executable in NPDRM SELF format.

ICON0.PNG

Application icon displayed in the XMB (320x176 pixels recommended).

Resources

Additional files like sounds, textures, and data files in USRDIR/.

Required Tools

The PKG creation process uses two Python scripts from tools/ps3py/:
  • pkg.py: Creates PKG archives from directory structures
  • sfo.py: Generates PARAM.SFO metadata files

PARAM.SFO Creation

Using sfo.py

PARAM.SFO files contain essential metadata for your application.
sfo.py -f [options] input.xml output.sfo

SFO XML Format

Create an XML template with your application metadata:
sfo.xml
<?xml version="1.0"?>
<sfo>
  <value name="APP_VER" type="string">01.00</value>
  <value name="ATTRIBUTE" type="integer">0</value>
  <value name="BOOTABLE" type="integer">1</value>
  <value name="CATEGORY" type="string">HG</value>
  <value name="LICENSE" type="string">Creative Commons</value>
  <value name="PS3_SYSTEM_VER" type="string">03.4100</value>
  <value name="RESOLUTION" type="integer">63</value>
  <value name="SOUND_FORMAT" type="integer">1</value>
  <value name="TITLE" type="string">My PSL1GHT App</value>
  <value name="TITLE_ID" type="string">MYAP00001</value>
  <value name="VERSION" type="string">01.00</value>
</sfo>
PSL1GHT includes a default sfo.xml at $PS3DEV/bin/sfo.xml that you can customize.

Generate PARAM.SFO

# From XML template
sfo.py -f sfo.xml PARAM.SFO

# Override title and app ID
sfo.py -f sfo.xml --title "My Game" --appid "GAME00001" PARAM.SFO

SFO Options

-f, --fromxml
string
Convert from XML to SFO format
-t, --toxml
string
Convert existing SFO to XML format
--title
string
Override the TITLE field from XML
--appid
string
Override the TITLE_ID field from XML
-l, --list
string
List contents of an existing SFO file

PKG Creation Workflow

1

Prepare Directory Structure

Create a package directory with the required structure:
mkdir -p pkg/USRDIR
2

Create NPDRM EBOOT.BIN

Convert your ELF to NPDRM SELF format:
fself -n myapp.elf pkg/USRDIR/EBOOT.BIN
3

Generate PARAM.SFO

Create the metadata file:
sfo.py -f sfo.xml --title "My App" --appid "MYAP00001" pkg/PARAM.SFO
4

Add Icon and Resources

Copy your icon and additional files:
cp ICON0.PNG pkg/
cp -r data/* pkg/USRDIR/
5

Create PKG

Build the package with a Content ID:
pkg.py --contentid UP0001-MYAP00001_00-0000000000000000 pkg/ myapp.pkg

Using pkg.py

Basic Usage

pkg.py [options] source-directory [output-file]

Creating a Package

# Create PKG from directory
pkg.py --contentid UP0001-GAME00001_00-0000000000000000 pkg/ mygame.pkg

# If output file is omitted, uses Content ID as filename
pkg.py --contentid UP0001-GAME00001_00-0000000000000000 pkg/
# Creates: UP0001-GAME00001_00-0000000000000000.pkg

PKG Options

-c, --contentid
string
required
Content ID in format: UP0001-TITLEID_00-0000000000000000
-l, --list
string
List contents of an existing PKG file
-x, --extract
string
Extract contents from an existing PKG

Content ID Format

The Content ID must follow Sony’s format:
UP0001-TITLEID_00-0000000000000000
│     │        │  │
│     │        │  └─ Unique identifier (16 chars)
│     │        └──── Version separator
│     └───────────── Title ID (9 chars)
└─────────────────── Publisher ID
For homebrew, use UP0001 as the publisher ID and create a unique Title ID.

Package Directory Structure

Your package directory should follow this structure:
pkg/
├── PARAM.SFO          # Application metadata (required)
├── ICON0.PNG          # Application icon (required)
├── PIC1.PNG           # Background image (optional)
└── USRDIR/            # Application directory (required)
    ├── EBOOT.BIN      # Main executable (required)
    ├── data/          # Your data files
    ├── shaders/       # Shader files
    └── textures/      # Texture files
The EBOOT.BIN must be in NPDRM SELF format. Use fself -n to create it.

Automated Build Integration

The PSL1GHT build system automates PKG creation in ppu_rules:
%.pkg: %.self
    $(VERB) echo building pkg ... $(notdir $@)
    $(VERB) mkdir -p $(BUILDDIR)/pkg/USRDIR
    $(VERB) cp $(ICON0) $(BUILDDIR)/pkg/ICON0.PNG
    $(VERB) $(SELF_NPDRM) $(BUILDDIR)/$(basename $(notdir $<)).elf \
            $(BUILDDIR)/pkg/USRDIR/EBOOT.BIN $(CONTENTID)
    $(VERB) $(SFO) --title "$(TITLE)" --appid "$(APPID)" \
            -f $(SFOXML) $(BUILDDIR)/pkg/PARAM.SFO
    $(VERB) if [ -n "$(PKGFILES)" -a -d "$(PKGFILES)" ]; then \
            cp -rf $(PKGFILES)/* $(BUILDDIR)/pkg/; fi
    $(VERB) $(PKG) --contentid $(CONTENTID) $(BUILDDIR)/pkg/ $@

Makefile Configuration

Configure your Makefile with package metadata:
# Package settings
TITLE      := My PSL1GHT Application
APPID      := MYAP00001
CONTENTID  := UP0001-$(APPID)_00-0000000000000000
ICON0      := $(CURDIR)/resources/ICON0.PNG
SFOXML     := $(CURDIR)/resources/sfo.xml
PKGFILES   := $(CURDIR)/pkgfiles

Build PKG

# Build everything and create PKG
make pkg

# Or explicitly
make myapp.pkg

Complete Example

#!/bin/bash

# Set up variables
APP_NAME="mygame"
APP_TITLE="My Awesome Game"
APP_ID="GAME00001"
CONTENT_ID="UP0001-${APP_ID}_00-0000000000000000"

# Create directory structure
mkdir -p pkg/USRDIR

# Create NPDRM SELF
fself -n build/${APP_NAME}.elf pkg/USRDIR/EBOOT.BIN

# Generate PARAM.SFO
sfo.py -f sfo.xml --title "${APP_TITLE}" --appid "${APP_ID}" pkg/PARAM.SFO

# Copy resources
cp resources/ICON0.PNG pkg/
cp -r data/* pkg/USRDIR/

# Create PKG
pkg.py --contentid ${CONTENT_ID} pkg/ ${APP_NAME}.pkg

echo "Package created: ${APP_NAME}.pkg"

Package Testing

List Package Contents

# View files in PKG
pkg.py -l myapp.pkg
Output:
Listing: "myapp.pkg"
+) overwrite, -) no overwrite

  directory:+          0: 
   raw data:+        320: PARAM.SFO
   raw data:+      51200: ICON0.PNG
  directory:+          0: USRDIR
 NPDRM SELF:+     524288: USRDIR/EBOOT.BIN
   raw data:+      16384: USRDIR/data/textures.dat

Extract Package

# Extract PKG to directory
pkg.py -x myapp.pkg

# Creates directory: UP0001-MYAP00001_00-0000000000000000/

Source Code Reference

Packaging tools are implemented in:
  • PKG Tool: tools/ps3py/pkg.py:1-608
  • SFO Tool: tools/ps3py/sfo.py:1-323
  • PKG Encryption: tools/ps3py/crypt.c
  • FSELF Integration: tools/ps3py/fself.py

Key Functions

# From tools/ps3py/pkg.py:378
def pack(folder, contentid, outname=None):
    # Creates encrypted PKG from folder structure
    # Handles NPDRM SELF metadata
    # Generates QA digest for verification

Troubleshooting

Ensure your Content ID follows the correct format:
UP0001-TITLEID_00-0000000000000000
  • Publisher: UP0001 (4-6 chars)
  • Title ID: 9 characters
  • Version: 00
  • Unique ID: 16 characters
Common causes:
  • EBOOT.BIN is not in NPDRM format (use fself -n)
  • PARAM.SFO is missing or invalid
  • Custom firmware doesn’t support homebrew PKG installation
Check that:
  • ICON0.PNG exists and is valid
  • PARAM.SFO has correct CATEGORY (use “HG” for homebrew games)
  • TITLE field in PARAM.SFO is not empty
The ps3py tools require Python 2 and compiled extensions:
cd tools/ps3py
python setup.py build

See Also

FSELF Tool

Create SELF executables for packaging

PS3 Loading

Test without creating PKG files

Build System

Automate PKG creation

Sample Projects

See complete packaging examples

Build docs developers (and LLMs) love