Commit 66ded17dfc8110f0d9aa9d50fe140a320bfa4e53

Authored by Simon Glass
Committed by Tom Rini
1 parent e1bf824dfd

Move autoboot code to autoboot.c

The autoboot code is complex and long. It deserves its own file with
a simple interface from main.c.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 4 changed files with 393 additions and 364 deletions Side-by-side Diff

... ... @@ -23,6 +23,11 @@
23 23 obj-y += xyzModem.o
24 24 obj-y += cmd_disk.o
25 25  
  26 +# This option is not just y/n - it can have a numeric value
  27 +ifdef CONFIG_BOOTDELAY
  28 +obj-y += autoboot.o
  29 +endif
  30 +
26 31 # boards
27 32 obj-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
28 33 obj-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * SPDX-License-Identifier: GPL-2.0+
  6 + */
  7 +
  8 +#include <common.h>
  9 +#include <cli.h>
  10 +#include <fdtdec.h>
  11 +#include <menu.h>
  12 +#include <post.h>
  13 +
  14 +DECLARE_GLOBAL_DATA_PTR;
  15 +
  16 +#define MAX_DELAY_STOP_STR 32
  17 +
  18 +#ifndef DEBUG_BOOTKEYS
  19 +#define DEBUG_BOOTKEYS 0
  20 +#endif
  21 +#define debug_bootkeys(fmt, args...) \
  22 + debug_cond(DEBUG_BOOTKEYS, fmt, ##args)
  23 +
  24 +/***************************************************************************
  25 + * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
  26 + * returns: 0 - no key string, allow autoboot 1 - got key string, abort
  27 + */
  28 +# if defined(CONFIG_AUTOBOOT_KEYED)
  29 +static int abortboot_keyed(int bootdelay)
  30 +{
  31 + int abort = 0;
  32 + uint64_t etime = endtick(bootdelay);
  33 + struct {
  34 + char *str;
  35 + u_int len;
  36 + int retry;
  37 + }
  38 + delaykey[] = {
  39 + { str: getenv("bootdelaykey"), retry: 1 },
  40 + { str: getenv("bootdelaykey2"), retry: 1 },
  41 + { str: getenv("bootstopkey"), retry: 0 },
  42 + { str: getenv("bootstopkey2"), retry: 0 },
  43 + };
  44 +
  45 + char presskey[MAX_DELAY_STOP_STR];
  46 + u_int presskey_len = 0;
  47 + u_int presskey_max = 0;
  48 + u_int i;
  49 +
  50 +#ifndef CONFIG_ZERO_BOOTDELAY_CHECK
  51 + if (bootdelay == 0)
  52 + return 0;
  53 +#endif
  54 +
  55 +# ifdef CONFIG_AUTOBOOT_PROMPT
  56 + printf(CONFIG_AUTOBOOT_PROMPT);
  57 +# endif
  58 +
  59 +# ifdef CONFIG_AUTOBOOT_DELAY_STR
  60 + if (delaykey[0].str == NULL)
  61 + delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;
  62 +# endif
  63 +# ifdef CONFIG_AUTOBOOT_DELAY_STR2
  64 + if (delaykey[1].str == NULL)
  65 + delaykey[1].str = CONFIG_AUTOBOOT_DELAY_STR2;
  66 +# endif
  67 +# ifdef CONFIG_AUTOBOOT_STOP_STR
  68 + if (delaykey[2].str == NULL)
  69 + delaykey[2].str = CONFIG_AUTOBOOT_STOP_STR;
  70 +# endif
  71 +# ifdef CONFIG_AUTOBOOT_STOP_STR2
  72 + if (delaykey[3].str == NULL)
  73 + delaykey[3].str = CONFIG_AUTOBOOT_STOP_STR2;
  74 +# endif
  75 +
  76 + for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i++) {
  77 + delaykey[i].len = delaykey[i].str == NULL ?
  78 + 0 : strlen(delaykey[i].str);
  79 + delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ?
  80 + MAX_DELAY_STOP_STR : delaykey[i].len;
  81 +
  82 + presskey_max = presskey_max > delaykey[i].len ?
  83 + presskey_max : delaykey[i].len;
  84 +
  85 + debug_bootkeys("%s key:<%s>\n",
  86 + delaykey[i].retry ? "delay" : "stop",
  87 + delaykey[i].str ? delaykey[i].str : "NULL");
  88 + }
  89 +
  90 + /* In order to keep up with incoming data, check timeout only
  91 + * when catch up.
  92 + */
  93 + do {
  94 + if (tstc()) {
  95 + if (presskey_len < presskey_max) {
  96 + presskey[presskey_len++] = getc();
  97 + } else {
  98 + for (i = 0; i < presskey_max - 1; i++)
  99 + presskey[i] = presskey[i + 1];
  100 +
  101 + presskey[i] = getc();
  102 + }
  103 + }
  104 +
  105 + for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i++) {
  106 + if (delaykey[i].len > 0 &&
  107 + presskey_len >= delaykey[i].len &&
  108 + memcmp(presskey + presskey_len -
  109 + delaykey[i].len, delaykey[i].str,
  110 + delaykey[i].len) == 0) {
  111 + debug_bootkeys("got %skey\n",
  112 + delaykey[i].retry ? "delay" :
  113 + "stop");
  114 +
  115 +# ifdef CONFIG_BOOT_RETRY_TIME
  116 + /* don't retry auto boot */
  117 + if (!delaykey[i].retry)
  118 + bootretry_dont_retry();
  119 +# endif
  120 + abort = 1;
  121 + }
  122 + }
  123 + } while (!abort && get_ticks() <= etime);
  124 +
  125 + if (!abort)
  126 + debug_bootkeys("key timeout\n");
  127 +
  128 +#ifdef CONFIG_SILENT_CONSOLE
  129 + if (abort)
  130 + gd->flags &= ~GD_FLG_SILENT;
  131 +#endif
  132 +
  133 + return abort;
  134 +}
  135 +
  136 +# else /* !defined(CONFIG_AUTOBOOT_KEYED) */
  137 +
  138 +#ifdef CONFIG_MENUKEY
  139 +static int menukey;
  140 +#endif
  141 +
  142 +static int abortboot_normal(int bootdelay)
  143 +{
  144 + int abort = 0;
  145 + unsigned long ts;
  146 +
  147 +#ifdef CONFIG_MENUPROMPT
  148 + printf(CONFIG_MENUPROMPT);
  149 +#else
  150 + if (bootdelay >= 0)
  151 + printf("Hit any key to stop autoboot: %2d ", bootdelay);
  152 +#endif
  153 +
  154 +#if defined CONFIG_ZERO_BOOTDELAY_CHECK
  155 + /*
  156 + * Check if key already pressed
  157 + * Don't check if bootdelay < 0
  158 + */
  159 + if (bootdelay >= 0) {
  160 + if (tstc()) { /* we got a key press */
  161 + (void) getc(); /* consume input */
  162 + puts("\b\b\b 0");
  163 + abort = 1; /* don't auto boot */
  164 + }
  165 + }
  166 +#endif
  167 +
  168 + while ((bootdelay > 0) && (!abort)) {
  169 + --bootdelay;
  170 + /* delay 1000 ms */
  171 + ts = get_timer(0);
  172 + do {
  173 + if (tstc()) { /* we got a key press */
  174 + abort = 1; /* don't auto boot */
  175 + bootdelay = 0; /* no more delay */
  176 +# ifdef CONFIG_MENUKEY
  177 + menukey = getc();
  178 +# else
  179 + (void) getc(); /* consume input */
  180 +# endif
  181 + break;
  182 + }
  183 + udelay(10000);
  184 + } while (!abort && get_timer(ts) < 1000);
  185 +
  186 + printf("\b\b\b%2d ", bootdelay);
  187 + }
  188 +
  189 + putc('\n');
  190 +
  191 +#ifdef CONFIG_SILENT_CONSOLE
  192 + if (abort)
  193 + gd->flags &= ~GD_FLG_SILENT;
  194 +#endif
  195 +
  196 + return abort;
  197 +}
  198 +# endif /* CONFIG_AUTOBOOT_KEYED */
  199 +
  200 +static int abortboot(int bootdelay)
  201 +{
  202 +#ifdef CONFIG_AUTOBOOT_KEYED
  203 + return abortboot_keyed(bootdelay);
  204 +#else
  205 + return abortboot_normal(bootdelay);
  206 +#endif
  207 +}
  208 +
  209 +/*
  210 + * Runs the given boot command securely. Specifically:
  211 + * - Doesn't run the command with the shell (run_command or parse_string_outer),
  212 + * since that's a lot of code surface that an attacker might exploit.
  213 + * Because of this, we don't do any argument parsing--the secure boot command
  214 + * has to be a full-fledged u-boot command.
  215 + * - Doesn't check for keypresses before booting, since that could be a
  216 + * security hole; also disables Ctrl-C.
  217 + * - Doesn't allow the command to return.
  218 + *
  219 + * Upon any failures, this function will drop into an infinite loop after
  220 + * printing the error message to console.
  221 + */
  222 +
  223 +#if defined(CONFIG_OF_CONTROL)
  224 +static void secure_boot_cmd(char *cmd)
  225 +{
  226 + cmd_tbl_t *cmdtp;
  227 + int rc;
  228 +
  229 + if (!cmd) {
  230 + printf("## Error: Secure boot command not specified\n");
  231 + goto err;
  232 + }
  233 +
  234 + /* Disable Ctrl-C just in case some command is used that checks it. */
  235 + disable_ctrlc(1);
  236 +
  237 + /* Find the command directly. */
  238 + cmdtp = find_cmd(cmd);
  239 + if (!cmdtp) {
  240 + printf("## Error: \"%s\" not defined\n", cmd);
  241 + goto err;
  242 + }
  243 +
  244 + /* Run the command, forcing no flags and faking argc and argv. */
  245 + rc = (cmdtp->cmd)(cmdtp, 0, 1, &cmd);
  246 +
  247 + /* Shouldn't ever return from boot command. */
  248 + printf("## Error: \"%s\" returned (code %d)\n", cmd, rc);
  249 +
  250 +err:
  251 + /*
  252 + * Not a whole lot to do here. Rebooting won't help much, since we'll
  253 + * just end up right back here. Just loop.
  254 + */
  255 + hang();
  256 +}
  257 +
  258 +static void process_fdt_options(const void *blob)
  259 +{
  260 + ulong addr;
  261 +
  262 + /* Add an env variable to point to a kernel payload, if available */
  263 + addr = fdtdec_get_config_int(gd->fdt_blob, "kernel-offset", 0);
  264 + if (addr)
  265 + setenv_addr("kernaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
  266 +
  267 + /* Add an env variable to point to a root disk, if available */
  268 + addr = fdtdec_get_config_int(gd->fdt_blob, "rootdisk-offset", 0);
  269 + if (addr)
  270 + setenv_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
  271 +}
  272 +#endif /* CONFIG_OF_CONTROL */
  273 +
  274 +void bootdelay_process(void)
  275 +{
  276 +#ifdef CONFIG_OF_CONTROL
  277 + char *env;
  278 +#endif
  279 + char *s;
  280 + int bootdelay;
  281 +#ifdef CONFIG_BOOTCOUNT_LIMIT
  282 + unsigned long bootcount = 0;
  283 + unsigned long bootlimit = 0;
  284 +#endif /* CONFIG_BOOTCOUNT_LIMIT */
  285 +
  286 +#ifdef CONFIG_BOOTCOUNT_LIMIT
  287 + bootcount = bootcount_load();
  288 + bootcount++;
  289 + bootcount_store(bootcount);
  290 + setenv_ulong("bootcount", bootcount);
  291 + bootlimit = getenv_ulong("bootlimit", 10, 0);
  292 +#endif /* CONFIG_BOOTCOUNT_LIMIT */
  293 +
  294 + s = getenv("bootdelay");
  295 + bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
  296 +
  297 +#ifdef CONFIG_OF_CONTROL
  298 + bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
  299 + bootdelay);
  300 +#endif
  301 +
  302 + debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);
  303 +
  304 +#if defined(CONFIG_MENU_SHOW)
  305 + bootdelay = menu_show(bootdelay);
  306 +#endif
  307 +# ifdef CONFIG_BOOT_RETRY_TIME
  308 + init_cmd_timeout();
  309 +# endif /* CONFIG_BOOT_RETRY_TIME */
  310 +
  311 +#ifdef CONFIG_POST
  312 + if (gd->flags & GD_FLG_POSTFAIL) {
  313 + s = getenv("failbootcmd");
  314 + } else
  315 +#endif /* CONFIG_POST */
  316 +#ifdef CONFIG_BOOTCOUNT_LIMIT
  317 + if (bootlimit && (bootcount > bootlimit)) {
  318 + printf("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
  319 + (unsigned)bootlimit);
  320 + s = getenv("altbootcmd");
  321 + } else
  322 +#endif /* CONFIG_BOOTCOUNT_LIMIT */
  323 + s = getenv("bootcmd");
  324 +#ifdef CONFIG_OF_CONTROL
  325 + /* Allow the fdt to override the boot command */
  326 + env = fdtdec_get_config_string(gd->fdt_blob, "bootcmd");
  327 + if (env)
  328 + s = env;
  329 +
  330 + process_fdt_options(gd->fdt_blob);
  331 +
  332 + /*
  333 + * If the bootsecure option was chosen, use secure_boot_cmd().
  334 + * Always use 'env' in this case, since bootsecure requres that the
  335 + * bootcmd was specified in the FDT too.
  336 + */
  337 + if (fdtdec_get_config_int(gd->fdt_blob, "bootsecure", 0))
  338 + secure_boot_cmd(env);
  339 +
  340 +#endif /* CONFIG_OF_CONTROL */
  341 +
  342 + debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
  343 +
  344 + if (bootdelay != -1 && s && !abortboot(bootdelay)) {
  345 +#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
  346 + int prev = disable_ctrlc(1); /* disable Control C checking */
  347 +#endif
  348 +
  349 + run_command_list(s, -1, 0);
  350 +
  351 +#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
  352 + disable_ctrlc(prev); /* restore Control C checking */
  353 +#endif
  354 + }
  355 +
  356 +#ifdef CONFIG_MENUKEY
  357 + if (menukey == CONFIG_MENUKEY) {
  358 + s = getenv("menucmd");
  359 + if (s)
  360 + run_command_list(s, -1, 0);
  361 + }
  362 +#endif /* CONFIG_MENUKEY */
  363 +}
