ПРОРЫВ: загрузчик HKLFBOOT достижим + ВЧ-чип = BK4819

Слушая COM при включении в режим прошивки, поймал boot модуля: баннер HKLFBOOT......
VERSION:01020032 RF_IC:BK_4819. ВЧ-трансивер = Beken BK4819 (как в UV-K5, полностью
реверснут) -> частотная калибровка = регистры BK4819, можно чинить TX по мануалу.
Загрузчик HKLFBOOT достижим через мост (мост прозрачен, CH34x держит связь через
перезагрузку), ждёт хендшейк в окне '......'; стандартный Beken 01 E0 FC не подходит.
Обновлены docs/fm100b-firmware-re.md, память.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NikMGoqQWWk9wy2ww2vJAr
Этот коммит содержится в:
2026-07-24 05:40:37 +09:00
co-authored by Claude Opus 4.8
родитель 0173b96ee9
Коммит 1dedc4150b
2 изменённых файлов: 78 добавлений и 0 удалений
+17
Просмотреть файл
@@ -140,3 +140,20 @@ download-режим) при владельце, с риском. Пока вла
2. **WebRTC-параметры:** найти конфиг NSX/AGC (режим/пороги) в коде, изменить, перешить модуль
(режим «Обновление DMR чипа»), проверить звук/приём. Это и есть «поменять и посмотреть заведётся ли».
3. **EasyFlash NV:** распарсить NV-регион (cal) во flash-дампе — прямой доступ к калибровке без live-протокола.
## ⭐⭐ ПРОРЫВ (24.07): загрузчик HKLFBOOT + ВЧ-чип BK4819
Слушая COM во время включения рации в режим «Обновление DMR чипа», поймал загрузку модуля
(мост ПРОЗРАЧНО передаёт boot; CH34x-шнурок держит связь через перезагрузку рации):
```
\r\nHKLFBOOT......\r\n VERSION:01020032\r\n RF_IC:BK_4819\r\n
68 06 02 76 85 83 00 00 10 (далее приложение шлёт 0x68)
```
- **RF_IC = BK4819** — ВЧ-трансивер модуля = **Beken BK4819** (тот же, что в Quansheng UV-K5,
ПОЛНОСТЬЮ реверснут сообществом). Частотная калибровка/девиация/AFC RT-4D = **регистры BK4819**.
SPCali_* (0xB4 VCCN=freq-трим, FreqOpt, DigMod=девиация) отображаются в регистры BK4819.
→ чинить TX можно по документации BK4819 (UV-K5), возможно без полного дампа.
- **Загрузчик = «HKLFBOOT»** (кастом, не гуглится). ДОСТИЖИМ через мост, ждёт хендшейк во время
«......», затем грузит app. Стандартный Beken `01 E0 FC` НЕ подходит. Инструменты:
`tools/bk_bootloader_catch.py` (ловит баннер/линк), `tools/bk_deinterleave.py` (снять CRC с дампа).
- Дамп флеша модуля разблокируется, как найдём HKLF-хендшейк (реверс прошивки AT32 «Update DMR Chip»,
либо аккуратный перебор в boot-окне). Тогда получим RF Firmware (AMBE) + NET info (NV).
+61
Просмотреть файл
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
"""Поймать Beken-загрузчик модуля во время включения (через мост RT-4D, WSL/powershell).
Формат флеша модуля = стандартный Beken (32+2 CRC), значит у него Beken UART-загрузчик,
который слушает link-check КОРОТКОЕ окно после сброса. Этот тул одним процессом powershell
в тайтовом цикле спамит link-check `01 E0 FC 01 00` и ловит ответ `04 0E 05 ...`.
Использование: запусти тул, и в течение его работы ВЫКЛЮЧИ и включи рацию в режим
«Обновление DMR чипа» (питание + MENU). Если поймаем ответ — загрузчик достижим через мост.
ТОЛЬКО ЧТЕНИЕ/handshake — ни erase, ни write не шлём.
"""
import argparse, subprocess, sys
PS = r'''
$port="{port}"; $sec={sec}
$p = New-Object System.IO.Ports.SerialPort $port,115200,"None",8,"one"
$p.ReadTimeout=20; $p.WriteTimeout=50
try {{ $p.Open() }} catch {{ Write-Output "ERR:$($_.Exception.Message)"; exit }}
$lc=[byte[]]@(1,224,252,1,0) # 01 E0 FC 01 00
$sw=[Diagnostics.Stopwatch]::StartNew()
$hit=$false
while($sw.Elapsed.TotalSeconds -lt $sec){{
try {{ $p.Write($lc,0,$lc.Length) }} catch {{}}
Start-Sleep -Milliseconds 8
$n=$p.BytesToRead
if($n -gt 0){{
$b=New-Object byte[] $n; $p.Read($b,0,$n)|Out-Null
$hex=($b|ForEach-Object{{"{{0:x2}}"-f $_}}) -join ""
if($hex -match "e0fc"){{ Write-Output ("HIT:"+$hex); $hit=$true; break }}
else {{ Write-Output ("RX:"+$hex) }}
}}
}}
$p.Close()
if(-not $hit){{ Write-Output "NOHIT" }}
'''
def main():
ap=argparse.ArgumentParser()
ap.add_argument("--port", default="COM4")
ap.add_argument("--sec", type=int, default=25)
a=ap.parse_args()
print(f"[спам link-check на {a.port} @115200, {a.sec}с]")
print(">>> СЕЙЧАС выключи рацию и включи в режим «Обновление DMR чипа» (питание+MENU) <<<\n")
r=subprocess.run(["powershell.exe","-NoProfile","-Command",PS.format(port=a.port,sec=a.sec)],
capture_output=True, text=True)
for line in r.stdout.replace("\r","").split("\n"):
line=line.strip()
if line.startswith("HIT:"):
print(f"✅ ЗАГРУЗЧИК ОТВЕТИЛ: {line[4:]}")
print(" -> Beken-загрузчик достижим через мост. Можно читать флеш.")
elif line.startswith("RX:") and line[3:]:
print(f" (эхо/данные: {line[3:][:60]})")
elif line=="NOHIT":
print("❌ Ответа загрузчика не поймано. Либо мост не пробрасывает загрузчик,")
print(" либо окно/бод другие. Попробуй ещё раз или обсудим физ.доступ.")
elif line.startswith("ERR:"):
print(line)
if __name__=="__main__":
main()