Blame view
common/autoboot.c
9.45 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
66ded17df Move autoboot cod... |
2 3 4 |
/* * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
66ded17df Move autoboot cod... |
5 6 7 |
*/ #include <common.h> |
39e1230ed autoboot: add its... |
8 |
#include <autoboot.h> |
0098e179e Move bootretry co... |
9 |
#include <bootretry.h> |
66ded17df Move autoboot cod... |
10 |
#include <cli.h> |
288b29e44 common: Move comm... |
11 |
#include <command.h> |
24b852a7a Move console defi... |
12 |
#include <console.h> |
c7694dd48 env: Move env_set... |
13 |
#include <env.h> |
66ded17df Move autoboot cod... |
14 |
#include <fdtdec.h> |
e8c780560 autoboot: Drop #i... |
15 |
#include <hash.h> |
336d4615f dm: core: Create ... |
16 |
#include <malloc.h> |
ecaae801d autoboot: fix bug... |
17 |
#include <memalign.h> |
66ded17df Move autoboot cod... |
18 19 |
#include <menu.h> #include <post.h> |
1045315df common: Move get_... |
20 |
#include <time.h> |
8f0b1e24e autoboot.c: Add f... |
21 |
#include <u-boot/sha256.h> |
bc8c440fa bootcount: Rewrit... |
22 |
#include <bootcount.h> |
decfa9848 MLK-21854-2 imx: ... |
23 24 25 |
#ifdef is_boot_from_usb #include <env.h> #endif |
66ded17df Move autoboot cod... |
26 27 28 29 30 31 32 33 34 35 |
DECLARE_GLOBAL_DATA_PTR; #define MAX_DELAY_STOP_STR 32 #ifndef DEBUG_BOOTKEYS #define DEBUG_BOOTKEYS 0 #endif #define debug_bootkeys(fmt, args...) \ debug_cond(DEBUG_BOOTKEYS, fmt, ##args) |
affb21562 main: Make the ex... |
36 37 |
/* Stored value of bootdelay, used by autoboot_command() */ static int stored_bootdelay; |
d915ad277 autoboot: Tidy up... |
38 |
static int menukey; |
affb21562 main: Make the ex... |
39 |
|
0c4bd318f autoboot: Use CON... |
40 41 42 43 44 |
#ifdef CONFIG_AUTOBOOT_ENCRYPTION #define AUTOBOOT_STOP_STR_SHA256 CONFIG_AUTOBOOT_STOP_STR_SHA256 #else #define AUTOBOOT_STOP_STR_SHA256 "" #endif |
d915ad277 autoboot: Tidy up... |
45 46 47 48 49 |
#ifdef CONFIG_USE_AUTOBOOT_MENUKEY #define AUTOBOOT_MENUKEY CONFIG_USE_AUTOBOOT_MENUKEY #else #define AUTOBOOT_MENUKEY 0 #endif |
8f0b1e24e autoboot.c: Add f... |
50 51 52 53 54 |
/* * Use a "constant-length" time compare function for this * hash compare: * * https://crackstation.net/hashing-security.htm |
66ded17df Move autoboot cod... |
55 |
*/ |
8f0b1e24e autoboot.c: Add f... |
56 57 58 59 60 61 62 63 64 65 |
static int slow_equals(u8 *a, u8 *b, int len) { int diff = 0; int i; for (i = 0; i < len; i++) diff |= a[i] ^ b[i]; return diff == 0; } |
88fa4beb6 autoboot: Improve... |
66 67 68 69 70 71 72 73 |
/** * passwd_abort_sha256() - check for a hashed key sequence to abort booting * * This checks for the user entering a SHA256 hash within a given time. * * @etime: Timeout value ticks (stop when get_ticks() reachs this) * @return 0 if autoboot should continue, 1 if it should stop */ |
e8c780560 autoboot: Drop #i... |
74 |
static int passwd_abort_sha256(uint64_t etime) |
8f0b1e24e autoboot.c: Add f... |
75 |
{ |
00caae6d4 env: Rename geten... |
76 |
const char *sha_env_str = env_get("bootstopkeysha256"); |
8f0b1e24e autoboot.c: Add f... |
77 |
u8 sha_env[SHA256_SUM_LEN]; |
ecaae801d autoboot: fix bug... |
78 79 |
u8 *sha; char *presskey; |
8f0b1e24e autoboot.c: Add f... |
80 81 82 |
const char *algo_name = "sha256"; u_int presskey_len = 0; int abort = 0; |
2d06fd839 Initialize SHA bu... |
83 |
int size = sizeof(sha); |
8f0b1e24e autoboot.c: Add f... |
84 85 86 |
int ret; if (sha_env_str == NULL) |
0c4bd318f autoboot: Use CON... |
87 |
sha_env_str = AUTOBOOT_STOP_STR_SHA256; |
8f0b1e24e autoboot.c: Add f... |
88 89 90 91 92 93 94 95 96 97 98 99 |
/* * Generate the binary value from the environment hash value * so that we can compare this value with the computed hash * from the user input */ ret = hash_parse_string(algo_name, sha_env_str, sha_env); if (ret) { printf("Hash %s not supported! ", algo_name); return 0; } |
ecaae801d autoboot: fix bug... |
100 101 102 |
presskey = malloc_cache_aligned(MAX_DELAY_STOP_STR); sha = malloc_cache_aligned(SHA256_SUM_LEN); size = SHA256_SUM_LEN; |
8f0b1e24e autoboot.c: Add f... |
103 104 105 106 107 108 109 110 |
/* * We don't know how long the stop-string is, so we need to * generate the sha256 hash upon each input character and * compare the value with the one saved in the environment */ do { if (tstc()) { /* Check for input string overflow */ |
ecaae801d autoboot: fix bug... |
111 112 113 |
if (presskey_len >= MAX_DELAY_STOP_STR) { free(presskey); free(sha); |
8f0b1e24e autoboot.c: Add f... |
114 |
return 0; |
ecaae801d autoboot: fix bug... |
115 |
} |
8f0b1e24e autoboot.c: Add f... |
116 117 118 119 120 121 122 123 124 125 126 127 |
presskey[presskey_len++] = getc(); /* Calculate sha256 upon each new char */ hash_block(algo_name, (const void *)presskey, presskey_len, sha, &size); /* And check if sha matches saved value in env */ if (slow_equals(sha, sha_env, SHA256_SUM_LEN)) abort = 1; } } while (!abort && get_ticks() <= etime); |
ecaae801d autoboot: fix bug... |
128 129 |
free(presskey); free(sha); |
8f0b1e24e autoboot.c: Add f... |
130 131 |
return abort; } |
e8c780560 autoboot: Drop #i... |
132 |
|
88fa4beb6 autoboot: Improve... |
133 134 135 136 137 138 139 140 |
/** * passwd_abort_key() - check for a key sequence to aborted booting * * This checks for the user entering a string within a given time. * * @etime: Timeout value ticks (stop when get_ticks() reachs this) * @return 0 if autoboot should continue, 1 if it should stop */ |
e8c780560 autoboot: Drop #i... |
141 |
static int passwd_abort_key(uint64_t etime) |
66ded17df Move autoboot cod... |
142 143 |
{ int abort = 0; |
66ded17df Move autoboot cod... |
144 145 146 147 148 149 |
struct { char *str; u_int len; int retry; } delaykey[] = { |
00caae6d4 env: Rename geten... |
150 151 |
{ .str = env_get("bootdelaykey"), .retry = 1 }, { .str = env_get("bootstopkey"), .retry = 0 }, |
66ded17df Move autoboot cod... |
152 153 154 155 156 157 |
}; char presskey[MAX_DELAY_STOP_STR]; u_int presskey_len = 0; u_int presskey_max = 0; u_int i; |
66ded17df Move autoboot cod... |
158 159 160 161 |
# ifdef CONFIG_AUTOBOOT_DELAY_STR if (delaykey[0].str == NULL) delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR; # endif |
66ded17df Move autoboot cod... |
162 |
# ifdef CONFIG_AUTOBOOT_STOP_STR |
2d908fa08 autoboot.c: Remov... |
163 164 |
if (delaykey[1].str == NULL) delaykey[1].str = CONFIG_AUTOBOOT_STOP_STR; |
66ded17df Move autoboot cod... |
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# endif for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i++) { delaykey[i].len = delaykey[i].str == NULL ? 0 : strlen(delaykey[i].str); delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ? MAX_DELAY_STOP_STR : delaykey[i].len; presskey_max = presskey_max > delaykey[i].len ? presskey_max : delaykey[i].len; debug_bootkeys("%s key:<%s> ", delaykey[i].retry ? "delay" : "stop", delaykey[i].str ? delaykey[i].str : "NULL"); } /* In order to keep up with incoming data, check timeout only * when catch up. */ do { if (tstc()) { if (presskey_len < presskey_max) { presskey[presskey_len++] = getc(); } else { for (i = 0; i < presskey_max - 1; i++) presskey[i] = presskey[i + 1]; presskey[i] = getc(); } } for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i++) { if (delaykey[i].len > 0 && presskey_len >= delaykey[i].len && memcmp(presskey + presskey_len - delaykey[i].len, delaykey[i].str, delaykey[i].len) == 0) { debug_bootkeys("got %skey ", delaykey[i].retry ? "delay" : "stop"); |
66ded17df Move autoboot cod... |
207 208 209 |
/* don't retry auto boot */ if (!delaykey[i].retry) bootretry_dont_retry(); |
66ded17df Move autoboot cod... |
210 211 212 213 |
abort = 1; } } } while (!abort && get_ticks() <= etime); |
8f0b1e24e autoboot.c: Add f... |
214 215 |
return abort; } |
8f0b1e24e autoboot.c: Add f... |
216 217 218 219 220 |
/*************************************************************************** * Watch for 'delay' seconds for autoboot stop or autoboot delay string. * returns: 0 - no key string, allow autoboot 1 - got key string, abort */ |
e79e4b250 autoboot: Drop #i... |
221 |
static int abortboot_key_sequence(int bootdelay) |
8f0b1e24e autoboot.c: Add f... |
222 223 224 |
{ int abort; uint64_t etime = endtick(bootdelay); |
8f0b1e24e autoboot.c: Add f... |
225 226 227 228 229 230 231 |
# ifdef CONFIG_AUTOBOOT_PROMPT /* * CONFIG_AUTOBOOT_PROMPT includes the %d for all boards. * To print the bootdelay value upon bootup. */ printf(CONFIG_AUTOBOOT_PROMPT, bootdelay); # endif |
e8c780560 autoboot: Drop #i... |
232 233 234 235 |
if (IS_ENABLED(CONFIG_AUTOBOOT_ENCRYPTION)) abort = passwd_abort_sha256(etime); else abort = passwd_abort_key(etime); |
66ded17df Move autoboot cod... |
236 237 238 |
if (!abort) debug_bootkeys("key timeout "); |
66ded17df Move autoboot cod... |
239 240 |
return abort; } |
e79e4b250 autoboot: Drop #i... |
241 |
static int abortboot_single_key(int bootdelay) |
66ded17df Move autoboot cod... |
242 243 244 |
{ int abort = 0; unsigned long ts; |
463273920 autoboot: move bo... |
245 |
printf("Hit any key to stop autoboot: %2d ", bootdelay); |
66ded17df Move autoboot cod... |
246 |
|
66ded17df Move autoboot cod... |
247 248 |
/* * Check if key already pressed |
66ded17df Move autoboot cod... |
249 |
*/ |
463273920 autoboot: move bo... |
250 251 252 253 |
if (tstc()) { /* we got a key press */ (void) getc(); /* consume input */ puts("\b\b\b 0"); abort = 1; /* don't auto boot */ |
66ded17df Move autoboot cod... |
254 |
} |
66ded17df Move autoboot cod... |
255 256 257 258 259 260 261 |
while ((bootdelay > 0) && (!abort)) { --bootdelay; /* delay 1000 ms */ ts = get_timer(0); do { if (tstc()) { /* we got a key press */ |
d915ad277 autoboot: Tidy up... |
262 |
int key; |
66ded17df Move autoboot cod... |
263 264 |
abort = 1; /* don't auto boot */ bootdelay = 0; /* no more delay */ |
d915ad277 autoboot: Tidy up... |
265 266 267 |
key = getc(); /* consume input */ if (IS_ENABLED(CONFIG_USE_AUTOBOOT_MENUKEY)) menukey = key; |
66ded17df Move autoboot cod... |
268 269 270 271 272 273 274 275 276 277 |
break; } udelay(10000); } while (!abort && get_timer(ts) < 1000); printf("\b\b\b%2d ", bootdelay); } putc(' '); |
66ded17df Move autoboot cod... |
278 279 |
return abort; } |
66ded17df Move autoboot cod... |
280 281 282 |
static int abortboot(int bootdelay) { |
463273920 autoboot: move bo... |
283 |
int abort = 0; |
09b9d9e55 autoboot: move CO... |
284 |
|
e79e4b250 autoboot: Drop #i... |
285 286 287 288 289 290 |
if (bootdelay >= 0) { if (IS_ENABLED(CONFIG_AUTOBOOT_KEYED)) abort = abortboot_key_sequence(bootdelay); else abort = abortboot_single_key(bootdelay); } |
09b9d9e55 autoboot: move CO... |
291 |
|
42b4d14e3 autoboot: Use if(... |
292 |
if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && abort) |
09b9d9e55 autoboot: move CO... |
293 |
gd->flags &= ~GD_FLG_SILENT; |
09b9d9e55 autoboot: move CO... |
294 295 |
return abort; |
66ded17df Move autoboot cod... |
296 |
} |
66ded17df Move autoboot cod... |
297 298 |
static void process_fdt_options(const void *blob) { |
5fa3fd25e autoboot: Move a ... |
299 |
#ifdef CONFIG_SYS_TEXT_BASE |
66ded17df Move autoboot cod... |
300 301 302 303 304 |
ulong addr; /* Add an env variable to point to a kernel payload, if available */ addr = fdtdec_get_config_int(gd->fdt_blob, "kernel-offset", 0); if (addr) |
018f53032 env: Rename commo... |
305 |
env_set_addr("kernaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr)); |
66ded17df Move autoboot cod... |
306 307 308 309 |
/* Add an env variable to point to a root disk, if available */ addr = fdtdec_get_config_int(gd->fdt_blob, "rootdisk-offset", 0); if (addr) |
018f53032 env: Rename commo... |
310 |
env_set_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr)); |
5fa3fd25e autoboot: Move a ... |
311 |
#endif /* CONFIG_SYS_TEXT_BASE */ |
affb21562 main: Make the ex... |
312 |
} |
66ded17df Move autoboot cod... |
313 |
|
affb21562 main: Make the ex... |
314 |
const char *bootdelay_process(void) |
66ded17df Move autoboot cod... |
315 |
{ |
66ded17df Move autoboot cod... |
316 317 |
char *s; int bootdelay; |
bc8c440fa bootcount: Rewrit... |
318 319 |
bootcount_inc(); |
66ded17df Move autoboot cod... |
320 |
|
00caae6d4 env: Rename geten... |
321 |
s = env_get("bootdelay"); |
66ded17df Move autoboot cod... |
322 |
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; |
5fa3fd25e autoboot: Move a ... |
323 324 325 |
if (IS_ENABLED(CONFIG_OF_CONTROL)) bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay", bootdelay); |
66ded17df Move autoboot cod... |
326 |
|
decfa9848 MLK-21854-2 imx: ... |
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
#if defined(is_boot_from_usb) if (is_boot_from_usb() && env_get("bootcmd_mfg")) { disconnect_from_pc(); printf("Boot from USB for mfgtools "); bootdelay = 0; env_set_default("Use default environment for \ mfgtools ", 0); } else if (is_boot_from_usb()) { printf("Boot from USB for uuu "); env_set("bootcmd", "fastboot 0"); } else { printf("Normal Boot "); } #endif |
66ded17df Move autoboot cod... |
345 346 347 |
debug("### main_loop entered: bootdelay=%d ", bootdelay); |
5fa3fd25e autoboot: Move a ... |
348 349 |
if (IS_ENABLED(CONFIG_AUTOBOOT_MENU_SHOW)) bootdelay = menu_show(bootdelay); |
b26440f1f Rename bootretry ... |
350 |
bootretry_init_cmd_timeout(); |
66ded17df Move autoboot cod... |
351 352 353 |
#ifdef CONFIG_POST if (gd->flags & GD_FLG_POSTFAIL) { |
00caae6d4 env: Rename geten... |
354 |
s = env_get("failbootcmd"); |
66ded17df Move autoboot cod... |
355 356 |
} else #endif /* CONFIG_POST */ |
bc8c440fa bootcount: Rewrit... |
357 |
if (bootcount_error()) |
00caae6d4 env: Rename geten... |
358 |
s = env_get("altbootcmd"); |
bc8c440fa bootcount: Rewrit... |
359 |
else |
00caae6d4 env: Rename geten... |
360 |
s = env_get("bootcmd"); |
66ded17df Move autoboot cod... |
361 |
|
decfa9848 MLK-21854-2 imx: ... |
362 363 364 365 366 367 368 |
#if defined(is_boot_from_usb) if (is_boot_from_usb() && env_get("bootcmd_mfg")) { s = env_get("bootcmd_mfg"); printf("Run bootcmd_mfg: %s ", s); } #endif |
5fa3fd25e autoboot: Move a ... |
369 370 |
if (IS_ENABLED(CONFIG_OF_CONTROL)) process_fdt_options(gd->fdt_blob); |
affb21562 main: Make the ex... |
371 |
stored_bootdelay = bootdelay; |
66ded17df Move autoboot cod... |
372 |
|
affb21562 main: Make the ex... |
373 374 |
return s; } |
66ded17df Move autoboot cod... |
375 |
|
affb21562 main: Make the ex... |
376 377 |
void autoboot_command(const char *s) { |
66ded17df Move autoboot cod... |
378 379 |
debug("### main_loop: bootcmd=\"%s\" ", s ? s : "<UNDEFINED>"); |
affb21562 main: Make the ex... |
380 |
if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { |
5ec35ff3e autoboot: Adjust ... |
381 382 383 384 385 386 387 |
bool lock; int prev; lock = IS_ENABLED(CONFIG_AUTOBOOT_KEYED) && !IS_ENABLED(CONFIG_AUTOBOOT_KEYED_CTRLC); if (lock) prev = disable_ctrlc(1); /* disable Ctrl-C checking */ |
66ded17df Move autoboot cod... |
388 389 |
run_command_list(s, -1, 0); |
5ec35ff3e autoboot: Adjust ... |
390 391 |
if (lock) disable_ctrlc(prev); /* restore Ctrl-C checking */ |
66ded17df Move autoboot cod... |
392 |
} |
d915ad277 autoboot: Tidy up... |
393 394 |
if (IS_ENABLED(CONFIG_USE_AUTOBOOT_MENUKEY) && menukey == AUTOBOOT_MENUKEY) { |
00caae6d4 env: Rename geten... |
395 |
s = env_get("menucmd"); |
66ded17df Move autoboot cod... |
396 397 398 |
if (s) run_command_list(s, -1, 0); } |
66ded17df Move autoboot cod... |
399 |
} |