... ... @@ -8,384 +8,24 @@
8 8 /* #define DEBUG */
9 9  
10 10 #include <common.h>
  11 +#include <autoboot.h>
11 12 #include <cli.h>
12 13 #include <command.h>
13   -#include <fdtdec.h>
14 14 #include <cli_hush.h>
15 15 #include <malloc.h>
16   -#include <menu.h>
17   -#include <post.h>
18 16 #include <version.h>
19 17  
20   -DECLARE_GLOBAL_DATA_PTR;
21   -
22 18 /*
23 19 * Board-specific Platform code can reimplement show_boot_progress () if needed
24 20 */
25 21 void inline __show_boot_progress (int val) {}
26 22 void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
27 23  
28   -#define MAX_DELAY_STOP_STR 32
29   -
30   -#ifndef DEBUG_BOOTKEYS
31   -#define DEBUG_BOOTKEYS 0
32   -#endif
33   -#define debug_bootkeys(fmt, args...) \
34   - debug_cond(DEBUG_BOOTKEYS, fmt, ##args)
35   -
36 24 #ifdef CONFIG_MODEM_SUPPORT
37 25 int do_mdm_init = 0;
38 26 extern void mdm_init(void); /* defined in board.c */
39 27 #endif
40 28  
41   -/***************************************************************************
42   - * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
43   - * returns: 0 - no key string, allow autoboot 1 - got key string, abort
44   - */
45   -#if defined(CONFIG_BOOTDELAY)
46   -# if defined(CONFIG_AUTOBOOT_KEYED)
47   -static int abortboot_keyed(int bootdelay)
48   -{
49   - int abort = 0;
50   - uint64_t etime = endtick(bootdelay);
51   - struct {
52   - char* str;
53   - u_int len;
54   - int retry;
55   - }
56   - delaykey [] = {
57   - { str: getenv ("bootdelaykey"), retry: 1 },
58   - { str: getenv ("bootdelaykey2"), retry: 1 },
59   - { str: getenv ("bootstopkey"), retry: 0 },
60   - { str: getenv ("bootstopkey2"), retry: 0 },
61   - };
62   -
63   - char presskey [MAX_DELAY_STOP_STR];
64   - u_int presskey_len = 0;
65   - u_int presskey_max = 0;
66   - u_int i;
67   -
68   -#ifndef CONFIG_ZERO_BOOTDELAY_CHECK
69   - if (bootdelay == 0)
70   - return 0;
71   -#endif
72   -
73   -# ifdef CONFIG_AUTOBOOT_PROMPT
74   - printf(CONFIG_AUTOBOOT_PROMPT);
75   -# endif
76   -
77   -# ifdef CONFIG_AUTOBOOT_DELAY_STR
78   - if (delaykey[0].str == NULL)
79   - delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;
80   -# endif
81   -# ifdef CONFIG_AUTOBOOT_DELAY_STR2
82   - if (delaykey[1].str == NULL)
83   - delaykey[1].str = CONFIG_AUTOBOOT_DELAY_STR2;
84   -# endif
85   -# ifdef CONFIG_AUTOBOOT_STOP_STR
86   - if (delaykey[2].str == NULL)
87   - delaykey[2].str = CONFIG_AUTOBOOT_STOP_STR;
88   -# endif
89   -# ifdef CONFIG_AUTOBOOT_STOP_STR2
90   - if (delaykey[3].str == NULL)
91   - delaykey[3].str = CONFIG_AUTOBOOT_STOP_STR2;
92   -# endif
93   -
94   - for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
95   - delaykey[i].len = delaykey[i].str == NULL ?
96   - 0 : strlen (delaykey[i].str);
97   - delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ?
98   - MAX_DELAY_STOP_STR : delaykey[i].len;
99   -
100   - presskey_max = presskey_max > delaykey[i].len ?
101   - presskey_max : delaykey[i].len;
102   -
103   - debug_bootkeys("%s key:<%s>\n",
104   - delaykey[i].retry ? "delay" : "stop",
105   - delaykey[i].str ? delaykey[i].str : "NULL");
106   - }
107   -
108   - /* In order to keep up with incoming data, check timeout only
109   - * when catch up.
110   - */
111   - do {
112   - if (tstc()) {
113   - if (presskey_len < presskey_max) {
114   - presskey [presskey_len ++] = getc();
115   - }
116   - else {
117   - for (i = 0; i < presskey_max - 1; i ++)
118   - presskey [i] = presskey [i + 1];
119   -
120   - presskey [i] = getc();
121   - }
122   - }
123   -
124   - for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {
125   - if (delaykey[i].len > 0 &&
126   - presskey_len >= delaykey[i].len &&
127   - memcmp (presskey + presskey_len - delaykey[i].len,
128   - delaykey[i].str,
129   - delaykey[i].len) == 0) {
130   - debug_bootkeys("got %skey\n",
131   - delaykey[i].retry ? "delay" :
132   - "stop");
133   -
134   -# ifdef CONFIG_BOOT_RETRY_TIME
135   - /* don't retry auto boot */
136   - if (! delaykey[i].retry)
137   - bootretry_dont_retry();
138   -# endif
139   - abort = 1;
140   - }
141   - }
142   - } while (!abort && get_ticks() <= etime);
143   -
144   - if (!abort)
145   - debug_bootkeys("key timeout\n");
146   -
147   -#ifdef CONFIG_SILENT_CONSOLE
148   - if (abort)
149   - gd->flags &= ~GD_FLG_SILENT;
150   -#endif
151   -
152   - return abort;
153   -}
154   -
155   -# else /* !defined(CONFIG_AUTOBOOT_KEYED) */
156   -
157   -#ifdef CONFIG_MENUKEY
158   -static int menukey = 0;
159   -#endif
160   -
161   -static int abortboot_normal(int bootdelay)
162   -{
163   - int abort = 0;
164   - unsigned long ts;
165   -
166   -#ifdef CONFIG_MENUPROMPT
167   - printf(CONFIG_MENUPROMPT);
168   -#else
169   - if (bootdelay >= 0)
170   - printf("Hit any key to stop autoboot: %2d ", bootdelay);
171   -#endif
172   -
173   -#if defined CONFIG_ZERO_BOOTDELAY_CHECK
174   - /*
175   - * Check if key already pressed
176   - * Don't check if bootdelay < 0
177   - */
178   - if (bootdelay >= 0) {
179   - if (tstc()) { /* we got a key press */
180   - (void) getc(); /* consume input */
181   - puts ("\b\b\b 0");
182   - abort = 1; /* don't auto boot */
183   - }
184   - }
185   -#endif
186   -
187   - while ((bootdelay > 0) && (!abort)) {
188   - --bootdelay;
189   - /* delay 1000 ms */
190   - ts = get_timer(0);
191   - do {
192   - if (tstc()) { /* we got a key press */
193   - abort = 1; /* don't auto boot */
194   - bootdelay = 0; /* no more delay */
195   -# ifdef CONFIG_MENUKEY
196   - menukey = getc();
197   -# else
198   - (void) getc(); /* consume input */
199   -# endif
200   - break;
201   - }
202   - udelay(10000);
203   - } while (!abort && get_timer(ts) < 1000);
204   -
205   - printf("\b\b\b%2d ", bootdelay);
206   - }
207   -
208   - putc('\n');
209   -
210   -#ifdef CONFIG_SILENT_CONSOLE
211   - if (abort)
212   - gd->flags &= ~GD_FLG_SILENT;
213   -#endif
214   -
215   - return abort;
216   -}
217   -# endif /* CONFIG_AUTOBOOT_KEYED */
218   -
219   -static int abortboot(int bootdelay)
220   -{
221   -#ifdef CONFIG_AUTOBOOT_KEYED
222   - return abortboot_keyed(bootdelay);
223   -#else
224   - return abortboot_normal(bootdelay);
225   -#endif
226   -}
227   -#endif /* CONFIG_BOOTDELAY */
228   -
229   -/*
230   - * Runs the given boot command securely. Specifically:
231   - * - Doesn't run the command with the shell (run_command or parse_string_outer),
232   - * since that's a lot of code surface that an attacker might exploit.
233   - * Because of this, we don't do any argument parsing--the secure boot command
234   - * has to be a full-fledged u-boot command.
235   - * - Doesn't check for keypresses before booting, since that could be a
236   - * security hole; also disables Ctrl-C.
237   - * - Doesn't allow the command to return.
238   - *
239   - * Upon any failures, this function will drop into an infinite loop after
240   - * printing the error message to console.
241   - */
242   -
243   -#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL)
244   -static void secure_boot_cmd(char *cmd)
245   -{
246   - cmd_tbl_t *cmdtp;
247   - int rc;
248   -
249   - if (!cmd) {
250   - printf("## Error: Secure boot command not specified\n");
251   - goto err;
252   - }
253   -
254   - /* Disable Ctrl-C just in case some command is used that checks it. */
255   - disable_ctrlc(1);
256   -
257   - /* Find the command directly. */
258   - cmdtp = find_cmd(cmd);
259   - if (!cmdtp) {
260   - printf("## Error: \"%s\" not defined\n", cmd);
261   - goto err;
262   - }
263   -
264   - /* Run the command, forcing no flags and faking argc and argv. */
265   - rc = (cmdtp->cmd)(cmdtp, 0, 1, &cmd);
266   -
267   - /* Shouldn't ever return from boot command. */
268   - printf("## Error: \"%s\" returned (code %d)\n", cmd, rc);
269   -
270   -err:
271   - /*
272   - * Not a whole lot to do here. Rebooting won't help much, since we'll
273   - * just end up right back here. Just loop.
274   - */
275   - hang();
276   -}
277   -
278   -static void process_fdt_options(const void *blob)
279   -{
280   - ulong addr;
281   -
282   - /* Add an env variable to point to a kernel payload, if available */
283   - addr = fdtdec_get_config_int(gd->fdt_blob, "kernel-offset", 0);
284   - if (addr)
285   - setenv_addr("kernaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
286   -
287   - /* Add an env variable to point to a root disk, if available */
288   - addr = fdtdec_get_config_int(gd->fdt_blob, "rootdisk-offset", 0);
289   - if (addr)
290   - setenv_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
291   -}
292   -#endif /* CONFIG_OF_CONTROL */
293   -
294   -#ifdef CONFIG_BOOTDELAY
295   -static void process_boot_delay(void)
296   -{
297   -#ifdef CONFIG_OF_CONTROL
298   - char *env;
299   -#endif
300   - char *s;
301   - int bootdelay;
302   -#ifdef CONFIG_BOOTCOUNT_LIMIT
303   - unsigned long bootcount = 0;
304   - unsigned long bootlimit = 0;
305   -#endif /* CONFIG_BOOTCOUNT_LIMIT */
306   -
307   -#ifdef CONFIG_BOOTCOUNT_LIMIT
308   - bootcount = bootcount_load();
309   - bootcount++;
310   - bootcount_store (bootcount);
311   - setenv_ulong("bootcount", bootcount);
312   - bootlimit = getenv_ulong("bootlimit", 10, 0);
313   -#endif /* CONFIG_BOOTCOUNT_LIMIT */
314   -
315   - s = getenv ("bootdelay");
316   - bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
317   -
318   -#ifdef CONFIG_OF_CONTROL
319   - bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
320   - bootdelay);
321   -#endif
322   -
323   - debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
324   -
325   -#if defined(CONFIG_MENU_SHOW)
326   - bootdelay = menu_show(bootdelay);
327   -#endif
328   -# ifdef CONFIG_BOOT_RETRY_TIME
329   - init_cmd_timeout ();
330   -# endif /* CONFIG_BOOT_RETRY_TIME */
331   -
332   -#ifdef CONFIG_POST
333   - if (gd->flags & GD_FLG_POSTFAIL) {
334   - s = getenv("failbootcmd");
335   - }
336   - else
337   -#endif /* CONFIG_POST */
338   -#ifdef CONFIG_BOOTCOUNT_LIMIT
339   - if (bootlimit && (bootcount > bootlimit)) {
340   - printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
341   - (unsigned)bootlimit);
342   - s = getenv ("altbootcmd");
343   - }
344   - else
345   -#endif /* CONFIG_BOOTCOUNT_LIMIT */
346   - s = getenv ("bootcmd");
347   -#ifdef CONFIG_OF_CONTROL
348   - /* Allow the fdt to override the boot command */
349   - env = fdtdec_get_config_string(gd->fdt_blob, "bootcmd");
350   - if (env)
351   - s = env;
352   -
353   - process_fdt_options(gd->fdt_blob);
354   -
355   - /*
356   - * If the bootsecure option was chosen, use secure_boot_cmd().
357   - * Always use 'env' in this case, since bootsecure requres that the
358   - * bootcmd was specified in the FDT too.
359   - */
360   - if (fdtdec_get_config_int(gd->fdt_blob, "bootsecure", 0))
361   - secure_boot_cmd(env);
362   -
363   -#endif /* CONFIG_OF_CONTROL */
364   -
365   - debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
366   -
367   - if (bootdelay != -1 && s && !abortboot(bootdelay)) {
368   -#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
369   - int prev = disable_ctrlc(1); /* disable Control C checking */
370   -#endif
371   -
372   - run_command_list(s, -1, 0);
373   -
374   -#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
375   - disable_ctrlc(prev); /* restore Control C checking */
376   -#endif
377   - }
378   -
379   -#ifdef CONFIG_MENUKEY
380   - if (menukey == CONFIG_MENUKEY) {
381   - s = getenv("menucmd");
382   - if (s)
383   - run_command_list(s, -1, 0);
384   - }
385   -#endif /* CONFIG_MENUKEY */
386   -}
387   -#endif /* CONFIG_BOOTDELAY */
388   -
389 29 void main_loop(void)
390 30 {
391 31 #ifdef CONFIG_PREBOOT
... ... @@ -444,9 +84,7 @@
444 84 update_tftp(0UL);
445 85 #endif /* CONFIG_UPDATE_TFTP */
446 86  
447   -#ifdef CONFIG_BOOTDELAY
448   - process_boot_delay();
449   -#endif
  87 + bootdelay_process();
450 88 /*
451 89 * Main Loop for Monitor Command Processing
452 90 */
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * Add to readline cmdline-editing by
  6 + * (C) Copyright 2005
  7 + * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com>
  8 + *
  9 + * SPDX-License-Identifier: GPL-2.0+
  10 + */
  11 +
  12 +#ifndef __AUTOBOOT_H
  13 +#define __AUTOBOOT_H
  14 +
  15 +#ifdef CONFIG_BOOTDELAY
  16 +void bootdelay_process(void);
  17 +#else
  18 +static inline void bootdelay_process(void)
  19 +{
  20 +}
  21 +#endif
  22 +
  23 +#endif