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:
- Setting up a donor device
- Generating your first firmware
- Understanding the output
- 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 x1pcileech_35t325_x4
— Artix-7 35T, 325 BGA, PCIe x4pcileech_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:
- Extract device configuration via VFIO
- Analyze PCIe capabilities
- Generate SystemVerilog and project files
- 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 fileconfig_space_init.hex
: Device configuration data for BRAM initializationvivado_project.tcl
: Ready-to-use Vivado project scriptdevice_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)
NVMe storage controller (example)
Custom donor templates
Device/vendor overrides are handled via donor info templates rather than ad-hoc CLI flags. Generate a template with:
Edit my_device.json
to set vendor/device IDs or other donor-specific fields, then pass it to build
using the --donor-template
option:
🐛 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:
- Device Cloning Guide: Learn advanced device extraction techniques
- Template Architecture: Understand how the generation works
- Development Guide: Contribute to the project
- Troubleshooting: Fix common issues
📚 Additional Resources
- Configuration Space Documentation: Deep dive into PCIe config space handling
- Supported Devices: Full list of tested devices
- TUI Guide: Complete TUI interface documentation
Questions? Check our Troubleshooting Guide or join the Discord Community!