Skip to content

Quick Start Guide

Get up and running with PCILeech Firmware Generator in just a few minutes! This guide assumes you have already completed the installation.

🎯 Overview

This tutorial will walk you through:

  1. Setting up a donor device
  2. Generating your first firmware
  3. Understanding the output
  4. Optional: Flashing to an FPGA

📋 Prerequisites

Before starting, ensure you have:

  • ✅ PCILeech Firmware Generator installed
  • ✅ At least one PCIe device bound to VFIO
  • ✅ Appropriate permissions (member of vfio group)
  • ✅ (Optional) Xilinx Vivado installed for synthesis

Step 1: Find a donor device (BDF)

The generator expects a PCI Bus:Device.Function (BDF) identifier for scripted runs. The easiest way to discover devices on your machine is to use lspci:

# List PCIe devices with numeric IDs (BDFs)
lspci -Dnn

# Example output (note the BDF at the start of each line):
# 0000:01:00.0  Ethernet controller [0200]: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10fb]
# 0000:02:00.0  VGA compatible controller [0300]: NVIDIA Corporation TU106 [GeForce RTX 2060] [10de:1f06]
# 0000:03:00.0  Non-Volatile memory controller [0108]: Samsung Electronics Co Ltd NVMe SSD Controller SM981/PM981/PM983 [144d:a808]

Pick the BDF (for example 0000:01:00.0) to use with the scripted build. If nothing appears, check your VFIO setup (see Installation).

Step 2: Choose your target board

Supported board names are defined in the project's board configuration. Common board identifiers you may see include:

  • pcileech_100t484_x1 — Artix-7 100T, 484 BGA, PCIe x1
  • pcileech_35t325_x4 — Artix-7 35T, 325 BGA, PCIe x4
  • pcileech_75t484_x1 — Artix-7 75T, 484 BGA, PCIe x1

If you installed the package entry points, you can also run the interactive picker (TUI) which will show supported boards; otherwise consult the repository's src/device_clone/board_config.py or run pcileech build --help for the exact choices available on your installation.

Step 3: Generate Your First Firmware

Now let's generate firmware using a donor device:

Basic generation (scripted)

Use the build subcommand with a BDF and a board name. Hardware access operations require root privileges (sudo):

# Scripted build (example)
sudo pcileech build --bdf 0000:01:00.0 --board pcileech_100t484_x1

# If you have the console entrypoint installed, the equivalent is:
# sudo pcileech build --bdf 0000:01:00.0 --board pcileech_100t484_x1

The generator will:

  1. Extract device configuration via VFIO
  2. Analyze PCIe capabilities
  3. Generate SystemVerilog and project files
  4. Create build / Vivado project scripts and save them to the configured output directory

With interactive TUI

For a guided experience use the TUI. The TUI performs device/board selection and generation in a friendly interface. It requires the textual/rich packages and runs on Linux:

# Launch the TUI (recommended on Linux)
sudo pcileech tui

# When running from a developer checkout: install the console entrypoint or run the
# project from the source tree using the `pcileech` entrypoint. Running a
# container is not required for normal VFIO workflows.

Follow the on-screen prompts to select donor device, choose a board, and generate firmware.

Method 3: Container (used by build; no manual action required)

The repository includes a Containerfile for CI and reproducible runtime images. The project's build orchestration may locally build and use a container image as part of internal build steps. This is an implementation detail of the build system — you do not need to manually build, run, or pull a container to perform VFIO-based generation on a host system.

Key points:

  • The build may automatically create and use a local container image during certain workflows. Treat the container as an internal implementation detail; you typically won't need to interact with it.
  • Do not rely on pulling an image from a public registry. If a reproducible image is required for CI or packaging, build it locally in your CI environment.
  • Crucially: kernel modules and any kernel-linked helpers (such as those used for donor dumping) must be built against the host kernel and cannot be reliably built or loaded from inside a container. See src/donor_dump/Makefile for host build instructions and follow those when working with donor_dump.

If you are developing CI or packaging that needs a reproducible image, you may build a local image with Podman; otherwise ignore the container details for normal VFIO workflows.

Advanced options (scripted)

The CLI build mode accepts a number of flags for advanced workflows. Examples:

# Enable advanced SystemVerilog features and manufacturing variance
sudo pcileech build --bdf 0000:01:00.0 --board pcileech_100t484_x1 --advanced-sv --enable-variance

# Generate a donor-info JSON template alongside build artifacts
sudo pcileech build --bdf 0000:01:00.0 --board pcileech_100t484_x1 --output-template donor_info.json

Note: flags such as --device-id / --vendor-id / --unique from older examples are no longer supported directly; donor-specific overrides are handled via donor info templates (donor-template) and the build configuration.

Step 4: Understanding the Output

