Files
pi-pm3/BUILD_GUIDE.md
michael 4f35df1781 Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:46:22 -08:00

9.1 KiB

Dangerous Pi - Image Build Guide

Complete guide for building custom Raspberry Pi OS images with pi-gen.

Prerequisites

System Requirements

  • Linux or macOS (tested on Apple Silicon)
  • Docker (or alternatives like Podman)
  • 8GB+ RAM recommended
  • 20GB+ free disk space

Install Docker

# macOS
brew install docker

# Ubuntu/Debian
sudo apt-get install docker.io

# Or use Docker Desktop

Setup

1. Clone pi-gen

# Clone the official pi-gen repository
git clone https://github.com/RPi-Distro/pi-gen.git
cd pi-gen

# Checkout arm64 branch (for Pi Zero 2 W)
git checkout arm64

2. Copy Dangerous Pi Stage

# From your dangerous-pi repository
cp -r /path/to/dangerous-pi/pi-gen/stageDTPM3 /path/to/pi-gen/
cp /path/to/dangerous-pi/pi-gen/config /path/to/pi-gen/config

Build Methods

Builds a complete Raspberry Pi OS image with all your customizations.

cd /path/to/pi-gen

# Start full build
sudo ./build.sh

Build Time: 1-2 hours Output: Complete bootable image in deploy/ directory

Method 2: Quick Build (Development)

For rapid iteration when testing changes:

cd /path/to/pi-gen

# Only rebuild your custom stage
CONTINUE=1 STAGE=stageDTPM3 sudo ./build.sh

Build Time: 5-10 minutes Use Case: Testing Dangerous Pi code changes only

Clean, isolated build environment:

cd /path/to/pi-gen

# Build in Docker container
./docker-build.sh

Advantages:

  • No host system pollution
  • Consistent build environment
  • Works on macOS

Build Script Helper

Use the provided helper script for easier builds:

# From dangerous-pi directory
./build-image.sh full    # Full build
./build-image.sh quick   # Incremental build
./build-image.sh test    # Validate scripts

Note: Update the PI_GEN_DIR variable in build-image.sh to point to your pi-gen installation.

Configuration

Your build configuration is defined in pi-gen/config:

IMG_NAME="Proxmark3"           # Image name
RELEASE="trixie"               # Debian Trixie
TARGET_HOSTNAME="Proxmark3"    # Hostname
FIRST_USER_NAME="dt"           # Default user
FIRST_USER_PASS="proxmark3"    # Default password
ENABLE_SSH=1                   # SSH enabled
STAGE_LIST="stage0 stage1 stage2 stageDTPM3"

Customizing the Build

Edit config to customize:

Change hostname:

TARGET_HOSTNAME="dangerous-pi"

Change default credentials:

FIRST_USER_NAME="admin"
FIRST_USER_PASS="your-secure-password"

Change WiFi country:

WPA_COUNTRY="GB"  # UK

Skip stages (for faster builds):

# Only include your custom stage (requires base stages)
STAGE_LIST="stage0 stage1 stage2 stageDTPM3"

Stage Architecture

Your custom stageDTPM3 includes 4 sub-stages that run in order:

Stage 01: Proxmark3

  • Compiles Proxmark3 firmware and client
  • Installs to /usr/local/bin

Stage 02: RaspAP (Wireless AP)

  • Configures WiFi access point
  • Default SSID: raspi-webgui
  • Default password: ChangeMe

Stage 03: ttyd (Web Terminal)

  • Installs web-based terminal
  • Accessible at http://10.3.141.1:8000/

Stage 04: Dangerous Pi

  • Installs your custom application
  • Location: /opt/dangerous-pi
  • Auto-starts on boot via systemd

Build Output

After successful build:

pi-gen/
└── deploy/
    ├── image_2025-11-26-Proxmark3.img        # Bootable image
    ├── image_2025-11-26-Proxmark3.img.zip    # Compressed image
    └── build.log                              # Build logs

Flashing the Image

Using Balena Etcher (Easiest)

  1. Download Balena Etcher
  2. Select your .img or .zip file
  3. Select your SD card
  4. Click "Flash!"

Using dd (Linux/macOS)

# Find your SD card device
lsblk  # Linux
diskutil list  # macOS

# Flash image (replace /dev/sdX with your device)
sudo dd if=deploy/image_2025-11-26-Proxmark3.img of=/dev/sdX bs=4M status=progress

# Sync and eject
sync
sudo eject /dev/sdX

Warning: Double-check the device path! Using the wrong device will destroy data.

Testing the Image

