xref: /aosp_15_r20/system/libufdt/utils/src/mkdtimg_create.c (revision 13e8728f0cffde9369df671f7b293a048a99c7ed)
1*13e8728fSAndroid Build Coastguard Worker /*
2*13e8728fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*13e8728fSAndroid Build Coastguard Worker  *
4*13e8728fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*13e8728fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*13e8728fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*13e8728fSAndroid Build Coastguard Worker  *
8*13e8728fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*13e8728fSAndroid Build Coastguard Worker  *
10*13e8728fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*13e8728fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*13e8728fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*13e8728fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*13e8728fSAndroid Build Coastguard Worker  * limitations under the License.
15*13e8728fSAndroid Build Coastguard Worker  */
16*13e8728fSAndroid Build Coastguard Worker 
17*13e8728fSAndroid Build Coastguard Worker #include <stdio.h>
18*13e8728fSAndroid Build Coastguard Worker #include <stdlib.h>
19*13e8728fSAndroid Build Coastguard Worker #include <string.h>
20*13e8728fSAndroid Build Coastguard Worker #include <unistd.h>
21*13e8728fSAndroid Build Coastguard Worker 
22*13e8728fSAndroid Build Coastguard Worker #include "dt_table.h"
23*13e8728fSAndroid Build Coastguard Worker #include "mkdtimg_core.h"
24*13e8728fSAndroid Build Coastguard Worker 
25*13e8728fSAndroid Build Coastguard Worker 
calculate_args_entry_count(int argc,char * argv[],int arg_start)26*13e8728fSAndroid Build Coastguard Worker static int calculate_args_entry_count(int argc, char *argv[], int arg_start) {
27*13e8728fSAndroid Build Coastguard Worker   int count = 0;
28*13e8728fSAndroid Build Coastguard Worker 
29*13e8728fSAndroid Build Coastguard Worker   int i;
30*13e8728fSAndroid Build Coastguard Worker   for (i = arg_start; i < argc; i++) {
31*13e8728fSAndroid Build Coastguard Worker     const char *arg = argv[i];
32*13e8728fSAndroid Build Coastguard Worker     char c = arg[0];
33*13e8728fSAndroid Build Coastguard Worker     /* Skip options starting with -- */
34*13e8728fSAndroid Build Coastguard Worker     if (c == '-') continue;
35*13e8728fSAndroid Build Coastguard Worker     count++;
36*13e8728fSAndroid Build Coastguard Worker   }
37*13e8728fSAndroid Build Coastguard Worker 
38*13e8728fSAndroid Build Coastguard Worker   return count;
39*13e8728fSAndroid Build Coastguard Worker }
40*13e8728fSAndroid Build Coastguard Worker 
parse_arg(char ** option,char ** value,char * arg)41*13e8728fSAndroid Build Coastguard Worker static int parse_arg(char **option, char **value, char *arg) {
42*13e8728fSAndroid Build Coastguard Worker   if (arg[0] != '-') {
43*13e8728fSAndroid Build Coastguard Worker     /* This is not a option */
44*13e8728fSAndroid Build Coastguard Worker     *option = NULL;
45*13e8728fSAndroid Build Coastguard Worker     return 0;
46*13e8728fSAndroid Build Coastguard Worker   }
47*13e8728fSAndroid Build Coastguard Worker 
48*13e8728fSAndroid Build Coastguard Worker   /* An option must start with -- */
49*13e8728fSAndroid Build Coastguard Worker   if (arg[1] != '-') {
50*13e8728fSAndroid Build Coastguard Worker     return -1;
51*13e8728fSAndroid Build Coastguard Worker   }
52*13e8728fSAndroid Build Coastguard Worker 
53*13e8728fSAndroid Build Coastguard Worker   return parse_option(option, value, arg + 2);
54*13e8728fSAndroid Build Coastguard Worker }
55*13e8728fSAndroid Build Coastguard Worker 
output_img_with_args(FILE * img_fp,int argc,char * argv[],int arg_start)56*13e8728fSAndroid Build Coastguard Worker static int output_img_with_args(FILE *img_fp, int argc, char *argv[], int arg_start) {
57*13e8728fSAndroid Build Coastguard Worker   int entry_count = calculate_args_entry_count(argc, argv, arg_start);
58*13e8728fSAndroid Build Coastguard Worker   struct dt_image_writer *writer = dt_image_writer_start(img_fp, entry_count);
59*13e8728fSAndroid Build Coastguard Worker 
60*13e8728fSAndroid Build Coastguard Worker   int is_entry = 0;
61*13e8728fSAndroid Build Coastguard Worker   int i;
62*13e8728fSAndroid Build Coastguard Worker   for (i = arg_start; i < argc; i++) {
63*13e8728fSAndroid Build Coastguard Worker     char *arg = argv[i];
64*13e8728fSAndroid Build Coastguard Worker     char *option, *value;
65*13e8728fSAndroid Build Coastguard Worker     if (parse_arg(&option, &value, arg) != 0) {
66*13e8728fSAndroid Build Coastguard Worker       fprintf(stderr, "Wrong syntax: %s\n", arg);
67*13e8728fSAndroid Build Coastguard Worker       return -1;
68*13e8728fSAndroid Build Coastguard Worker     }
69*13e8728fSAndroid Build Coastguard Worker 
70*13e8728fSAndroid Build Coastguard Worker     if (option == NULL) {
71*13e8728fSAndroid Build Coastguard Worker       /* This is a file name */
72*13e8728fSAndroid Build Coastguard Worker       if (dt_image_writer_add_entry(writer, arg) != 0) {
73*13e8728fSAndroid Build Coastguard Worker         return -1;
74*13e8728fSAndroid Build Coastguard Worker       }
75*13e8728fSAndroid Build Coastguard Worker       is_entry = 1;
76*13e8728fSAndroid Build Coastguard Worker       continue;
77*13e8728fSAndroid Build Coastguard Worker     }
78*13e8728fSAndroid Build Coastguard Worker 
79*13e8728fSAndroid Build Coastguard Worker     int ret = is_entry ?
80*13e8728fSAndroid Build Coastguard Worker       set_entry_options(writer, option, value) :
81*13e8728fSAndroid Build Coastguard Worker       set_global_options(writer, option, value);
82*13e8728fSAndroid Build Coastguard Worker     if (ret != 0) {
83*13e8728fSAndroid Build Coastguard Worker       fprintf(stderr, "Unknown option: %s\n", option);
84*13e8728fSAndroid Build Coastguard Worker       return -1;
85*13e8728fSAndroid Build Coastguard Worker     }
86*13e8728fSAndroid Build Coastguard Worker   } /* for all argv */
87*13e8728fSAndroid Build Coastguard Worker 
88*13e8728fSAndroid Build Coastguard Worker   if (dt_image_writer_end(writer) != 0) {
89*13e8728fSAndroid Build Coastguard Worker     return -1;
90*13e8728fSAndroid Build Coastguard Worker   }
91*13e8728fSAndroid Build Coastguard Worker 
92*13e8728fSAndroid Build Coastguard Worker   return 0;
93*13e8728fSAndroid Build Coastguard Worker }
94*13e8728fSAndroid Build Coastguard Worker 
handle_usage_create(FILE * out_fp,const char * prog_name)95*13e8728fSAndroid Build Coastguard Worker void handle_usage_create(FILE *out_fp, const char *prog_name) {
96*13e8728fSAndroid Build Coastguard Worker   fprintf(out_fp, "  %s create <image_file> (<global_option>...) (<dtb_file> (<entry_option>...) ...)\n\n", prog_name);
97*13e8728fSAndroid Build Coastguard Worker   fprintf(out_fp,
98*13e8728fSAndroid Build Coastguard Worker           "    global_options:\n"
99*13e8728fSAndroid Build Coastguard Worker           "      --dt_type=<type>         Device Tree type (dtb|acpi). Default:"
100*13e8728fSAndroid Build Coastguard Worker           " dtb\n"
101*13e8728fSAndroid Build Coastguard Worker           "      --page_size=<number>     Output page size. Default: 2048\n"
102*13e8728fSAndroid Build Coastguard Worker           "      --version=<version>      DTBO version. Default: 0\n"
103*13e8728fSAndroid Build Coastguard Worker           "      --id=<number|path>       The default value to set property id "
104*13e8728fSAndroid Build Coastguard Worker           "in dt_table_entry. Default: 0\n"
105*13e8728fSAndroid Build Coastguard Worker           "      --rev=<number|path>\n"
106*13e8728fSAndroid Build Coastguard Worker           "      --custom0=<number|path>\n"
107*13e8728fSAndroid Build Coastguard Worker           "      --custom1=<number|path>\n"
108*13e8728fSAndroid Build Coastguard Worker           "      --custom2=<number|path>\n"
109*13e8728fSAndroid Build Coastguard Worker           "      --custom3=<number|path>\n\n"
110*13e8728fSAndroid Build Coastguard Worker           "      The value could be a number or a DT node path.\n"
111*13e8728fSAndroid Build Coastguard Worker           "      <number> could be a 32-bits digit or hex value, ex. 68000, "
112*13e8728fSAndroid Build Coastguard Worker           "0x6800.\n"
113*13e8728fSAndroid Build Coastguard Worker           "      <path> format is <full_node_path>:<property_name>, ex. "
114*13e8728fSAndroid Build Coastguard Worker           "/board/:id,\n"
115*13e8728fSAndroid Build Coastguard Worker           "      will read the value in given FTB file with the path.\n");
116*13e8728fSAndroid Build Coastguard Worker }
117*13e8728fSAndroid Build Coastguard Worker 
handle_command_create(int argc,char * argv[],int arg_start)118*13e8728fSAndroid Build Coastguard Worker int handle_command_create(int argc, char *argv[], int arg_start) {
119*13e8728fSAndroid Build Coastguard Worker   int ret = -1;
120*13e8728fSAndroid Build Coastguard Worker   FILE *img_fp = NULL;
121*13e8728fSAndroid Build Coastguard Worker 
122*13e8728fSAndroid Build Coastguard Worker   if (argc - arg_start < 1) {
123*13e8728fSAndroid Build Coastguard Worker     handle_usage_create(stderr, argv[0]);
124*13e8728fSAndroid Build Coastguard Worker     goto end;
125*13e8728fSAndroid Build Coastguard Worker   }
126*13e8728fSAndroid Build Coastguard Worker 
127*13e8728fSAndroid Build Coastguard Worker   const char *img_filename = argv[arg_start];
128*13e8728fSAndroid Build Coastguard Worker 
129*13e8728fSAndroid Build Coastguard Worker   printf("create image file: %s...\n", img_filename);
130*13e8728fSAndroid Build Coastguard Worker 
131*13e8728fSAndroid Build Coastguard Worker   img_fp = fopen(img_filename, "wb");
132*13e8728fSAndroid Build Coastguard Worker   if (img_fp == NULL) {
133*13e8728fSAndroid Build Coastguard Worker     fprintf(stderr, "Can not create file: %s\n", img_filename);
134*13e8728fSAndroid Build Coastguard Worker     goto end;
135*13e8728fSAndroid Build Coastguard Worker   }
136*13e8728fSAndroid Build Coastguard Worker 
137*13e8728fSAndroid Build Coastguard Worker   ret = output_img_with_args(img_fp, argc, argv, arg_start + 1);
138*13e8728fSAndroid Build Coastguard Worker   if (ret < 0) fprintf(stderr, "Can not output image with args\n");
139*13e8728fSAndroid Build Coastguard Worker 
140*13e8728fSAndroid Build Coastguard Worker end:
141*13e8728fSAndroid Build Coastguard Worker   if (img_fp) {
142*13e8728fSAndroid Build Coastguard Worker     fclose(img_fp);
143*13e8728fSAndroid Build Coastguard Worker     if (ret < 0) unlink(img_filename);
144*13e8728fSAndroid Build Coastguard Worker   }
145*13e8728fSAndroid Build Coastguard Worker 
146*13e8728fSAndroid Build Coastguard Worker   return ret;
147*13e8728fSAndroid Build Coastguard Worker }
148