[PR #7009] [MERGED] feat(firmware): inspect flattened devicetree blobs #7569

Closed
opened 2026-11-03 13:38:47 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7009
Author: @mvanhorn
Created: 10/24/2026
Status: ✅ Merged
Merged: 10/24/2026
Merged by: @morluto

Base: main ← Head: fix/devicetree-blob


📝 Commits (4)

  • 3a6af02 feat(firmware): inspect flattened devicetree blobs
  • a85a442 fix(firmware): reject conflicting devicetree phandles and bound page summaries
  • 1b8fb12 Merge main into devicetree inspection
  • 3da2904 Merge latest main into devicetree inspection

📊 Changes

31 files changed (+2311 additions, -9 deletions)

View changed files

📝 docs/cli.md (+12 -0)
➕ docs/devicetree.md (+102 -0)
📝 docs/firmware-analysis.md (+7 -0)
📝 package.json (+1 -0)
📝 scripts/lib/catalog-builders.mjs (+7 -0)
➕ scripts/verify/firmware/devicetree.mjs (+88 -0)
📝 src/application/CapabilityInventory.ts (+1 -0)
➕ src/application/binaryDiagnostics/DevicetreePort.ts (+20 -0)
➕ src/application/binaryDiagnostics/DevicetreeService.test.ts (+110 -0)
➕ src/application/binaryDiagnostics/DevicetreeService.ts (+129 -0)
📝 src/cli/binaryDiagnosticsCommands.ts (+51 -0)
📝 src/cliCommandNames.ts (+1 -0)
📝 src/composition/binaryDiagnostics.ts (+5 -0)
📝 src/contracts/native/binaryDiagnosticsToolContracts.ts (+25 -0)
📝 src/contracts/toolEffects.test.ts (+1 -0)
📝 src/contracts/toolEffects.ts (+1 -0)
📝 src/domain/analysisView/analysisView.ts (+24 -0)
➕ src/domain/analysisView/devicetreeView.ts (+157 -0)
📝 src/domain/artifactOperationError.ts (+1 -0)
➕ src/domain/firmware/devicetree.ts (+98 -0)

...and 11 more files

📄 Description

Summary

Flattened devicetree blobs (.dtb, magic d00dfeed) describe the hardware of most ARM and RISC-V boards and ship inside firmware images. REA can extract firmware but had no structured reader for the blobs it finds. This adds inspect-devicetree (CLI) and inspect_devicetree (MCP) for FDT v16/v17 blobs, with no dtc dependency and no target execution. No related issue; this is a new static format within existing firmware analysis.

Problem and expected behavior

Today an analyst who extracts a .dtb has to run dtc -I dtb -O dts outside REA and then lose the evidence trail. Expected: REA reports the validated header, memory reservations, the node and property tree with bounded raw previews, standard derived values (model, compatible, aliases, stdout-path, bootargs) and resolved phandle references.

Change and scope

src/firmware/devicetree/DevicetreeParser.ts validates the header and block layout, walks the structure block and decodes standard properties. Derived values carry confidence: "derived"; raw property bytes are kept as bounded previews.

Parsing enforces file, tree and decoded-representation budgets and rejects malformed input without partial success. Summary delivery supports retained Evidence pagination. Not included: overlay (/plugin/) application, binding validation against schemas, or DTS reconstruction. AI was used for assistance.

Follow the contribution scope.
Unresolved scope, authority, side effects, or required verification block
integration. Link the required maintainer scope decision for new providers or
capabilities involving target execution, injection, mutation, or protection
recovery; ordinary fixes within existing boundaries may state "not applicable".
Draft PRs may leave the scope decision pending and the readiness and merge checklists
unchecked. Maintainers can help resolve open questions.

Contract and boundary impact

  • Semantic owner and earliest changed stage: firmware format inspection (src/firmware/devicetree/) and the binary diagnostics service.
  • Contribution scope fit and linked maintainer decision: static format inspection of a local file within existing firmware analysis; separate scope decision not applicable.
  • CLI and MCP/tool-catalog contract: new inspect-devicetree command and inspect_devicetree tool.
  • Provider, bridge, target-format, or platform compatibility: portable TypeScript, no provider and no dtc.
  • Evidence, artifact, provenance, or reconstruction contract: Evidence carries artifact identity, header and block offsets, and coverage counts; derived values are labeled.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): unchanged; reads a stable regular file.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact (CI generates and validates ignored catalogs and skills/; edit authored instructions in .agents/skills/reverse-engineer-anything/ and never commit build outputs): catalog builder entry and a verify:devicetree package script. No committed build outputs.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: src/firmware/devicetree/DevicetreeParser.test.ts (v16/v17 headers, reservations, nested nodes, phandles, truncated and overlapping blocks, budget exhaustion), DevicetreeService.test.ts, tests/acceptance/devicetreeCli.test.ts, tests/boundary/mcp/devicetreeMcp.test.ts (including access after the input is removed), and the shared tool-contract list. Fixtures are synthetic; no binaries are committed.
  • Base reproduction or other evidence: the released CLI has no devicetree reader. Executed against a dtc-compiled board blob and the Raspberry Pi 4 bcm2711-rpi-4-b.dtb from the Raspberry Pi firmware tree (not committed), compared with dtc -I dtb -O dts.
  • User-visible CLI/MCP output (if applicable): see below.
  • Remaining proof gaps: overlay blobs and big-tree budget edges were exercised with synthetic fixtures only.
