Files
qdl/file.h
T
Igor Opaniuk 702abb441f qdl: add --skipblock=sha256 to skip programs already on flash
Automated flashing pipelines often re-program identical content on every
run, which dominates total flash time on slow storage like spinor. With
the <getsha256digest> primitive now exposed, qdl can ask the device for
the SHA-256 of the target region before each <program> and skip the
write when it already matches what would have been sent.

Add --skipblock=<none|sha256>, defaulting to none. When sha256 is
selected, firehose_program() hashes the bytes it would otherwise stream
to the device - reading num_partition_sectors * SECTOR_SIZE_IN_BYTES
from the file with zero-padding for the trailing partial sector, exactly
matching what the existing chunked write path puts on the wire - then
asks the device for the digest of the same region via
firehose_getsha256digest(), reusing the op->digest field that the
sha256 subcommand path also reads. On a match, the <program> is skipped
entirely and "skipped \"<label>\" (sha256 match)" is logged in place of
the usual flashed-at-rate line.

The optimization is gated on three conditions, all enforced silently:

  - !program->sparse: each sparse chunk would need its own digest;
    keeping sparse images on the normal program path avoids per-chunk
    round trips and the bookkeeping that would come with them.
  - !program->is_nand: NAND spare/OOB byte semantics differ across
    programmers, so the digest the device returns is not guaranteed to
    correspond to the bytes qdl would compute locally.
  - VIP disabled: <getsha256digest> is not part of pre-built VIP
    digest tables, so issuing it under VIP would cause a hash mismatch
    on the device.

Any failure on the optimization path - file read error, query failure,
digest absent, or digest mismatch - falls through to the normal program
flow. The file position is restored unconditionally by the existing
qdl_file_seek() at the top of the write loop, so the fall-through path
is byte-identical to --skipblock=none.

[1] https://github.com/linux-msm/qdl/issues/237

Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
2026-05-16 16:35:15 -05:00

41 lines
1.0 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef __QDL_FILE_H__
#define __QDL_FILE_H__
#include <sys/types.h>
struct zip_file;
enum qdl_file_type {
QDL_FILE_TYPE_UNKNOWN,
QDL_FILE_TYPE_POSIX,
QDL_FILE_TYPE_ZIP,
};
struct qdl_file {
enum qdl_file_type type;
size_t size;
int fd;
struct zip_file *zip_file;
};
struct qdl_zip;
int qdl_file_open(struct qdl_zip *qzip, const char *filename, struct qdl_file *file);
void *qdl_file_load(struct qdl_file *file, size_t *len);
void qdl_file_close(struct qdl_file *file);
size_t qdl_file_getsize(struct qdl_file *file);
ssize_t qdl_file_read(struct qdl_file *file, void *buf, size_t len);
ssize_t qdl_file_read_exact(struct qdl_file *file, void *buf, size_t len);
off_t qdl_file_seek(struct qdl_file *file, off_t offset, int whence);
int qdl_zip_open(const char *filename, struct qdl_zip **__qdl_zip);
struct qdl_zip *qdl_zip_get(struct qdl_zip *qzip);
void qdl_zip_put(struct qdl_zip *qzip);
#endif