binman: Correct the error message for a bad hash algorithm
[platform/kernel/u-boot.git] / cmd / bootm.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000-2009
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  */
6
7 /*
8  * Boot support
9  */
10 #include <common.h>
11 #include <bootm.h>
12 #include <command.h>
13 #include <env.h>
14 #include <errno.h>
15 #include <image.h>
16 #include <malloc.h>
17 #include <nand.h>
18 #include <asm/byteorder.h>
19 #include <asm/global_data.h>
20 #include <linux/ctype.h>
21 #include <linux/err.h>
22 #include <u-boot/zlib.h>
23 #include <mapmem.h>
24
25 DECLARE_GLOBAL_DATA_PTR;
26
27 #if defined(CONFIG_CMD_IMI)
28 static int image_info(unsigned long addr);
29 #endif
30
31 #if defined(CONFIG_CMD_IMLS)
32 #include <flash.h>
33 #include <mtd/cfi_flash.h>
34 extern flash_info_t flash_info[]; /* info for FLASH chips */
35 #endif
36
37 #if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
38 static int do_imls(struct cmd_tbl *cmdtp, int flag, int argc,
39                    char *const argv[]);
40 #endif
41
42 /* we overload the cmd field with our state machine info instead of a
43  * function pointer */
44 static struct cmd_tbl cmd_bootm_sub[] = {
45         U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""),
46         U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""),
47 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
48         U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""),
49 #endif
50 #ifdef CONFIG_OF_LIBFDT
51         U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""),
52 #endif
53         U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""),
54         U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""),
55         U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""),
56         U_BOOT_CMD_MKENT(fake, 0, 1, (void *)BOOTM_STATE_OS_FAKE_GO, "", ""),
57         U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""),
58 };
59
60 static int do_bootm_subcommand(struct cmd_tbl *cmdtp, int flag, int argc,
61                                char *const argv[])
62 {
63         int ret = 0;
64         long state;
65         struct cmd_tbl *c;
66
67         c = find_cmd_tbl(argv[0], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub));
68         argc--; argv++;
69
70         if (c) {
71                 state = (long)c->cmd;
72                 if (state == BOOTM_STATE_START)
73                         state |= BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER;
74         } else {
75                 /* Unrecognized command */
76                 return CMD_RET_USAGE;
77         }
78
79         if (((state & BOOTM_STATE_START) != BOOTM_STATE_START) &&
80             images.state >= state) {
81                 printf("Trying to execute a command out of order\n");
82                 return CMD_RET_USAGE;
83         }
84
85         ret = do_bootm_states(cmdtp, flag, argc, argv, state, &images, 0);
86
87         return ret;
88 }
89
90 /*******************************************************************/
91 /* bootm - boot application image from image in memory */
92 /*******************************************************************/
93
94 int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
95 {
96 #ifdef CONFIG_NEEDS_MANUAL_RELOC
97         static int relocated = 0;
98
99         if (!relocated) {
100                 int i;
101
102                 /* relocate names of sub-command table */
103                 for (i = 0; i < ARRAY_SIZE(cmd_bootm_sub); i++)
104                         cmd_bootm_sub[i].name += gd->reloc_off;
105
106                 relocated = 1;
107         }
108 #endif
109
110         /* determine if we have a sub command */
111         argc--; argv++;
112         if (argc > 0) {
113                 char *endp;
114
115                 hextoul(argv[0], &endp);
116                 /* endp pointing to NULL means that argv[0] was just a
117                  * valid number, pass it along to the normal bootm processing
118                  *
119                  * If endp is ':' or '#' assume a FIT identifier so pass
120                  * along for normal processing.
121                  *
122                  * Right now we assume the first arg should never be '-'
123                  */
124                 if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
125                         return do_bootm_subcommand(cmdtp, flag, argc, argv);
126         }
127
128         return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
129                 BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
130                 BOOTM_STATE_LOADOS |
131 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
132                 BOOTM_STATE_RAMDISK |
133 #endif
134 #if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
135                 BOOTM_STATE_OS_CMDLINE |
136 #endif
137                 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
138                 BOOTM_STATE_OS_GO, &images, 1);
139 }
140
141 int bootm_maybe_autostart(struct cmd_tbl *cmdtp, const char *cmd)
142 {
143         if (env_get_autostart()) {
144                 char *local_args[2];
145                 local_args[0] = (char *)cmd;
146                 local_args[1] = NULL;
147                 printf("Automatic boot of image at addr 0x%08lX ...\n",
148                        image_load_addr);
149                 return do_bootm(cmdtp, 0, 1, local_args);
150         }
151
152         return 0;
153 }
154
155 #ifdef CONFIG_SYS_LONGHELP
156 static char bootm_help_text[] =
157         "[addr [arg ...]]\n    - boot application image stored in memory\n"
158         "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
159         "\t'arg' can be the address of an initrd image\n"
160 #if defined(CONFIG_OF_LIBFDT)
161         "\tWhen booting a Linux kernel which requires a flat device-tree\n"
162         "\ta third argument is required which is the address of the\n"
163         "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
164         "\tuse a '-' for the second argument. If you do not pass a third\n"
165         "\ta bd_info struct will be passed instead\n"
166 #endif
167 #if defined(CONFIG_FIT)
168         "\t\nFor the new multi component uImage format (FIT) addresses\n"
169         "\tmust be extended to include component or configuration unit name:\n"
170         "\taddr:<subimg_uname> - direct component image specification\n"
171         "\taddr#<conf_uname>   - configuration specification\n"
172         "\tUse iminfo command to get the list of existing component\n"
173         "\timages and configurations.\n"
174 #endif
175         "\nSub-commands to do part of the bootm sequence.  The sub-commands "
176         "must be\n"
177         "issued in the order below (it's ok to not issue all sub-commands):\n"
178         "\tstart [addr [arg ...]]\n"
179         "\tloados  - load OS image\n"
180 #if defined(CONFIG_SYS_BOOT_RAMDISK_HIGH)
181         "\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"
182 #endif
183 #if defined(CONFIG_OF_LIBFDT)
184         "\tfdt     - relocate flat device tree\n"
185 #endif
186         "\tcmdline - OS specific command line processing/setup\n"
187         "\tbdt     - OS specific bd_info processing\n"
188         "\tprep    - OS specific prep before relocation or go\n"
189 #if defined(CONFIG_TRACE)
190         "\tfake    - OS specific fake start without go\n"
191 #endif
192         "\tgo      - start OS";
193 #endif
194
195 U_BOOT_CMD(
196         bootm,  CONFIG_SYS_MAXARGS,     1,      do_bootm,
197         "boot application image from memory", bootm_help_text
198 );
199
200 /*******************************************************************/
201 /* bootd - boot default image */
202 /*******************************************************************/
203 #if defined(CONFIG_CMD_BOOTD)
204 int do_bootd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
205 {
206         return run_command(env_get("bootcmd"), flag);
207 }
208
209 U_BOOT_CMD(
210         boot,   1,      1,      do_bootd,
211         "boot default, i.e., run 'bootcmd'",
212         ""
213 );
214
215 /* keep old command name "bootd" for backward compatibility */
216 U_BOOT_CMD(
217         bootd, 1,       1,      do_bootd,
218         "boot default, i.e., run 'bootcmd'",
219         ""
220 );
221
222 #endif
223
224
225 /*******************************************************************/
226 /* iminfo - print header info for a requested image */
227 /*******************************************************************/
228 #if defined(CONFIG_CMD_IMI)
229 static int do_iminfo(struct cmd_tbl *cmdtp, int flag, int argc,
230                      char *const argv[])
231 {
232         int     arg;
233         ulong   addr;
234         int     rcode = 0;
235
236         if (argc < 2) {
237                 return image_info(image_load_addr);
238         }
239
240         for (arg = 1; arg < argc; ++arg) {
241                 addr = hextoul(argv[arg], NULL);
242                 if (image_info(addr) != 0)
243                         rcode = 1;
244         }
245         return rcode;
246 }
247
248 static int image_info(ulong addr)
249 {
250         void *hdr = (void *)map_sysmem(addr, 0);
251
252         printf("\n## Checking Image at %08lx ...\n", addr);
253
254         switch (genimg_get_format(hdr)) {
255 #if defined(CONFIG_LEGACY_IMAGE_FORMAT)
256         case IMAGE_FORMAT_LEGACY:
257                 puts("   Legacy image found\n");
258                 if (!image_check_magic(hdr)) {
259                         puts("   Bad Magic Number\n");
260                         unmap_sysmem(hdr);
261                         return 1;
262                 }
263
264                 if (!image_check_hcrc(hdr)) {
265                         puts("   Bad Header Checksum\n");
266                         unmap_sysmem(hdr);
267                         return 1;
268                 }
269
270                 image_print_contents(hdr);
271
272                 puts("   Verifying Checksum ... ");
273                 if (!image_check_dcrc(hdr)) {
274                         puts("   Bad Data CRC\n");
275                         unmap_sysmem(hdr);
276                         return 1;
277                 }
278                 puts("OK\n");
279                 unmap_sysmem(hdr);
280                 return 0;
281 #endif
282 #if defined(CONFIG_ANDROID_BOOT_IMAGE)
283         case IMAGE_FORMAT_ANDROID:
284                 puts("   Android image found\n");
285                 android_print_contents(hdr);
286                 unmap_sysmem(hdr);
287                 return 0;
288 #endif
289 #if defined(CONFIG_FIT)
290         case IMAGE_FORMAT_FIT:
291                 puts("   FIT image found\n");
292
293                 if (fit_check_format(hdr, IMAGE_SIZE_INVAL)) {
294                         puts("Bad FIT image format!\n");
295                         unmap_sysmem(hdr);
296                         return 1;
297                 }
298
299                 fit_print_contents(hdr);
300
301                 if (!fit_all_image_verify(hdr)) {
302                         puts("Bad hash in FIT image!\n");
303                         unmap_sysmem(hdr);
304                         return 1;
305                 }
306
307                 unmap_sysmem(hdr);
308                 return 0;
309 #endif
310         default:
311                 puts("Unknown image format!\n");
312                 break;
313         }
314
315         unmap_sysmem(hdr);
316         return 1;
317 }
318
319 U_BOOT_CMD(
320         iminfo, CONFIG_SYS_MAXARGS,     1,      do_iminfo,
321         "print header information for application image",
322         "addr [addr ...]\n"
323         "    - print header information for application image starting at\n"
324         "      address 'addr' in memory; this includes verification of the\n"
325         "      image contents (magic number, header and payload checksums)"
326 );
327 #endif
328
329
330 /*******************************************************************/
331 /* imls - list all images found in flash */
332 /*******************************************************************/
333 #if defined(CONFIG_CMD_IMLS)
334 static int do_imls_nor(void)
335 {
336         flash_info_t *info;
337         int i, j;
338         void *hdr;
339
340         for (i = 0, info = &flash_info[0];
341                 i < CFI_FLASH_BANKS; ++i, ++info) {
342
343                 if (info->flash_id == FLASH_UNKNOWN)
344                         goto next_bank;
345                 for (j = 0; j < info->sector_count; ++j) {
346
347                         hdr = (void *)info->start[j];
348                         if (!hdr)
349                                 goto next_sector;
350
351                         switch (genimg_get_format(hdr)) {
352 #if defined(CONFIG_LEGACY_IMAGE_FORMAT)
353                         case IMAGE_FORMAT_LEGACY:
354                                 if (!image_check_hcrc(hdr))
355                                         goto next_sector;
356
357                                 printf("Legacy Image at %08lX:\n", (ulong)hdr);
358                                 image_print_contents(hdr);
359
360                                 puts("   Verifying Checksum ... ");
361                                 if (!image_check_dcrc(hdr)) {
362                                         puts("Bad Data CRC\n");
363                                 } else {
364                                         puts("OK\n");
365                                 }
366                                 break;
367 #endif
368 #if defined(CONFIG_FIT)
369                         case IMAGE_FORMAT_FIT:
370                                 if (fit_check_format(hdr, IMAGE_SIZE_INVAL))
371                                         goto next_sector;
372
373                                 printf("FIT Image at %08lX:\n", (ulong)hdr);
374                                 fit_print_contents(hdr);
375                                 break;
376 #endif
377                         default:
378                                 goto next_sector;
379                         }
380
381 next_sector:            ;
382                 }
383 next_bank:      ;
384         }
385         return 0;
386 }
387 #endif
388
389 #if defined(CONFIG_CMD_IMLS_NAND)
390 static int nand_imls_legacyimage(struct mtd_info *mtd, int nand_dev,
391                                  loff_t off, size_t len)
392 {
393         void *imgdata;
394         int ret;
395
396         imgdata = malloc(len);
397         if (!imgdata) {
398                 printf("May be a Legacy Image at NAND device %d offset %08llX:\n",
399                                 nand_dev, off);
400                 printf("   Low memory(cannot allocate memory for image)\n");
401                 return -ENOMEM;
402         }
403
404         ret = nand_read_skip_bad(mtd, off, &len, NULL, mtd->size, imgdata);
405         if (ret < 0 && ret != -EUCLEAN) {
406                 free(imgdata);
407                 return ret;
408         }
409
410         if (!image_check_hcrc(imgdata)) {
411                 free(imgdata);
412                 return 0;
413         }
414
415         printf("Legacy Image at NAND device %d offset %08llX:\n",
416                         nand_dev, off);
417         image_print_contents(imgdata);
418
419         puts("   Verifying Checksum ... ");
420         if (!image_check_dcrc(imgdata))
421                 puts("Bad Data CRC\n");
422         else
423                 puts("OK\n");
424
425         free(imgdata);
426
427         return 0;
428 }
429
430 static int nand_imls_fitimage(struct mtd_info *mtd, int nand_dev, loff_t off,
431                               size_t len)
432 {
433         void *imgdata;
434         int ret;
435
436         imgdata = malloc(len);
437         if (!imgdata) {
438                 printf("May be a FIT Image at NAND device %d offset %08llX:\n",
439                                 nand_dev, off);
440                 printf("   Low memory(cannot allocate memory for image)\n");
441                 return -ENOMEM;
442         }
443
444         ret = nand_read_skip_bad(mtd, off, &len, NULL, mtd->size, imgdata);
445         if (ret < 0 && ret != -EUCLEAN) {
446                 free(imgdata);
447                 return ret;
448         }
449
450         if (fit_check_format(imgdata, IMAGE_SIZE_INVAL)) {
451                 free(imgdata);
452                 return 0;
453         }
454
455         printf("FIT Image at NAND device %d offset %08llX:\n", nand_dev, off);
456
457         fit_print_contents(imgdata);
458         free(imgdata);
459
460         return 0;
461 }
462
463 static int do_imls_nand(void)
464 {
465         struct mtd_info *mtd;
466         int nand_dev = nand_curr_device;
467         size_t len;
468         loff_t off;
469         u32 buffer[16];
470
471         if (nand_dev < 0 || nand_dev >= CONFIG_SYS_MAX_NAND_DEVICE) {
472                 puts("\nNo NAND devices available\n");
473                 return -ENODEV;
474         }
475
476         printf("\n");
477
478         for (nand_dev = 0; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE; nand_dev++) {
479                 mtd = get_nand_dev_by_index(nand_dev);
480                 if (!mtd->name || !mtd->size)
481                         continue;
482
483                 for (off = 0; off < mtd->size; off += mtd->erasesize) {
484                         const image_header_t *header;
485                         int ret;
486
487                         if (nand_block_isbad(mtd, off))
488                                 continue;
489
490                         len = sizeof(buffer);
491
492                         ret = nand_read(mtd, off, &len, (u8 *)buffer);
493                         if (ret < 0 && ret != -EUCLEAN) {
494                                 printf("NAND read error %d at offset %08llX\n",
495                                                 ret, off);
496                                 continue;
497                         }
498
499                         switch (genimg_get_format(buffer)) {
500 #if defined(CONFIG_LEGACY_IMAGE_FORMAT)
501                         case IMAGE_FORMAT_LEGACY:
502                                 header = (const image_header_t *)buffer;
503
504                                 len = image_get_image_size(header);
505                                 nand_imls_legacyimage(mtd, nand_dev, off, len);
506                                 break;
507 #endif
508 #if defined(CONFIG_FIT)
509                         case IMAGE_FORMAT_FIT:
510                                 len = fit_get_size(buffer);
511                                 nand_imls_fitimage(mtd, nand_dev, off, len);
512                                 break;
513 #endif
514                         }
515                 }
516         }
517
518         return 0;
519 }
520 #endif
521
522 #if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
523 static int do_imls(struct cmd_tbl *cmdtp, int flag, int argc,
524                    char *const argv[])
525 {
526         int ret_nor = 0, ret_nand = 0;
527
528 #if defined(CONFIG_CMD_IMLS)
529         ret_nor = do_imls_nor();
530 #endif
531
532 #if defined(CONFIG_CMD_IMLS_NAND)
533         ret_nand = do_imls_nand();
534 #endif
535
536         if (ret_nor)
537                 return ret_nor;
538
539         if (ret_nand)
540                 return ret_nand;
541
542         return (0);
543 }
544
545 U_BOOT_CMD(
546         imls,   1,              1,      do_imls,
547         "list all images found in flash",
548         "\n"
549         "    - Prints information about all images found at sector/block\n"
550         "      boundaries in nor/nand flash."
551 );
552 #endif