diff --git a/src/adsp_config.c b/src/adsp_config.c index ac19607..dc1d0b2 100644 --- a/src/adsp_config.c +++ b/src/adsp_config.c @@ -2337,15 +2337,50 @@ static int adsp_parse_config_fd(FILE *fd, struct image *image) return ret; } +static void copy_file(FILE *src, FILE *dst) +{ + char ch; + while ((ch = fgetc(src)) != EOF) + fputc(ch, dst); +} + +static FILE* adsp_conf_files_open(const struct adsp_conf_files *files, const char *mode) +{ + FILE *file, *out_file; + int i; + + out_file = fopen(files->out_file, "w"); + if (!out_file) { + file_error("unable to open file for writing", files->out_file); + return NULL; + } + + /* Merge multiple input toml files into one */ + for (i = 0; i < files->file_count; i++) { + fprintf(out_file, "## File path: %s\n", files->file[i]); + file = fopen(files->file[i], "r"); + if (!file) { + file_error("unable to open file for reading", files->file[i]); + fclose(out_file); + return NULL; + } + copy_file(file, out_file); + fclose(file); + fprintf(out_file, "\n\n"); + } + fclose(out_file); + return fopen(files->out_file, mode); +} + /* public function, fully handle parsing process */ -int adsp_parse_config(const char *file, struct image *image) +int adsp_parse_config(const struct adsp_conf_files *files, struct image *image) { FILE *fd; int ret; - fd = fopen(file, "r"); + fd = adsp_conf_files_open(files, "r"); if (!fd) - return file_error("unable to open file for reading", file); + return file_error("unable to open file for reading", files->out_file); ret = adsp_parse_config_fd(fd, image); fclose(fd); diff --git a/src/include/rimage/adsp_config.h b/src/include/rimage/adsp_config.h index e87c78c..fdbd39d 100644 --- a/src/include/rimage/adsp_config.h +++ b/src/include/rimage/adsp_config.h @@ -5,5 +5,5 @@ #include #include -int adsp_parse_config(const char *file, struct image *image); +int adsp_parse_config(const struct adsp_conf_files *file, struct image *image); void adsp_free(struct adsp *adsp); diff --git a/src/include/rimage/rimage.h b/src/include/rimage/rimage.h index 2b9a26e..f18c3a1 100644 --- a/src/include/rimage/rimage.h +++ b/src/include/rimage/rimage.h @@ -15,6 +15,7 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define MAX_MODULES 32 +#define MAX_SUPPORTED_CONF_FILES 8 struct adsp; @@ -128,6 +129,12 @@ struct adsp { int exec_boot_ldr; }; +struct adsp_conf_files { + uint32 file_count; + char *file[MAX_SUPPORTED_CONF_FILES]; + char *out_file; +}; + int ri_manifest_sign_v1_5(struct image *image); int ri_manifest_sign_v1_8(struct image *image); int ri_manifest_sign_v2_5(struct image *image); diff --git a/src/rimage.c b/src/rimage.c index 7c89e09..46e41fd 100644 --- a/src/rimage.c +++ b/src/rimage.c @@ -40,11 +40,14 @@ int main(int argc, char *argv[]) { struct image image; struct adsp *heap_adsp; - const char *adsp_config = NULL; - int opt, ret, i, first_non_opt; + struct adsp_conf_files files; + int opt, ret, first_non_opt; int use_ext_man = 0; unsigned int pv_bit = 0; + const char *adsp_desc_suffix = ".toml"; bool imr_type_override = false; + int i = 0; + size_t len; memset(&image, 0, sizeof(image)); @@ -84,7 +87,8 @@ int main(int argc, char *argv[]) use_ext_man = 1; break; case 'c': - adsp_config = optarg; + files.file[i] = optarg; + i++; break; case 'y': image.verify_file = optarg; @@ -110,11 +114,12 @@ int main(int argc, char *argv[]) first_non_opt = optind; /* we must have config */ - if (!adsp_config) { + if (i == 0 || i >= MAX_SUPPORTED_CONF_FILES) { usage(argv[0]); - fprintf(stderr, "error: must have adsp desc\n"); + fprintf(stderr, "error: invalid number of adsp_desc provided\n"); return -EINVAL; } + files.file_count = i; /* requires private key */ if (!image.key_name) { @@ -122,12 +127,25 @@ int main(int argc, char *argv[]) return -EINVAL; } - /* make sure we have an outfile if not verifying */ - if ((!image.out_file && !image.verify_file)) { + /* We are either signing or verifying an image, not both or neither */ + if (!(!!image.out_file ^ !!image.verify_file)) { usage(argv[0]); return -EINVAL; } + /* Construct the output path for the final adsp_desc toml */ + files.out_file = NULL; + if (image.out_file){ + len = strlen(image.out_file); + files.out_file = malloc(len + strlen(adsp_desc_suffix) + 1); + strcpy(files.out_file, image.out_file); + } else { + len = strlen(image.verify_file); + files.out_file = malloc(len + strlen(adsp_desc_suffix) + 1); + strcpy(files.out_file, image.verify_file); + } + strcpy(files.out_file + len, adsp_desc_suffix); + /* firmware version: major.minor.micro */ if (image.fw_ver_string) { ret = sscanf(image.fw_ver_string, "%hu.%hu.%hu", @@ -161,7 +179,7 @@ int main(int argc, char *argv[]) } image.adsp = heap_adsp; memset(heap_adsp, 0, sizeof(*heap_adsp)); - ret = adsp_parse_config(adsp_config, &image); + ret = adsp_parse_config(&files, &image); if (ret < 0) goto out; @@ -272,5 +290,7 @@ int main(int argc, char *argv[]) if (image.out_fd) fclose(image.out_fd); + free(files.out_file); + return ret; }