Files
qdl/ks.c
T
Bjorn Andersson 457e2e830a flashmap: Introduce support for consuming a zip file
The flashmap and related files form a package, suitable for distribution
and one-step installation, but having to unzip the archive in order to
flash/install its content is not convenient for the user.

Extend the qdl_file helper code to also provide access to files within a
zip file, then extend the flashmap code to attempt to decode the package
file as such.

Pass the optional zip object around to the various places where we might
read files from the package.

With this we can now "flash" the installer.zip directly:

  qdl flash installer.zip

The selective flashing mechanism is carried into the zip handling,
allowing the user to flash specific memories only, such as:

  qdl flash installer.zip::spinor

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
2026-04-22 17:14:46 -05:00

142 lines
3.0 KiB
C

// SPDX-License-Identifier: BSD-3-Clause
#include <sys/types.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "qdl.h"
#include "oscompat.h"
#ifdef _WIN32
const char *__progname = "ks";
#endif
static struct qdl_device qdl;
bool qdl_debug;
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout __unused)
{
return read(qdl->fd, buf, len);
}
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, unsigned int timeout __unused)
{
return write(qdl->fd, buf, len);
}
static void print_usage(FILE *out)
{
extern const char *__progname;
fprintf(out,
"%s -p <sahara dev_node> -s <id:file path> ...\n",
__progname);
fprintf(out,
" -h --help Print this usage info\n"
" -p --port Sahara device node to use\n"
" -s <id:file path> --sahara <id:file path> Sahara protocol file mapping\n"
"\n"
"One -p instance is required. One or more -s instances are required.\n"
"\n"
"Example:\n"
"ks -p /dev/mhi0_QAIC_SAHARA -s 1:/opt/qti-aic/firmware/fw1.bin -s 2:/opt/qti-aic/firmware/fw2.bin\n");
}
int main(int argc, char **argv)
{
struct sahara_image mappings[MAPPING_SZ] = {};
const char *filename;
bool found_mapping = false;
char *dev_node = NULL;
long file_id;
char *colon;
int opt;
int ret;
static struct option options[] = {
{"debug", no_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{"port", required_argument, 0, 'p'},
{"sahara", required_argument, 0, 's'},
{0, 0, 0, 0}
};
while ((opt = getopt_long(argc, argv, "dvp:s:h", options, NULL)) != -1) {
switch (opt) {
case 'd':
qdl_debug = true;
break;
case 'v':
print_version();
return 0;
case 'p':
dev_node = optarg;
printf("Using port - %s\n", dev_node);
break;
case 's':
found_mapping = true;
file_id = strtol(optarg, NULL, 10);
if (file_id < 0) {
print_usage(stderr);
return 1;
}
if (file_id >= MAPPING_SZ) {
fprintf(stderr,
"ID:%ld exceeds the max value of %d\n",
file_id,
MAPPING_SZ - 1);
return 1;
}
colon = strchr(optarg, ':');
if (!colon) {
print_usage(stderr);
return 1;
}
filename = &optarg[colon - optarg + 1];
ret = load_sahara_image(NULL, filename, &mappings[file_id]);
if (ret < 0)
return 1;
printf("Created mapping ID:%ld File:%s\n", file_id, filename);
break;
case 'h':
print_usage(stdout);
return 0;
default:
print_usage(stderr);
return 1;
}
}
// -p and -s is required
if (!dev_node || !found_mapping) {
print_usage(stderr);
return 1;
}
if (qdl_debug)
print_version();
qdl.fd = open(dev_node, O_RDWR);
if (qdl.fd < 0) {
fprintf(stderr, "Unable to open %s\n", dev_node);
return 1;
}
ret = sahara_run(&qdl, mappings, NULL, NULL);
if (ret < 0)
return 1;
return 0;
}