summaryrefslogtreecommitdiffstats
path: root/tools/ghidra/analyze_fwimage.py
diff options
context:
space:
mode:
authorOpen-IOV <dev@open-iov.org>2026-09-23 05:44:08 -0400
committerOpen-IOV <dev@open-iov.org>2026-09-23 05:46:43 -0400
commit68cdd7728a7cc6715bbbff7decfe2b11c3bdf558 (patch)
tree3dc8ce2e6af313a97ec6852f5c663a9a93665d2e /tools/ghidra/analyze_fwimage.py
downloadopen-iov-68cdd7728a7cc6715bbbff7decfe2b11c3bdf558.tar.gz
open-iov-68cdd7728a7cc6715bbbff7decfe2b11c3bdf558.zip
Open-IOV: initial public release
Open-IOV virtualizes NVIDIA GPUs so that unmodified guest drivers run with real GPU functionality - CUDA first, 3D and video to follow - on unmodified hosts, without a proprietary vGPU license and without patching any driver, firmware or hypervisor. Core principle: emulate the interface, pass through the work. kernel/ open-iov-vfio.ko - host VFIO mdev driver: virtual GPU device (PCI config space, BAR shadows, MSI-X), GSP boot emulation, GSP-RM message-queue/RPC emulation, memory model (GPU-VA to guest-PA discovery) and the semaphore-completion service that advances guest UVM progress. userspace/ libiov.so management API and examples. tools/ guest diagnostics, firmware analysis wrappers, RM probes. scripts/ stack manager, VM harness, build/load/test automation. config/ hardware/version profiles (the portability surface). docs/ documentation tree - start at docs/README.md. wiki/ long-form firmware and protocol deep dives. Status: initialization works end to end for a stock 570.144 Linux guest on Turing (TU104): driver probe, nvidia-smi, the full GSP-RM control battery, object creation and the early CUDA/UVM start-up path. GPU work forwarding - the step that makes CUDA kernels execute on real hardware - is the active work item; see docs/04-implementation/01-known-knowns-and-unknowns.md. License: BSD-3-Clause for the project; GPL-2.0 for kernel modules that link GPL-only kernel interfaces. See LICENSE and docs/09-reference/legal-and-licensing.md.
Diffstat (limited to 'tools/ghidra/analyze_fwimage.py')
-rw-r--r--tools/ghidra/analyze_fwimage.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/tools/ghidra/analyze_fwimage.py b/tools/ghidra/analyze_fwimage.py
new file mode 100644
index 0000000..5d98504
--- /dev/null
+++ b/tools/ghidra/analyze_fwimage.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+"""
+Analyze GSP firmware .fwimage binary in Ghidra.
+Usage: python3 analyze_fwimage.py <fwimage_bin> <project_dir> <project_name>
+"""
+
+import sys
+import os
+import subprocess
+
+def analyze_fwimage(fwimage_path, project_dir, project_name):
+ """Analyze the .fwimage binary in Ghidra."""
+
+ ghidra_path = "/snap/bin/ghidra"
+ analyze_headless = "/snap/ghidra/47/ghidra/support/analyzeHeadless"
+
+ if not os.path.exists(analyze_headless):
+ analyze_headless = "/opt/ghidra/support/analyzeHeadless"
+
+ if not os.path.exists(analyze_headless):
+ print("ERROR: Ghidra analyzeHeadless not found")
+ return False
+
+ # Create project directory
+ os.makedirs(project_dir, exist_ok=True)
+
+ # Import the .fwimage binary
+ cmd = [
+ analyze_headless,
+ project_dir,
+ project_name,
+ "-import", fwimage_path,
+ "-processor", "RISCV:LE:64:default",
+ "-cspec", "gcc",
+ "-overwrite",
+ "-scriptPath", os.path.join(project_dir, "scripts"),
+ "-postScript", "analyze_gsp_fwimage.py"
+ ]
+
+ print(f"Running: {' '.join(cmd)}")
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=3600)
+
+ print(result.stdout)
+ if result.stderr:
+ print(result.stderr, file=sys.stderr)
+
+ return result.returncode == 0
+
+def main():
+ if len(sys.argv) < 4:
+ print("Usage: analyze_fwimage.py <fwimage_bin> <project_dir> <project_name>")
+ sys.exit(1)
+
+ fwimage_path = sys.argv[1]
+ project_dir = sys.argv[2]
+ project_name = sys.argv[3]
+
+ if not os.path.exists(fwimage_path):
+ print(f"ERROR: Firmware image not found: {fwimage_path}")
+ sys.exit(1)
+
+ success = analyze_fwimage(fwimage_path, project_dir, project_name)
+ sys.exit(0 if success else 1)
+
+if __name__ == "__main__":
+ main() \ No newline at end of file