mpm: add bootgen_wrapper script

Provide the following two functions by wrapping the "bootgen"
command line tool:

verify: verify the validity of the signature of the .bin file.

extract_bitstream: extract the FPGA bitstream from the .bin file.
This works if the .bin file includes the FPGA bitstream as a
single partition.
This commit is contained in:
Jörg Hofrichter 2026-07-16 13:17:59 +02:00 committed by mkoop-ni
parent eb21a19deb
commit d4828aa208
2 changed files with 58 additions and 0 deletions

View File

@ -13,6 +13,7 @@ set(USRP_MPM_TOP_FILES
${CMAKE_CURRENT_SOURCE_DIR}/aurora_control.py
${CMAKE_CURRENT_SOURCE_DIR}/bfrfs.py
${CMAKE_CURRENT_SOURCE_DIR}/bist.py
${CMAKE_CURRENT_SOURCE_DIR}/bootgen_wrapper.py
${CMAKE_CURRENT_SOURCE_DIR}/components.py
${CMAKE_CURRENT_SOURCE_DIR}/compat_num.py
${CMAKE_CURRENT_SOURCE_DIR}/discovery.py

View File

@ -0,0 +1,57 @@
#!/usr/bin/env python3
#
# Copyright 2026 Ettus Research, a National Instruments Company
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
"""Utility functions provided by wrapping the "bootgen" tool.
verify: Verify the signature of a .bin file.
extract_bitstream: Extract the FPGA bitstream from a .bin file.
"""
import shutil
import subprocess
import tempfile
from pathlib import Path
def verify(input, arch):
"""Verify the signature of the .bin file."""
proc = subprocess.run(["bootgen", "-arch", arch, "-verify", input], capture_output=True)
if proc.returncode != 0:
stderr = proc.stderr.decode().splitlines()[0]
raise RuntimeError(
f'FPGA bitstream (.bin file) verification using bootgen failed: "{stderr}"'
)
def extract_bitstream(input, output, arch):
"""Extract the FPGA bitstream from the bootgen generated .bin file."""
temp_dir = tempfile.TemporaryDirectory()
proc = subprocess.run(
["bootgen", "-arch", arch, "-dump", input, "-dump_dir", temp_dir.name], capture_output=True
)
if proc.returncode != 0:
if proc.stderr.decode().startswith("[ERROR] : Boot Header not found"):
# The file is already a FPGA bitstream in .bin file format, just copy it
try:
shutil.copyfile(input, output)
except shutil.SameFileError:
# in-place conversion is allowed
pass
else:
stderr = proc.stderr.decode().splitlines()[0]
raise RuntimeError(
f'Could not extract bitstream from .bin file, bootgen returned "{stderr}"'
)
else:
extracted_bins = list(Path(temp_dir.name).glob("*.bin"))
num_bins = len(extracted_bins)
if num_bins == 0:
raise RuntimeError("Could not find extracted .bin file in bootgen dump output")
elif num_bins > 1:
raise RuntimeError(
f"Invalid .bin file: found {num_bins} partitions but expected only one."
)
shutil.move(str(extracted_bins[0]), output)