816848a474
- Ghidra decompilation of v1.02-v1.19 blobs (118 functions) - 53 functions renamed, 79 MMIO registers mapped to TRM - 45 timeout-less poll loops identified and patched - Production patcher (patch_prod.py) and QEMU emulator - Comprehensive analysis, frequency tables, community research Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
109 lines
3.2 KiB
Makefile
109 lines
3.2 KiB
Makefile
# RK3588 DDR Init Blob — Reverse Engineering Toolkit
|
|
#
|
|
# Prerequisites:
|
|
# apt install gcc-aarch64-linux-gnu libunicorn-dev openjdk-21-jdk-headless python3
|
|
# pip install unicorn
|
|
#
|
|
# On Arch (boltzmann):
|
|
# pacman -S aarch64-linux-gnu-gcc python-unicorn java-runtime
|
|
#
|
|
# Ghidra (for decompilation, x86 only):
|
|
# Download from https://github.com/NationalSecurityAgency/ghidra/releases
|
|
# Requires JDK 21+
|
|
|
|
CROSS := aarch64-linux-gnu-
|
|
CC := gcc
|
|
CFLAGS := -O2 -Wall
|
|
LDFLAGS := -lunicorn -lm
|
|
|
|
BLOB_DIR := /opt/rkbin/bin/rk35
|
|
BLOB_FAST := $(BLOB_DIR)/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.19.bin
|
|
BLOB_CONS := $(BLOB_DIR)/rk3588_ddr_lp4_1848MHz_lp5_2112MHz_v1.19.bin
|
|
GHIDRA := /opt/ghidra
|
|
JAVA_HOME ?= /opt/jdk21
|
|
|
|
.PHONY: all patch patch-prod patch-all emulator decompile diff clean help
|
|
|
|
help:
|
|
@echo "RK3588 DDR Blob Toolkit"
|
|
@echo ""
|
|
@echo "Targets:"
|
|
@echo " patch-prod - Apply production patch (40 NOP, 5 kept)"
|
|
@echo " patch-all - Apply aggressive patch (all 45 NOPped)"
|
|
@echo " emulator - Build unicorn-based emulator (x86 only)"
|
|
@echo " test-orig - Emulate original blob"
|
|
@echo " test-patched - Emulate patched blob"
|
|
@echo " decompile - Decompile blob with Ghidra (x86 only)"
|
|
@echo " annotate - Generate annotated C source"
|
|
@echo " diff - Diff fast vs conservative blobs"
|
|
@echo " clean - Remove generated files"
|
|
@echo ""
|
|
@echo "Prerequisites:"
|
|
@echo " Python 3.8+, unicorn (pip), Ghidra 11.3+ (for decompile)"
|
|
@echo " gcc + libunicorn-dev (for emulator)"
|
|
|
|
all: patch-prod
|
|
|
|
# === Patching ===
|
|
|
|
rk3588_ddr_v1.19_prod.bin: patch_prod.py $(BLOB_FAST)
|
|
python3 patch_prod.py $(BLOB_FAST) $@
|
|
|
|
rk3588_ddr_v1.19_patched_v2.bin: patch_timeouts.py $(BLOB_FAST)
|
|
python3 patch_timeouts.py $(BLOB_FAST) $@
|
|
|
|
patch-prod: rk3588_ddr_v1.19_prod.bin
|
|
|
|
patch-all: rk3588_ddr_v1.19_patched_v2.bin
|
|
|
|
# === Emulation (x86 only) ===
|
|
|
|
ddr_emu: ddr_emu2.c
|
|
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
|
|
|
|
emulator: ddr_emu
|
|
|
|
test-orig: ddr_emu
|
|
./ddr_emu $(BLOB_FAST) 50000
|
|
|
|
test-patched: ddr_emu rk3588_ddr_v1.19_prod.bin
|
|
./ddr_emu rk3588_ddr_v1.19_prod.bin 50000
|
|
|
|
# === Ghidra Decompilation (x86 only) ===
|
|
|
|
decompile: ddr_decompiled.c
|
|
|
|
ddr_decompiled.c: $(BLOB_FAST) ExportDecompiled.java
|
|
@test -d $(GHIDRA) || (echo "Error: Ghidra not found at $(GHIDRA)" && exit 1)
|
|
rm -rf ghidra_project ghidra_project.rep
|
|
JAVA_HOME=$(JAVA_HOME) $(GHIDRA)/support/analyzeHeadless . ghidra_project \
|
|
-import $(BLOB_FAST) \
|
|
-processor 'AARCH64:LE:64:v8A' \
|
|
-scriptPath . \
|
|
-postScript ExportDecompiled.java $@
|
|
|
|
ddr_fast_asm.s: $(BLOB_FAST) ExportAsm.java
|
|
@test -d $(GHIDRA) || (echo "Error: Ghidra not found at $(GHIDRA)" && exit 1)
|
|
JAVA_HOME=$(JAVA_HOME) $(GHIDRA)/support/analyzeHeadless . ghidra_project \
|
|
-process $$(basename $(BLOB_FAST)) \
|
|
-noanalysis -scriptPath . \
|
|
-postScript ExportAsm.java $@
|
|
|
|
# === Analysis ===
|
|
|
|
diff: ddr_diff.txt
|
|
|
|
ddr_diff.txt: ddr_decompiled.c ddr_conservative_decompiled.c
|
|
diff $^ > $@ || true
|
|
@echo "$$(wc -l < $@) lines differ"
|
|
|
|
annotate: ddr_annotated.c
|
|
|
|
# === Cleanup ===
|
|
|
|
clean:
|
|
rm -f ddr_emu
|
|
rm -f rk3588_ddr_v1.19_prod.bin rk3588_ddr_v1.19_patched_v2.bin
|
|
rm -rf ghidra_project ghidra_project.rep ghidra_project.gpr
|
|
rm -f qemu_trace_*.log
|