|
#!/usr/bin/env python3 |
|
|
|
import argparse |
|
import struct |
|
from pathlib import Path |
|
|
|
# https://github.com/torvalds/linux/blob/13a2e429f644691fca70049ea1c75f135957c788/drivers/thunderbolt/nvm.c#L19 |
|
INTEL_NVM_DEVID = 0x05 |
|
INTEL_NVM_VERSION = 0x08 |
|
INTEL_NVM_CSS = 0x10 |
|
INTEL_NVM_FLASH_SIZE = 0x45 |
|
|
|
|
|
# https://github.com/torvalds/linux/blob/13a2e429f644691fca70049ea1c75f135957c788/drivers/thunderbolt/nvm.c#L56 |
|
def strip_nvm(nvm: bytes) -> bytes: |
|
nvm_offset = struct.unpack_from("<I", nvm)[0] |
|
device_id = struct.unpack_from("<H", nvm, nvm_offset + INTEL_NVM_DEVID)[0] |
|
version = struct.unpack_from("<I", nvm, nvm_offset + INTEL_NVM_VERSION)[0] |
|
major_version = (version >> 16) & 0xFF |
|
minor_version = (version >> 8) & 0xFF |
|
nvm_size = struct.unpack_from("<I", nvm, nvm_offset + INTEL_NVM_FLASH_SIZE)[0] |
|
nvm_size = (1024 * 1024 << (nvm_size & 7)) // 8 |
|
nvm_size = (nvm_size - 16 * 1024) // 2 |
|
print(f"NVM offset: 0x{nvm_offset:X}") |
|
print(f"Device ID: 0x{device_id:X}") |
|
print(f"NVM version: {major_version:X}.{minor_version:X}") |
|
print(f"NVM size: 0x{nvm_size:X}") |
|
|
|
return nvm[0 : nvm_offset + nvm_size] |
|
|
|
|
|
def main() -> None: |
|
parser = argparse.ArgumentParser(prog="nvm-strip") |
|
parser.add_argument("input", type=Path) |
|
parser.add_argument("output", type=Path) |
|
|
|
args = parser.parse_args() |
|
with open(args.input, "rb") as fp: |
|
nvm = fp.read() |
|
|
|
stripped_nvm = strip_nvm(nvm) |
|
with open(args.output, "wb") as fp: |
|
fp.write(stripped_nvm) |
|
|
|
|
|
main() |