After generation you'll find the build directory (default name depends on the build config). Typical artifacts include:

my_first_firmware/
├── pcileech_top.sv           # Top-level SystemVerilog module
├── <board>_bar_*.sv         # Board-specific controllers
├── config_space_init.hex     # Configuration space initialization
├── vivado_project.tcl        # Vivado project / synthesis script
├── build_instructions.md     # How to build the project
├── device_info.json          # Extracted device information (donor info)
└── logs/
  ├── generation.log        # Detailed generation log
  └── vfio_extraction.log   # VFIO extraction details

Key Files Explained

  • pcileech_top.sv: The main FPGA design file
  • config_space_init.hex: Device configuration data for BRAM initialization
  • vivado_project.tcl: Ready-to-use Vivado project script
  • device_info.json: Complete device analysis and extracted data

Step 5: Verify Generation Success

Check that generation completed successfully:

# Verify output files
ls -la my_first_firmware/

# Check generation log for any issues
grep -i error my_first_firmware/logs/generation.log || echo "No errors found"

# Validate SystemVerilog / run synthesis with Vivado (manual step)
cd my_first_firmware/
vivado -mode batch -source vivado_project.tcl

There is no dedicated --validate flag — use the generated Vivado project/script or review the generation logs and device_info.json to confirm correctness.

Step 6: Build FPGA Bitstream (Optional)

If you have Xilinx Vivado installed, you can synthesize the design using the generated project TCL:

# In the generated output directory
cd my_first_firmware/

# Run Vivado synthesis
vivado -mode batch -source vivado_project.tcl

# The bitstream will typically be created under:
# project.runs/impl_1/pcileech_top.bit

Step 7: Flash to FPGA (Optional)

If you have a compatible FPGA board and USB-JTAG programmer you can flash the generated firmware with the flash subcommand. Pass the firmware file and the board identifier:

# Flash a firmware file (example)
sudo pcileech flash my_first_firmware/pcileech_top.bin --board pcileech_100t484_x1

# Or, with console entry installed:
# sudo pcileech flash my_first_firmware/pcileech_top.bin --board pcileech_100t484_x1

If the repository's flash helper is not available, the generated build may include instructions for the appropriate usbloader/platform cable tool for your board.

🎛️ Interactive TUI Mode

For beginners, the TUI provides a user-friendly interface (see Step 3). It will guide you through device selection, board choice, generation options and progress monitoring.

🔧 Common Use Cases

Network card cloning (example)

sudo pcileech build --bdf 0000:01:00.0 --board pcileech_100t484_x1 --advanced-sv

NVMe storage controller (example)

sudo pcileech build --bdf 0000:03:00.0 --board pcileech_35t325_x4

Custom donor templates

Device/vendor overrides are handled via donor info templates rather than ad-hoc CLI flags. Generate a template with:

sudo pcileech donor-template -o my_device.json --bdf 0000:01:00.0

Edit my_device.json to set vendor/device IDs or other donor-specific fields, then pass it to build using the --donor-template option:

sudo pcileech build --bdf 0000:01:00.0 --board pcileech_100t484_x1 --donor-template my_device.json

🐛 Troubleshooting Quick Fixes

"No VFIO devices found"

# Check VFIO module is loaded
lsmod | grep vfio

# Verify device is bound to VFIO
ls /sys/bus/pci/drivers/vfio-pci/

"Permission denied accessing device"

# Check group membership
groups | grep vfio

# Add user to vfio group if needed (Linux)
sudo usermod -a -G vfio $USER
# Log out and back in

"Vivado not found"

# Source Vivado environment
source /opt/Xilinx/Vivado/*/settings64.sh

# Or add to your shell profile
echo 'source /opt/Xilinx/Vivado/2023.1/settings64.sh' >> ~/.bashrc

✨ Tips for Success

1. Choose the Right Donor Device

  • Simple devices (network cards) are easier than complex ones (GPUs)
  • Ensure the device has standard PCIe capabilities
  • Check that VFIO can access all configuration space

2. Match PCIe Lane Count

  • Use x1 boards for x1 devices
  • Use x4 boards for high-bandwidth devices
  • Consider the target use case for lane count selection

3. Verify Before Building

  • Always check the generation log for warnings
  • Validate device information in device_info.json
  • Test with simulation before hardware synthesis

4. Keep Unique Identifiers

  • Use --unique flag to generate unique device/vendor IDs
  • This prevents conflicts with real hardware
  • Important for security research applications

🎓 Next Steps

Now that you've generated your first firmware:

  1. Device Cloning Guide: Learn advanced device extraction techniques
  2. Template Architecture: Understand how the generation works
  3. Development Guide: Contribute to the project
  4. Troubleshooting: Fix common issues

📚 Additional Resources


Questions? Check our Troubleshooting Guide or join the Discord Community!