Metadata-Version: 2.4
Name: asm3042-flasher
Version: 0.4.16
Summary: CLI-утилита для чтения, runtime-загрузки и постоянной прошивки firmware ASMedia ASM3042 и ASM3142 под Linux
License: MIT
Keywords: asmedia,asm3042,firmware,pci,linux,xhci
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Topic :: System :: Hardware
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Dynamic: license-file

# asm3042-flasher

`asm3042-flasher` это Python-пакет с CLI-утилитой для Linux, предназначенной для работы с firmware PCIe-контроллеров ASMedia ASM3042 и ASM3142.

Пакет поддерживает три режима работы:

- `upload`: runtime-загрузка firmware в SRAM контроллера;
- `permanent-write-internal`: постоянная запись во встроенный SPI ROM через внутренний ASMedia PCIe-протокол;
- `crossflash-internal`: упрощённый high-level internal crossflash по `.bin + ASMTxHCIMPTool.ini`;
- `permanent-restore-internal`: восстановление встроенного SPI ROM из ранее сохранённого backup;
- `permanent-write`: постоянная запись через `flashrom` и внешний SPI-программатор.

## Статус проекта

Текущий статус: `alpha`.

Internal permanent-flash путь реализован по reverse-engineering Windows-пакета `ASMTxHCI_MPTool` и предназначен для Linux-систем, где нужно получить поведение, близкое к фирменной Windows-утилите, без внешнего программатора.

## Возможности

- поиск ASMedia xHCI-устройств через `/sys/bus/pci/devices`;
- чтение текущей версии running firmware через mailbox-регистры;
- разбор `.bin`-файла и извлечение permanent payload из ASMedia-образов с тегами `*_RCFG` и `*_FW`;
- runtime-загрузка firmware в SRAM;
- чтение встроенного SPI ROM через внутренний PCIe-протокол;
- постоянная запись встроенного SPI ROM через внутренний PCIe-протокол;
- восстановление встроенного SPI ROM из backup без внешнего программатора;
- резервное копирование SPI ROM перед постоянной записью;
- запись manifest-файла рядом с backup для recovery-аудита;
- автоматическая запись operation log рядом с вызовом опасной команды;
- проверка manifest-файла при internal restore;
- fail-closed backup и rollback для внешнего `flashrom`-пути;
- альтернативная работа через `flashrom` и внешний SPI-программатор.

## Поддерживаемые устройства

Подтверждённый safe allowlist пакета:

- `1b21:3042`
- `1b21:3142`

Для других ASMedia xHCI-устройств доступен `--force-device`, но использовать его нужно только после отдельной проверки совместимости.

## Требования

- Linux;
- Python 3.10 или новее;
- права `root` для `version`, `upload`, `permanent-read-internal` и `permanent-write-internal`;
- установленный `flashrom` и внешний SPI-программатор, если используется внешний путь `permanent-read` или `permanent-write`;
- корректный firmware-файл `.bin`, совместимый с вашей платой и ревизией контроллера.

## Установка

Установка из PyPI:

```bash
python -m pip install asm3042-flasher
```

Установка из исходников:

```bash
python -m pip install .
```

Запуск тестов в репозитории:

```bash
PYTHONPATH=src python -m pytest -q
```

## Быстрый старт

Найти поддерживаемые устройства:

```bash
asm3042-fw discover
```

Посмотреть структуру firmware-файла:

```bash
asm3042-fw inspect /path/to/firmware.bin
```

Прочитать текущую running firmware version:

```bash
sudo asm3042-fw version --bdf 0000:03:00.0
```

Сделать backup встроенного SPI ROM через внутренний ASMedia-протокол:

```bash
sudo asm3042-fw permanent-read-internal asm3142-backup.bin --bdf 0000:03:00.0
```

Постоянно записать встроенный SPI ROM без внешнего программатора:

```bash
sudo asm3042-fw permanent-write-internal /path/to/firmware.bin --bdf 0000:03:00.0
```

Безопасно посмотреть план прошивки и сохранить backup, не записывая SPI:

```bash
sudo asm3042-fw permanent-write-internal /path/to/firmware.bin --bdf 0000:03:00.0 --plan
```

Упрощённый internal crossflash с Windows-совместимыми subsystem-overrides из `ASMTxHCIMPTool.ini`:

```bash
sudo asm3042-fw crossflash-internal /path/to/firmware.bin \
  --ini /path/to/ASMTxHCIMPTool.ini \
  --bdf 0000:03:00.0
```

Фактическая запись для `crossflash-internal` требует явный `--apply`:

```bash
sudo asm3042-fw crossflash-internal /path/to/firmware.bin \
  --ini /path/to/ASMTxHCIMPTool.ini \
  --apply \
  --bdf 0000:03:00.0
```

Восстановить встроенный SPI ROM из backup:

```bash
sudo asm3042-fw permanent-restore-internal /share/iproskuryakov/fw.backup.bin --bdf 0000:03:00.0
```

Постоянно записать внешнюю flash-память через `flashrom`:

```bash
asm3042-fw permanent-write /path/to/firmware.bin --programmer ch341a_spi
```

## Команды

`asm3042-fw discover`

- выводит список найденных ASMedia xHCI-устройств;
- показывает `BDF`, `vendor`, `device`, текущий драйвер и статус `known-protocol`.

`asm3042-fw inspect <firmware.bin>`

- показывает источник и размер файла;
- извлекает `family-tag` и `header-tags`;
- для поддерживаемых ASMedia-образов показывает `permanent-raw-size` и `permanent-rom-size`.

`asm3042-fw version [--bdf ...]`

- читает running firmware version из контроллера;
- требует `root`;
- по умолчанию работает только с устройствами из allowlist.

`asm3042-fw upload <firmware.bin> [--bdf ...]`

- загружает firmware во внутреннюю SRAM;
- не меняет содержимое SPI ROM;
- требует `root`;
- по умолчанию временно отвязывает PCI-драйвер.

`asm3042-fw permanent-read-internal <backup.bin> [--bdf ...]`

- читает встроенный SPI ROM через внутренний ASMedia PCIe-протокол;
- требует `root`;
- по умолчанию читает весь обнаруженный SPI ROM;
- если устройство осталось в состоянии `driver=-`, сначала пытается автоматически восстановить `xhci_hcd` через `bind`, `reset` и `remove/rescan`;
- может использоваться для обязательного резервного копирования перед записью.
- рядом с backup пишет manifest-файл `<backup>.manifest.json` с ROM ID, SHA256 и PCI identity.

`asm3042-fw permanent-write-internal <firmware.bin> [--ini ASMTxHCIMPTool.ini] [--bdf ...]`

- собирает финальный ROM-образ по Windows-логике `CREATE_ROM`, а не шьёт только raw payload;
- может применить `SSID/SVID/PCIe speed` overrides из `ASMTxHCIMPTool.ini`;
- primary `device id` override во внутреннем `.ini` path намеренно заблокирован, пока он не будет подтверждён against real Windows MPTool on hardware;
- internal `.ini` path дополнительно пропускается через Windows-validated safety profile: только device type `2214A` и только известные subsystem overrides;
- при `--ini` текущий SPI ROM читается заранее и используется как источник canonical bootable base-config, а внешний `.bin` используется как источник нового payload;
- для ASM2142/ASM3142-class (`2214A`) builder нормализует config-block к Windows-style base layout (`0x30 + 0xCC-records`) и не переносит старые appended overrides из уже прошитого SPI-образа;
- при `--ini` пакет печатает predicted `target-primary-id` и `target-subsystem-id` до записи;
- для дополнительной страховки доступны `--require-subsystem-device-id` и `--require-subsystem-vendor-id`;
- internal `--ini` override path считается экспериментальным и по умолчанию заблокирован;
- для `--ini` нужно явно передать `--unsafe-allow-ini-overrides` и иметь внешний SPI recovery path;
- `--skip-backup` отключён: сохранение backup обязательно для любого internal write path;
- если `--backup-file` не задан, backup автоматически сохраняется в текущую рабочую директорию;
- `--plan` выполняет весь preflight, сохраняет backup и останавливается до записи SPI;
- рядом с операцией автоматически пишет `*.log` файл с key decisions, predicted IDs, backup/manifest путями, ошибками и встроенным SPI trace;
- перед записью выполняет round-trip validation собранного ROM-образа и отказывается шить структурно неконсистентный образ;
- записывает firmware во встроенный SPI ROM без внешнего программатора;
- пишет транзакционно по секторам: `erase -> write -> verify sector`; при первом расхождении останавливается;
- по умолчанию выполняет full readback verification после записи;
- если запись или verify завершаются ошибкой и backup был сохранён, пакет автоматически пытается восстановить предыдущий SPI-образ;
- рядом с backup пишет manifest-файл `<backup>.manifest.json`, чтобы recovery не зависел от ручных заметок;
- если устройство осталось в состоянии `driver=-`, сначала пытается автоматически восстановить `xhci_hcd` через `bind`, `reset` и `remove/rescan`;
- после записи требует cold reboot или power cycle для проверки нового образа.

`asm3042-fw crossflash-internal <firmware.bin> --ini ASMTxHCIMPTool.ini [--bdf ...]`

- это упрощённый high-level wrapper вокруг `permanent-write-internal --ini`;
- он ориентирован только на Windows-подтверждённый subsystem-level path (`svid/ssid/pcie_speed`);
- primary `device id` remap в internal path намеренно запрещён;
- по умолчанию работает в safe plan-only режиме и сохраняет backup без записи SPI;
- для реальной записи нужен явный `--apply`;
- автоматически выводит и закрепляет ожидаемые subsystem target IDs из `.ini`;
- использует те же safe backup/verify/rollback механизмы, что и обычный internal write;
- если `--backup-file` не задан, backup автоматически сохраняется в текущую рабочую директорию;
- поддерживает `--plan`; но без `--apply` он и так не пишет SPI.
- автоматически пишет operation log, который можно сразу приложить к отчёту о сбое.

