summaryrefslogtreecommitdiffstats
path: root/tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java
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
commit2302fc09080bad51c73f293294e19fd4db464eb0 (patch)
treec722d186347fdef5a34131e9e143b1549b1daf8e /tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java
downloadopen-iov-2302fc09080bad51c73f293294e19fd4db464eb0.tar.gz
open-iov-2302fc09080bad51c73f293294e19fd4db464eb0.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/gsp-fwimage-570.144/scripts/BasicAnalysis.java')
-rw-r--r--tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java156
1 files changed, 156 insertions, 0 deletions
diff --git a/tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java b/tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java
new file mode 100644
index 0000000..1776ea2
--- /dev/null
+++ b/tools/ghidra/gsp-fwimage-570.144/scripts/BasicAnalysis.java
@@ -0,0 +1,156 @@
+// Ghidra script to do basic disassembly analysis of GSP .fwimage binary
+// Usage: analyzeHeadless ... -postScript BasicAnalysis.java
+
+import ghidra.app.script.GhidraScript;
+import ghidra.program.model.listing.*;
+import ghidra.program.model.mem.*;
+import ghidra.program.model.symbol.*;
+import ghidra.program.model.address.*;
+import ghidra.util.task.TaskMonitor;
+import java.io.*;
+import java.util.*;
+import java.nio.file.*;
+
+public class BasicAnalysis extends GhidraScript {
+
+ @Override
+ protected void run() throws Exception {
+ Program program = getCurrentProgram();
+ Listing listing = program.getListing();
+ Memory memory = program.getMemory();
+ FunctionManager functionManager = program.getFunctionManager();
+
+ println("=== GSP Firmware .fwimage Basic Analysis ===");
+ println("Program: " + program.getName());
+ println("Architecture: " + program.getLanguage().toString());
+
+ // Create output directory
+ String outputDir = "/home/rmcore/Git/integdev_gpu_drv/open-iov/firmware/570-GSP";
+ Files.createDirectories(Paths.get(outputDir));
+
+ // 1. Check memory blocks
+ println("\n--- Memory Blocks ---");
+ List<Map<String, Object>> memBlocks = new ArrayList<>();
+ for (MemoryBlock block : memory.getBlocks()) {
+ Map<String, Object> blockInfo = new HashMap<>();
+ blockInfo.put("name", block.getName());
+ blockInfo.put("start", block.getStart().toString());
+ blockInfo.put("end", block.getEnd().toString());
+ blockInfo.put("size", block.getSize());
+ blockInfo.put("execute", block.isExecute());
+ blockInfo.put("read", block.isRead());
+ blockInfo.put("write", block.isWrite());
+ memBlocks.add(blockInfo);
+ println(" " + block.getName() + ": " + block.getStart() + " - " + block.getEnd() +
+ " (" + block.getSize() + " bytes) r=" + block.isRead() + " w=" + block.isWrite() + " x=" + block.isExecute());
+ }
+ writeJson(outputDir + "/memory_blocks.json", memBlocks);
+
+ // 2. Find all functions
+ println("\n--- Finding Functions ---");
+ List<Map<String, Object>> functions = new ArrayList<>();
+ FunctionIterator funcIter = functionManager.getFunctions(true);
+ int count = 0;
+ while (funcIter.hasNext()) {
+ Function func = funcIter.next();
+ Map<String, Object> funcInfo = new HashMap<>();
+ funcInfo.put("name", func.getName());
+ funcInfo.put("entry", func.getEntryPoint().toString());
+ funcInfo.put("size", func.getBody().getNumAddresses());
+ functions.add(funcInfo);
+ count++;
+ if (count % 1000 == 0) {
+ println(" Found " + count + " functions...");
+ }
+ }
+ println("Total functions: " + functions.size());
+ writeJson(outputDir + "/functions.json", functions);
+
+ // 3. Find strings
+ println("\n--- Finding Strings ---");
+ List<Map<String, String>> strings = new ArrayList<>();
+ DataIterator dataIter = listing.getDefinedData(true);
+ while (dataIter.hasNext()) {
+ Data data = dataIter.next();
+ if (data.getDataType().getName().equals("string")) {
+ Object value = data.getValue();
+ if (value != null && value.toString().length() > 4) {
+ Map<String, String> strInfo = new HashMap<>();
+ strInfo.put("address", data.getAddress().toString());
+ strInfo.put("value", value.toString());
+ strings.add(strInfo);
+ }
+ }
+ }
+ println("Found " + strings.size() + " strings");
+
+ // Filter for interesting strings
+ String[] interestingKeywords = {"vgpu", "vmiop", "rpc", "hal", "bar", "migrate", "init", "boot", "kgsp", "wpr", "firmware", "version", "error", "fail", "assert", "panic", "nvidia", "rmapi", "gsp", "falcon", "mailbox", "interrupt", "dma", "iommu", "page", "mmu", "pde", "pte"};
+ List<Map<String, String>> interestingStrings = new ArrayList<>();
+ for (Map<String, String> s : strings) {
+ String val = s.get("value").toLowerCase();
+ for (String kw : interestingKeywords) {
+ if (val.contains(kw)) {
+ interestingStrings.add(s);
+ break;
+ }
+ }
+ }
+ println("Interesting strings: " + interestingStrings.size());
+ writeJson(outputDir + "/interesting_strings.json", interestingStrings);
+
+ // 4. Find entry point
+ println("\n--- Entry Point Analysis ---");
+ Address entryAddr = program.getMinAddress();
+ println("Program entry (min address): " + entryAddr);
+ Function funcAtZero = functionManager.getFunctionAt(entryAddr);
+ if (funcAtZero != null) {
+ println("Function at entry: " + funcAtZero.getName());
+ } else {
+ println("No function at entry point - creating one...");
+ Function func = functionManager.createFunction("entry_point", entryAddr, null, null, monitor);
+ if (func != null) {
+ println("Created function: " + func.getName());
+ }
+ }
+
+ println("\n--- Analysis Complete ---");
+ println("Results saved to " + outputDir);
+ }
+
+ private void writeJson(String path, Object data) throws IOException {
+ StringBuilder json = new StringBuilder();
+ json.append("[\n");
+ if (data instanceof List) {
+ List<?> list = (List<?>) data;
+ for (int i = 0; i < list.size(); i++) {
+ Object item = list.get(i);
+ if (item instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>) item;
+ json.append(" {");
+ int j = 0;
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
+ json.append("\"").append(entry.getKey()).append("\": ");
+ Object val = entry.getValue();
+ if (val instanceof String) {
+ json.append("\"").append(escapeJson(val.toString())).append("\"");
+ } else {
+ json.append(val);
+ }
+ if (j < map.size() - 1) json.append(", ");
+ j++;
+ }
+ json.append("}");
+ }
+ if (i < list.size() - 1) json.append(",");
+ json.append("\n");
+ }
+ }
+ json.append("]");
+ Files.writeString(Paths.get(path), json.toString());
+ }
+
+ private String escapeJson(String s) {
+ return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t");
+ }
+} \ No newline at end of file