DTB LED Patcher for Router Firmware
This skill helps you work with `fix_led.py`, a specialized Python script that patches LED GPIO mappings in router firmware Device Tree Blob (DTB) files. It's designed for fixing LED functionality on routers running Gecoos AP firmware (MTK chipsets).
Purpose
The script performs surgical modifications to firmware binary files:
Scans firmware `.bin` files for embedded DTB blobs (identified by `0xD00DFEED` magic number)Modifies `/leds/*:gpios` properties **in-place**, changing only the second `u32` value in 3x `u32` arraysRecomputes DTB checksums (CRC32) and hashes (SHA1) after modificationsUpdates FIT image hash nodes so U-Boot verification still passesKey Constraints
When working with this codebase, **always** follow these rules:
1. Single-File Architecture
Keep everything in `fix_led.py` - **never split into modules**Standard library only - **no external dependencies allowed**Script must remain self-contained and portable2. DTB Size Immutability
**Never change DTB size** - all modifications must be in-placeDo not modify `totalsize` or relocate DTB blobsOnly modify fixed-size properties (currently 12-byte `gpios` values)3. INI-Only Configuration
All board configurations must use INI format in `leds.ini`**Do not introduce JSON, YAML, or other formats**Configuration schema: ```ini
[board_name]
dtb_index = 1 ; optional, 0-based DTB index
green = 8 ; LED name = GPIO pin number (decimal or 0x hex)
red = 34
```
Any key except `dtb_index` is treated as an LED name mapping to `/leds/<name>:gpios`4. Hash Logic is Critical
CRC32 must use `binascii.crc32(data) & 0xffffffff` with big-endian packingAfter patching, recompute both CRC32 (4 bytes) and SHA1 (20 bytes)FIT hash update must: - Find `/images/*/hash-*` nodes with `algo = "crc32"` or `"sha1"`
- Match old hash values first before overwriting
- **Never skip hash verification** unless `--no-fit-hash` is explicitly set
5. CLI Stability
Preserve existing option names and behavior: - `-b/--board` (stored as `args.profile`)
- `--config` (INI file path, default `leds.ini`)
- `-o/--output` (output firmware path)
- `--dtb-index` (legacy override for DTB selection)
- `--list` (dry-run mode, print info only)
- `--no-fit-hash` (skip FIT hash update - debug only)
**Do not suggest backwards-incompatible CLI changes**6. Safety Guarantees
Never overwrite input firmware file (check with `os.path.abspath`)Warn explicitly when nodes/properties are missingWarn when FIT hash nodes cannot be foundExit with error if critical operations failCommon Tasks
Listing DTBs in Firmware
```bash
python3 fix_led.py firmware.bin --list
```
This prints DTB indices, board names, and LED configurations without modifying the file.
Patching All Configured Boards (Batch Mode)
```bash
python3 fix_led.py firmware.bin
```
Processes all board profiles defined in `leds.ini`, creating separate output files for each.
Patching Specific Board
```bash
python3 fix_led.py firmware.bin -b konka_komi-a31 -o patched_firmware.bin
```
Adding New Board Configuration
Edit `leds.ini`:
```ini
[new_board_name]
dtb_index = 0
green = 12
red = 15
blue = 22
```
What You Can Help With
**Adding support for more property kinds**: Extend `MappingRule.kind` to handle other fixed-size `u32` arrays or simple strings (without size changes)**Improving logging and output**: Enhance user feedback without changing core behavior**Extending documentation**: Add examples in `README.md` and `leds.ini` for new boards**Testing**: Verify patches work on different firmware variantsWhat You Should Avoid
Changing DTB parsing logic (`scan_dtbs`, `parse_properties`, `collect_node_paths`) in ways that might miss valid DTBsModifying hash update logic or removing digest matchingIntroducing non-standard-library dependenciesRefactoring into multiple files/packagesMaking CLI changes that break existing scripts/workflowsTesting Workflow
```bash
Download test firmware (CI uses this URL)
curl -L -o test.bin "http://file.cnrouter.com/upload/test/集客AP_MTK_MT7981_WIFI6/JIKEAP_AP250MDV_MT7981_K5_NAND_8.1_2025102100.bin"
List DTBs to verify parsing
python3 fix_led.py test.bin --list
Test batch mode
python3 fix_led.py test.bin
Test single board mode
python3 fix_led.py test.bin -b konka_komi-a31 -o output.bin
```
Automated Release System
The repository includes `.github/workflows/release.yml` which:
Downloads latest firmware daily from vendor serverPatches all boards in `leds.ini` (batch mode)Creates GitHub releases with patched firmware filesTriggered by: daily cron (02:00 UTC), version tags (`v*`), or manual dispatchCode Style
Use type hints (already present in codebase)Follow existing docstring conventionsUse `#` for inline comments matching current styleKeep bilingual comments (Chinese/English) where they existImplementation Notes
DTB format: Flattened Device Tree (FDT) with big-endian `u32` structuresProperty modification: Locate property offset, modify bytes 4-7 (second `u32` in triplet), preserve restFIT image: U-Boot Flattened Image Tree containing multiple DTBs with embedded hashesHash chain: DTB CRC32/SHA1 → FIT `/images/*/hash-*` nodes → outer image verification