diff --git a/docs/sbl-bringup.md b/docs/sbl-bringup.md index 716669b..64dc8e0 100644 --- a/docs/sbl-bringup.md +++ b/docs/sbl-bringup.md @@ -275,3 +275,8 @@ упирается в настоящий код прошивки. Дальше SDHCI и UEFI. - Creep 300B/Kinsn вверх остается, закрыт маппингами DDRHI-ext как runway. QEMU-паритет держится на b43. + +## logstream --logport 2026-09-15 +- Харнесс умеет отдавать лог в TCP: --logport PORT слушает 0.0.0.0, + tee stdout всем клиентам, accept в prog-блоке, медленные отваливаются. + Читать: nc HOST PORT. Строки с новыми строками как в stdout. diff --git a/tools/sbl_uni.py b/tools/sbl_uni.py index 371282f..b7f861e 100644 --- a/tools/sbl_uni.py +++ b/tools/sbl_uni.py @@ -3,7 +3,7 @@ Карта RAM как в saimaa; ELF-сегменты; UARTDM/TF в stdout; MMIO->0. Использование: ./tools/sbl_uni.py fw/img/patch/img0_b17.elf --thumb 0x802f63f [--regs r0=0x220000,...] - [--fill 0x085F0000:0x10000:0x08006831] [--poke 0xADDR=0xVAL] [--limit 1000000] + [--fill 0x085F0000:0x10000:0x08006831] [--poke 0xADDR=0xVAL] [--limit 1000000] [--logport PORT] Печатает: выполнено инстр., последний PC, fault-адрес, UART. """ import struct @@ -69,6 +69,43 @@ def load_elf(mu, path): def main(): path = sys.argv[1] + _logclients = [] + _loglisten = None + if '--logport' in sys.argv: + import socket as _skt + _loglisten = _skt.socket(_skt.AF_INET, _skt.SOCK_STREAM) + _loglisten.setsockopt(_skt.SOL_SOCKET, _skt.SO_REUSEADDR, 1) + _loglisten.bind(('0.0.0.0', int(sys.argv[sys.argv.index('--logport') + 1]))) + _loglisten.listen(8) + _loglisten.setblocking(False) + print('logstream: listening', flush=True) + _real_stdout = sys.stdout + class _Tee: + def write(self, s): + _real_stdout.write(s) + if _loglisten is not None and s: + _b = s.encode('utf-8', 'replace') + for _c in list(_logclients): + _n = 0 + try: + _n = _c.send(_b) + if _n < len(_b): + _n += _c.send(_b[_n:]) + except Exception: + pass + if _n < len(_b): + try: + _c.close() + except Exception: + pass + if _c in _logclients: + _logclients.remove(_c) + def flush(self): + _real_stdout.flush() + def isatty(self): + return False + if _loglisten is not None: + sys.stdout = _Tee() thumb = int(sys.argv[sys.argv.index("--thumb") + 1], 0) mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) for base, size in RAMS: @@ -205,6 +242,18 @@ def main(): print('prog:', count[0], hex(addr), hex(mu.reg_read(_SX)), hex(_RR(_R4)), hex(_RR(_R5)), hex(_RR(_R6)), hex(_RR(_R7)), hex(_RR(_R8)), hex(_RR(_R9)), hex(_RR(_RA)), hex(_RR(_RB)), flush=True) + if _loglisten is not None: + while True: + try: + _conn, _cli = _loglisten.accept() + except Exception: + break + try: + _conn.setblocking(False) + _conn.send(b'--- lumia-emu log stream ---\n') + except Exception: + pass + _logclients.append(_conn) _pp = _prev[0] _prev[0] = addr if addr == _pp + 2 or addr == _pp + 4: