"Das U-Boot" Source Tree
at master 184 lines 4.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2011 4 * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> 5 */ 6 7#include <command.h> 8#include <cmd_spl.h> 9#include <env.h> 10#include <image.h> 11#include <log.h> 12#include <asm/global_data.h> 13#include <linux/libfdt.h> 14 15DECLARE_GLOBAL_DATA_PTR; 16 17static const char **subcmd_list[] = { 18 19 [SPL_EXPORT_FDT] = (const char * []) { 20#ifdef CONFIG_OF_LIBFDT 21 "start", 22 "loados", 23 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 24 "ramdisk", 25 #endif 26 "fdt", 27 "cmdline", 28 "bdt", 29 "prep", 30#endif 31 NULL, 32 }, 33 [SPL_EXPORT_ATAGS] = (const char * []) { 34#ifdef CONFIG_SUPPORT_PASSING_ATAGS 35 "start", 36 "loados", 37#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH 38 "ramdisk", 39#endif 40 "cmdline", 41 "bdt", 42 "prep", 43#endif 44 NULL, 45 }, 46 NULL 47}; 48 49/* Calls bootm with the parameters given */ 50static int call_bootm(int argc, char *const argv[], const char *subcommand[]) 51{ 52 char *bootm_argv[5]; 53 54 int i = 0; 55 int ret = 0; 56 int j; 57 58 /* create paramter array */ 59 bootm_argv[0] = "do_bootm"; 60 switch (argc) { 61 case 3: 62 bootm_argv[4] = argv[2]; /* fdt addr */ 63 case 2: 64 bootm_argv[3] = argv[1]; /* initrd addr */ 65 case 1: 66 bootm_argv[2] = argv[0]; /* kernel addr */ 67 } 68 69 /* 70 * - do the work - 71 * exec subcommands of do_bootm to init the images 72 * data structure 73 */ 74 while (subcommand[i] != NULL) { 75 bootm_argv[1] = (char *)subcommand[i]; 76 debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]); 77 for (j = 0; j < argc; j++) 78 debug("%s ", bootm_argv[j + 2]); 79 debug("\n"); 80 81 ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, 82 bootm_argv); 83 debug("Subcommand retcode: %d\n", ret); 84 i++; 85 } 86 87 if (ret) { 88 printf("ERROR prep subcommand failed!\n"); 89 return -1; 90 } 91 92 return 0; 93} 94 95static struct cmd_tbl cmd_spl_export_sub[] = { 96 U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), 97 U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), 98}; 99 100static int spl_export(struct cmd_tbl *cmdtp, int flag, int argc, 101 char *const argv[]) 102{ 103 const struct cmd_tbl *c; 104 105 if (argc < 2) /* no subcommand */ 106 return cmd_usage(cmdtp); 107 108 c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], 109 ARRAY_SIZE(cmd_spl_export_sub)); 110 if ((c) && ((long)c->cmd <= SPL_EXPORT_LAST)) { 111 argc -= 2; 112 argv += 2; 113 if (call_bootm(argc, argv, subcmd_list[(long)c->cmd])) 114 return -1; 115 switch ((long)c->cmd) { 116#ifdef CONFIG_OF_LIBFDT 117 case SPL_EXPORT_FDT: 118 printf("Argument image is now in RAM: 0x%p\n", 119 (void *)images.ft_addr); 120 env_set_addr("fdtargsaddr", images.ft_addr); 121 env_set_hex("fdtargslen", fdt_totalsize(images.ft_addr)); 122#ifdef CONFIG_CMD_SPL_WRITE_SIZE 123 if (fdt_totalsize(images.ft_addr) > 124 CONFIG_CMD_SPL_WRITE_SIZE) 125 puts("WARN: FDT size > CMD_SPL_WRITE_SIZE\n"); 126#endif 127 break; 128#endif 129 case SPL_EXPORT_ATAGS: 130 printf("Argument image is now in RAM at: 0x%p\n", 131 (void *)gd->bd->bi_boot_params); 132 break; 133 } 134 } else { 135 /* Unrecognized command */ 136 return cmd_usage(cmdtp); 137 } 138 139 return 0; 140} 141 142static struct cmd_tbl cmd_spl_sub[] = { 143 U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), 144}; 145 146static int do_spl(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 147{ 148 const struct cmd_tbl *c; 149 int cmd; 150 151 if (argc < 2) /* no subcommand */ 152 return cmd_usage(cmdtp); 153 154 c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); 155 if (c) { 156 cmd = (long)c->cmd; 157 switch (cmd) { 158 case SPL_EXPORT: 159 argc--; 160 argv++; 161 if (spl_export(cmdtp, flag, argc, argv)) 162 printf("Subcommand failed\n"); 163 break; 164 default: 165 /* unrecognized command */ 166 return cmd_usage(cmdtp); 167 } 168 } else { 169 /* Unrecognized command */ 170 return cmd_usage(cmdtp); 171 } 172 return 0; 173} 174 175U_BOOT_CMD( 176 spl, 6 , 1, do_spl, "SPL configuration", 177 "export <img=atags|fdt> [kernel_addr] [initrd_addr] [fdt_addr]\n" 178 "\timg\t\t\"atags\" or \"fdt\"\n" 179 "\tkernel_addr\taddress where a kernel image is stored.\n" 180 "\t\t\tkernel is loaded as part of the boot process, but it is not started.\n" 181 "\tinitrd_addr\taddress of initial ramdisk\n" 182 "\t\t\tcan be set to \"-\" if fdt_addr without initrd_addr is used.\n" 183 "\tfdt_addr\tin case of fdt, the address of the device tree.\n" 184 );