mirror of
https://github.com/linux-msm/qdl.git
synced 2026-02-25 13:12:25 -08:00
ks (short for kickstart) is a utility which uses sahara to load images from the host to a device. This is intended for "flashless boot" devices like the Qualcomm Cloud AI 100 which rely on obtaining the runtime firmware from the host instead of storing it on device. While ks uses sahara, like qdl, it is different enough that a separate utility is justified. ks does not need USB support, instead opting for simple open()/read()/write() operations. ks does not need firehose. The set of program arguments that ks needs is vastly different than the set that qdl supports. This initial implementation of ks defines two arguments. Both are required, but the image specifier argument can be specified more than one. A sample invocation - ks -p /dev/mhi0_QAIC_SAHARA -s 1:/opt/qti-aic/firmware/fw1.bin -s 2:/opt/qti-aic/firmware/fw2.bin In this example, ks is instructed to use the /dev/mhi0_QAIC_SAHARA device node file as the "port" which the device is using for the sahara protocol. /opt/qti-aic/firmware/fw1.bin is mapped to id 1, and /opt/qti-aic/firmware/fw2.bin is mapped to id 2. If the device requests image id 1, ks will attempt to open and read /opt/qti-aic/firmware/fw1.bin to send to the device. Note that /opt/qti-aic/firmware/fw1.bin does not need to exist on the filesystem. If ks cannot access the file (perhaps because it does not exist), then the device will determine the next action. This is useful for setting up a single command in a udev rule that can handle multiple configurations, such as an optional DDR training process. Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
118 lines
2.4 KiB
C
118 lines
2.4 KiB
C
#include <sys/types.h>
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <dirent.h>
|
|
#include <err.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <getopt.h>
|
|
#include <poll.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
|
|
#include "qdl.h"
|
|
|
|
static struct qdl_device qdl;
|
|
|
|
bool qdl_debug;
|
|
|
|
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
|
|
{
|
|
return read(qdl->fd, buf, len);
|
|
}
|
|
|
|
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
|
|
{
|
|
|
|
return write(qdl->fd, buf, len);
|
|
}
|
|
|
|
static void print_usage(void)
|
|
{
|
|
extern const char *__progname;
|
|
fprintf(stderr,
|
|
"%s -p <sahara dev_node> -s <id:file path> ...\n",
|
|
__progname);
|
|
fprintf(stderr,
|
|
" -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)
|
|
{
|
|
bool found_mapping = false;
|
|
char *dev_node = NULL;
|
|
long file_id;
|
|
char *colon;
|
|
int opt;
|
|
int ret;
|
|
|
|
static struct option options[] = {
|
|
{"port", required_argument, 0, 'p'},
|
|
{"sahara", required_argument, 0, 's'},
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
while ((opt = getopt_long(argc, argv, "p:s:", options, NULL )) != -1) {
|
|
switch (opt) {
|
|
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();
|
|
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();
|
|
return 1;
|
|
}
|
|
qdl.mappings[file_id] = &optarg[colon - optarg + 1];
|
|
printf("Created mapping ID:%ld File:%s\n", file_id, qdl.mappings[file_id]);
|
|
break;
|
|
default:
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// -p and -s is required
|
|
if (!dev_node || !found_mapping) {
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
|
|
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, qdl.mappings);
|
|
if (ret < 0)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|