mirror of
https://github.com/linux-msm/qdl.git
synced 2026-10-07 06:29:17 -07:00
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>
41 lines
1.0 KiB
C
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
|