mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
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.
58 lines
2.0 KiB
Python
Executable File
58 lines
2.0 KiB
Python
Executable File
#!/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)
|