`asm3042-fw permanent-restore-internal <backup.bin> [--bdf ...]`

- восстанавливает встроенный SPI ROM из ранее сохранённого backup;
- требует `root`;
- использует тот же internal PCIe flash path, что и `permanent-write-internal`;
- если рядом есть `<backup>.manifest.json`, проверяет `sha256` и размер backup до записи;
- по умолчанию делает post-restore readback verification;
- после восстановления требует cold reboot или power cycle.

`asm3042-fw permanent-read <backup.bin> --programmer ...`

- читает SPI flash через `flashrom` и внешний программатор.
- после чтения пишет manifest-файл `<backup>.manifest.json` с `sha256`, programmer/chip и путём backup.
- также пишет operation log с параметрами вызова и результатом.

`asm3042-fw permanent-write <firmware.bin> --programmer ...`

- пишет SPI flash через `flashrom` и внешний программатор;
- теперь всегда делает pre-write backup и не позволяет `--skip-backup`;
- проверяет, что backup-файл реально записан и не пустой;
- пишет manifest-файл `<backup>.manifest.json` рядом с backup;
- если `flashrom`-запись падает, пытается восстановить старый SPI-образ из backup тем же программатором;
- автоматически пишет operation log с backup/rollback и ошибкой;
- остаётся полезным fallback-режимом, если internal PCIe-путь не подходит.

## Примеры

Постоянная запись встроенной flash-памяти без внешнего программатора:

```bash
sudo asm3042-fw permanent-write-internal \
  /software/firmware_collection/expansion_board/AQAIC1-USB31-A2.bin \
  --bdf 0000:01:00.0
```

Упрощённый crossflash с `.ini` в безопасном plan-only режиме:

```bash
sudo asm3042-fw crossflash-internal \
  /software/firmware_collection/expansion_board/AQAIC1-USB31-A2.bin \
  --ini /home/ivan/Документы/ASMTxHCI_MPToolv1430/ASMTxHCIMPTool.ini \
  --backup-file /share/iproskuryakov/AQAIC1-USB31-A2.backup.bin \
  --bdf 0000:01:00.0
```

Фактическая запись после проверки плана:

```bash
sudo asm3042-fw crossflash-internal \
  /software/firmware_collection/expansion_board/AQAIC1-USB31-A2.bin \
  --ini /home/ivan/Документы/ASMTxHCI_MPToolv1430/ASMTxHCIMPTool.ini \
  --apply \
  --backup-file /share/iproskuryakov/AQAIC1-USB31-A2.backup.bin \
  --bdf 0000:01:00.0
```

Backup только первых `0x10000` байт:

```bash
sudo asm3042-fw permanent-read-internal partial-backup.bin --bdf 0000:01:00.0 --size 0x10000
```

## Ограничения и меры предосторожности

- Internal permanent path основан на reverse-engineering Windows-утилиты ASMedia, а не на официально опубликованной документации.
- Internal `--ini` override path остаётся экспериментальным: на ASM3142-class железе он уже приводил к не-bootable SPI образам и поэтому требует явного `--unsafe-allow-ini-overrides`.
- Primary `device id` override во внутреннем `.ini` path намеренно отключён: пока этот кусок не подтверждён against real Windows MPTool on hardware, пакет не будет шить такой remap.
- Internal `.ini` path дополнительно ограничен Windows-validated subset: подтверждён только `2214A/ASM2142/ASM3142`-класс с безопасными `svid/ssid/pcie_speed` значениями.
- Rollback защищает только от сбоев записи и verify при уже сохранённом backup; он не может исправить логически неверный, но успешно записанный ROM, если такой образ сам по себе не проходит PCI enumeration после power cycle.
- Для безопасной записи нужно использовать только firmware, совместимую с конкретной платой и ревизией контроллера.
- На время `unbind`/`bind` все USB-устройства за этим контроллером будут временно отключены.
- После `permanent-write-internal` running firmware может оставаться прежней до полного холодного перезапуска.
- Если контроллер после неудачной операции завис в состоянии `driver=-`, пакет сначала попробует `bind`, затем PCI `reset`, затем `remove/rescan`; если и это не помогает, нужен cold reboot.
- Если backup уже существует, пакет по умолчанию не перезапишет его без `--overwrite-backup`.
- Если устройство не входит в allowlist, пакет потребует явный `--force-device`.

## Публикация пакета

Сборка:

```bash
python -m build
```

Проверка README и метаданных:

```bash
python -m twine check dist/*
```

Публикация в PyPI:

```bash
python -m twine upload dist/*
```

## Основание реализации

Проект использует два источника протокола:

- публично доступную Linux-реализацию runtime firmware loader для ASMedia xHCI;
- reverse-engineering Windows-пакета `ASMTxHCI_MPTool`, включая `ASMTxHCI_MPTool.exe`, `ASMxHCICtlDLL.dll` и `ASMxHCICtl64.sys`.

## Лицензия

Проект распространяется под лицензией MIT. Полный текст находится в файле `LICENSE`.