$ rea inspect-devicetree bcm2711-rpi-4-b.dtb --json | jq ...
header: version 17  last_comp_version 16  totalsize 56407
reservations: 1   coverage: complete  nodes 325  properties 1753
model: Raspberry Pi 4 Model B
compatible: raspberrypi,4-model-b  brcm,bcm2711
stdout_path: serial0:115200n8   aliases: 55
reference: / interrupt-parent -> phandle 1 -> /soc/interrupt-controller@40041000

dtc -I dtb -O dts on the same blob emits 325 nodes. All 4 phandle references REA reports resolve to the same targets in the dtc output.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

Head 3a6af020c on main d361c53c5; macOS arm64, Node 26.5.0, npm 12.2.0:

  • npx --no-install vitest run src/application/binaryDiagnostics/DevicetreeService.test.ts src/contracts/toolEffects.test.ts src/firmware/devicetree/DevicetreeParser.test.ts tests/acceptance/devicetreeCli.test.ts tests/acceptance/tools/localToolContracts.test.ts tests/boundary/mcp/devicetreeMcp.test.ts - passed.
  • Real bcm2711-rpi-4-b.dtb and a dtc-built board blob inspected as shown above.

Compatibility, safety, and release

  • Breaking changes or migration steps: none; new command and tool only.
  • Real Hopper/Ghidra, browser, or OS coverage: macOS arm64; no provider involved.
  • Package or release metadata impact: one new package script (verify:devicetree).
  • Security, privacy, process, or containment review: input is parsed only, under named budgets; malformed blobs fail closed.

Author readiness

Human owner: @mvanhorn

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

Demo

demo


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/7009 **Author:** [@mvanhorn](https://github.com/mvanhorn) **Created:** 10/24/2026 **Status:** ✅ Merged **Merged:** 10/24/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/devicetree-blob` --- ### 📝 Commits (4) - [`3a6af02`](https://github.com/morluto/rea/commit/3a6af020c2727ca36970396f9c96c9729af27670) feat(firmware): inspect flattened devicetree blobs - [`a85a442`](https://github.com/morluto/rea/commit/a85a4429edccc70bcdb93598cc05066103e68794) fix(firmware): reject conflicting devicetree phandles and bound page summaries - [`1b8fb12`](https://github.com/morluto/rea/commit/1b8fb1245861e0b22964513578520abba9054766) Merge main into devicetree inspection - [`3da2904`](https://github.com/morluto/rea/commit/3da2904d23cb47cadd84cf3845a4537b6cf8f589) Merge latest main into devicetree inspection ### 📊 Changes **31 files changed** (+2311 additions, -9 deletions) <details> <summary>View changed files</summary> 📝 `docs/cli.md` (+12 -0) ➕ `docs/devicetree.md` (+102 -0) 📝 `docs/firmware-analysis.md` (+7 -0) 📝 `package.json` (+1 -0) 📝 `scripts/lib/catalog-builders.mjs` (+7 -0) ➕ `scripts/verify/firmware/devicetree.mjs` (+88 -0) 📝 `src/application/CapabilityInventory.ts` (+1 -0) ➕ `src/application/binaryDiagnostics/DevicetreePort.ts` (+20 -0) ➕ `src/application/binaryDiagnostics/DevicetreeService.test.ts` (+110 -0) ➕ `src/application/binaryDiagnostics/DevicetreeService.ts` (+129 -0) 📝 `src/cli/binaryDiagnosticsCommands.ts` (+51 -0) 📝 `src/cliCommandNames.ts` (+1 -0) 📝 `src/composition/binaryDiagnostics.ts` (+5 -0) 📝 `src/contracts/native/binaryDiagnosticsToolContracts.ts` (+25 -0) 📝 `src/contracts/toolEffects.test.ts` (+1 -0) 📝 `src/contracts/toolEffects.ts` (+1 -0) 📝 `src/domain/analysisView/analysisView.ts` (+24 -0) ➕ `src/domain/analysisView/devicetreeView.ts` (+157 -0) 📝 `src/domain/artifactOperationError.ts` (+1 -0) ➕ `src/domain/firmware/devicetree.ts` (+98 -0) _...and 11 more files_ </details> ### 📄 Description ## Summary Flattened devicetree blobs (`.dtb`, magic `d00dfeed`) describe the hardware of most ARM and RISC-V boards and ship inside firmware images. REA can extract firmware but had no structured reader for the blobs it finds. This adds `inspect-devicetree` (CLI) and `inspect_devicetree` (MCP) for FDT v16/v17 blobs, with no `dtc` dependency and no target execution. No related issue; this is a new static format within existing firmware analysis. ## Problem and expected behavior Today an analyst who extracts a `.dtb` has to run `dtc -I dtb -O dts` outside REA and then lose the evidence trail. Expected: REA reports the validated header, memory reservations, the node and property tree with bounded raw previews, standard derived values (model, compatible, aliases, stdout-path, bootargs) and resolved phandle references. ## Change and scope `src/firmware/devicetree/DevicetreeParser.ts` validates the header and block layout, walks the structure block and decodes standard properties. Derived values carry `confidence: "derived"`; raw property bytes are kept as bounded previews. Parsing enforces file, tree and decoded-representation budgets and rejects malformed input without partial success. Summary delivery supports retained Evidence pagination. Not included: overlay (`/plugin/`) application, binding validation against schemas, or DTS reconstruction. AI was used for assistance. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Unresolved scope, authority, side effects, or required verification block integration. Link the required maintainer scope decision for new providers or capabilities involving target execution, injection, mutation, or protection recovery; ordinary fixes within existing boundaries may state "not applicable". Draft PRs may leave the scope decision pending and the readiness and merge checklists unchecked. Maintainers can help resolve open questions. ## Contract and boundary impact - Semantic owner and earliest changed stage: firmware format inspection (`src/firmware/devicetree/`) and the binary diagnostics service. - Contribution scope fit and linked maintainer decision: static format inspection of a local file within existing firmware analysis; separate scope decision not applicable. - CLI and MCP/tool-catalog contract: new `inspect-devicetree` command and `inspect_devicetree` tool. - Provider, bridge, target-format, or platform compatibility: portable TypeScript, no provider and no `dtc`. - Evidence, artifact, provenance, or reconstruction contract: Evidence carries artifact identity, header and block offsets, and coverage counts; derived values are labeled. - Target selection, authority, upstream behavior, and cleanup details (if applicable): unchanged; reads a stable regular file. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs): catalog builder entry and a `verify:devicetree` package script. No committed build outputs. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: `src/firmware/devicetree/DevicetreeParser.test.ts` (v16/v17 headers, reservations, nested nodes, phandles, truncated and overlapping blocks, budget exhaustion), `DevicetreeService.test.ts`, `tests/acceptance/devicetreeCli.test.ts`, `tests/boundary/mcp/devicetreeMcp.test.ts` (including access after the input is removed), and the shared tool-contract list. Fixtures are synthetic; no binaries are committed. - Base reproduction or other evidence: the released CLI has no devicetree reader. Executed against a `dtc`-compiled board blob and the Raspberry Pi 4 `bcm2711-rpi-4-b.dtb` from the Raspberry Pi firmware tree (not committed), compared with `dtc -I dtb -O dts`. - User-visible CLI/MCP output (if applicable): see below. - Remaining proof gaps: overlay blobs and big-tree budget edges were exercised with synthetic fixtures only. ```text $ rea inspect-devicetree bcm2711-rpi-4-b.dtb --json | jq ... header: version 17 last_comp_version 16 totalsize 56407 reservations: 1 coverage: complete nodes 325 properties 1753 model: Raspberry Pi 4 Model B compatible: raspberrypi,4-model-b brcm,bcm2711 stdout_path: serial0:115200n8 aliases: 55 reference: / interrupt-parent -> phandle 1 -> /soc/interrupt-controller@40041000 ``` `dtc -I dtb -O dts` on the same blob emits 325 nodes. All 4 phandle references REA reports resolve to the same targets in the dtc output. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed Head `3a6af020c` on main `d361c53c5`; macOS arm64, Node 26.5.0, npm 12.2.0: - `npx --no-install vitest run src/application/binaryDiagnostics/DevicetreeService.test.ts src/contracts/toolEffects.test.ts src/firmware/devicetree/DevicetreeParser.test.ts tests/acceptance/devicetreeCli.test.ts tests/acceptance/tools/localToolContracts.test.ts tests/boundary/mcp/devicetreeMcp.test.ts` - passed. - Real `bcm2711-rpi-4-b.dtb` and a `dtc`-built board blob inspected as shown above. ## Compatibility, safety, and release - Breaking changes or migration steps: none; new command and tool only. - Real Hopper/Ghidra, browser, or OS coverage: macOS arm64; no provider involved. - Package or release metadata impact: one new package script (`verify:devicetree`). - Security, privacy, process, or containment review: input is parsed only, under named budgets; malformed blobs fail closed. ## Author readiness Human owner: @mvanhorn - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. ## Demo ![demo](https://raw.githubusercontent.com/mvanhorn/pr-demo-assets/main/rea/2026-10-24-013-feat-devicetree-blob/preview.gif) <video src="https://mvanhorn.github.io/pr-demo-assets/rea/2026-10-24-013-feat-devicetree-blob/out.mp4" controls width="720"></video> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-03 13:38:47 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#7569
No description provided.