1. Boot the Pi

  1. Insert SD card into Raspberry Pi Zero 2 W
  2. Connect Proxmark3 via USB
  3. Power on the Pi
  4. Wait ~1 minute for first boot

2. Connect to Access Point

SSID: raspi-webgui
Password: ChangeMe
Gateway: 10.3.141.1

3. Run Automated Tests

# From your development machine
./test-image.sh 10.3.141.1

This will verify:

  • SSH connectivity
  • Service status
  • Hardware access
  • API endpoints
  • Python dependencies

4. Manual Verification

SSH into device:

ssh dt@10.3.141.1
# Password: proxmark3

Check service status:

sudo systemctl status dangerous-pi.service
sudo journalctl -u dangerous-pi.service -f

Test API:

curl http://10.3.141.1:8000/api/health
curl http://10.3.141.1:8000/api/system/info

Access web interface:

Troubleshooting

Build Fails - Permission Denied

# Ensure scripts are executable
chmod +x pi-gen/stageDTPM3/*/00-*.sh

Build Fails - Docker Issues

# Ensure Docker is running
docker ps

# Clean up old containers
docker system prune -a

Build Fails - Disk Space

# Check available space (need 20GB+)
df -h

# Clean up old builds
sudo rm -rf pi-gen/work pi-gen/deploy

Service Not Starting After Boot

Check logs:

ssh dt@10.3.141.1
sudo journalctl -u dangerous-pi.service -n 50

Common issues:

  1. Port conflict with ttyd (see PORT_CONFLICT.md)
  2. Missing Python dependencies
  3. Incorrect file permissions
  4. Environment variables not set

Quick fix:

# Restart service
sudo systemctl restart dangerous-pi.service

# Check status
sudo systemctl status dangerous-pi.service

Image Too Large

Your current build should be ~600-700MB. If it's larger:

Check what's using space:

ssh dt@10.3.141.1
du -sh /* | sort -h | tail -10

Already implemented optimizations:

  • Package cache cleanup (apt-get clean)
  • Pip cache cleanup (pip3 cache purge)
  • Auto-remove unused packages

Can't Access Hardware (I2C, GPIO, Serial)

Verify groups:

ssh dt@10.3.141.1
groups pi  # Should show: i2c bluetooth gpio dialout

If missing:

sudo usermod -a -G i2c,bluetooth,gpio,dialout pi
# Log out and back in

Verify devices exist:

ls -la /dev/i2c*     # I2C bus
ls -la /dev/ttyACM*  # Proxmark3

Optimization Tips

Faster Builds

  1. Use incremental builds during development
  2. Cache compiled binaries from previous builds
  3. Use Docker for consistent environment
  4. Skip unnecessary stages in config

Smaller Images

Already implemented in your scripts:

  • Package manager cleanup
  • No development packages
  • No man pages
  • Pip cache removal

Build Caching

Pi-gen caches build artifacts in work/ directory:

# Keep work directory for incremental builds
# Clean when you want fresh build
sudo rm -rf work/

Version Management

Set version before building:

echo "1.0.0" > /path/to/dangerous-pi/VERSION

This version will be copied into the image at /opt/dangerous-pi/VERSION.

Advanced: Custom Stage Development

Script Execution Order

For each stage directory (NN-name/), pi-gen runs:

  1. 00-run.sh - Host-side preparation (optional)
  2. 00-run-chroot.sh - Chroot installation (required)
  3. 01-run-chroot.sh - Additional chroot tasks (optional)
  4. 02-run-chroot.sh - More chroot tasks (optional)

Adding New Stage

cd pi-gen/stageDTPM3

# Create new stage
mkdir 05-my-feature
cd 05-my-feature

# Create installation script
cat > 00-run-chroot.sh << 'EOF'
#!/bin/bash -e
echo "Installing my feature..."
apt-get install -y my-package
EOF

chmod +x 00-run-chroot.sh

Stage Best Practices

  1. Use #!/bin/bash -e - Exit on error
  2. Use $ROOTFS_DIR in 00-run.sh for paths
  3. Clean up package caches at end
  4. Set ownership for files (chown pi:pi)
  5. Document in README.md what stage does

Next Steps

  1. First build: Run full build to create base image
  2. Test hardware: Flash to SD card and test on Pi Zero 2 W
  3. Iterate: Make changes and use quick builds
  4. Document: Update configuration for your needs
  5. Deploy: Create final production image

Resources

Support

For issues with:

  • pi-gen: Check official pi-gen repository
  • Dangerous Pi: Review logs with journalctl -u dangerous-pi
  • Proxmark3: See Proxmark3 documentation
  • RaspAP: Visit RaspAP website

Happy building! 🚀