#!/usr/bin/env python3 import json import os import hashlib import shutil import struct import subprocess from copy import deepcopy from pathlib import Path from collections import namedtuple ROOT = Path(__file__).parent.parent OUTPUT_DIR = ROOT / "output" FIRMWARE_DIR = ROOT / "firmware" OTA_OUTPUT_DIR = OUTPUT_DIR / "ota" BUILD_DIR = ROOT / "build" SECTOR_SIZE = 4096 AGNOS_UPDATE_URL = os.getenv("AGNOS_UPDATE_URL", "https://commadist.azureedge.net/agnosupdate") AGNOS_STAGING_UPDATE_URL = os.getenv("AGNOS_STAGING_UPDATE_URL", "https://commadist.azureedge.net/agnosupdate-staging") GPT = namedtuple('GPT', ['lun', 'name', 'path', 'start_sector', 'num_sectors', 'has_ab', 'ota', 'full_check', 'sparse']) GPTS = [ GPT(0, 'gpt_main_0', FIRMWARE_DIR / 'gpt_main_0.img', 0, 6, False, False, True, False), GPT(1, 'gpt_main_1', FIRMWARE_DIR / 'gpt_main_1.img', 0, 6, False, False, True, False), GPT(2, 'gpt_main_2', FIRMWARE_DIR / 'gpt_main_2.img', 0, 6, False, False, True, False), GPT(3, 'gpt_main_3', FIRMWARE_DIR / 'gpt_main_3.img', 0, 6, False, False, True, False), GPT(4, 'gpt_main_4', FIRMWARE_DIR / 'gpt_main_4.img', 0, 6, False, False, True, False), GPT(5, 'gpt_main_5', FIRMWARE_DIR / 'gpt_main_5.img', 0, 6, False, False, True, False), ] Partition = namedtuple('Partition', ['name', 'path', 'has_ab', 'ota', 'full_check', 'sparse']) PARTITIONS = [ Partition('persist', FIRMWARE_DIR / 'persist.img', False, False, True, False), Partition('systemrw', FIRMWARE_DIR / 'systemrw.img', False, False, True, False), Partition('cache', FIRMWARE_DIR / 'cache.img', False, False, True, False), Partition('xbl', FIRMWARE_DIR / 'xbl.img', True, True, True, False), Partition('xbl_config', FIRMWARE_DIR / 'xbl_config.img', True, True, True, False), Partition('abl', FIRMWARE_DIR / 'abl.img', True, True, True, False), Partition('aop', FIRMWARE_DIR / 'aop.img', True, True, True, False), Partition('bluetooth', FIRMWARE_DIR / 'bluetooth.img', True, False, True, False), Partition('cmnlib64', FIRMWARE_DIR / 'cmnlib64.img', True, False, True, False), Partition('cmnlib', FIRMWARE_DIR / 'cmnlib.img', True, False, True, False), Partition('devcfg', FIRMWARE_DIR / 'devcfg.img', True, True, True, False), Partition('devinfo', FIRMWARE_DIR / 'devinfo.img', False, False, True, False), Partition('dsp', FIRMWARE_DIR / 'dsp.img', True, False, True, False), Partition('hyp', FIRMWARE_DIR / 'hyp.img', True, False, True, False), Partition('keymaster', FIRMWARE_DIR / 'keymaster.img', True, False, True, False), Partition('limits', FIRMWARE_DIR / 'limits.img', False, False, True, False), Partition('logfs', FIRMWARE_DIR / 'logfs.img', False, False, True, False), Partition('modem', FIRMWARE_DIR / 'modem.img', True, False, True, False), Partition('qupfw', FIRMWARE_DIR / 'qupfw.img', True, False, True, False), Partition('splash', FIRMWARE_DIR / 'splash.img', False, False, True, False), Partition('storsec', FIRMWARE_DIR / 'storsec.img', True, False, True, False), Partition('tz', FIRMWARE_DIR / 'tz.img', True, False, True, False), Partition('boot', OUTPUT_DIR / 'boot.img', True, True, True, False), Partition('system', OUTPUT_DIR / 'system.img', True, True, False, True), Partition('userdata_90', OUTPUT_DIR / 'userdata_90.img', False, False, True, True), Partition('userdata_89', OUTPUT_DIR / 'userdata_89.img', False, False, True, True), Partition('userdata_30', OUTPUT_DIR / 'userdata_30.img', False, False, True, True), ] def file_checksum(fn): sha256 = hashlib.sha256() with open(fn, 'rb') as f: for chunk in iter(lambda: f.read(4096), b""): sha256.update(chunk) return sha256 def ondevice_checksum_sparse(fn, ota): with open(fn, 'rb') as data_source: dat = data_source.read(28) header = struct.unpack(" None: # since system.img is a squashfs now, we don't rely on this compression. # however, openpilot's updater still expects an xz archive, so use lowest # compression level for quick packaging. subprocess.check_call(f"xz -0 -T0 -vc {fin} > {fout}", shell=True) def process_file(entry): size = entry.path.stat().st_size print(f"\n{entry.name} {size} bytes") sha256 = file_checksum(entry.path) hash = hash_raw = sha256.hexdigest() if struct.unpack("