From 224b72e639e87040a1845cf9795b45417e064bba Mon Sep 17 00:00:00 2001 From: Che-Liang Chiou Date: Thu, 25 Oct 2012 16:31:07 +0000 Subject: fdt: Load boot command from device tree Load boot command from /config/bootcmd of device tree if present. Signed-off-by: Tom Wai-Hong Tam Signed-off-by: Che-Liang Chiou Signed-off-by: Simon Glass --- common/main.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'common/main.c') diff --git a/common/main.c b/common/main.c index 592ce07..48bed95 100644 --- a/common/main.c +++ b/common/main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_MODEM_SUPPORT @@ -40,6 +41,10 @@ #include #endif +#ifdef CONFIG_OF_CONTROL +#include +#endif + #include #include #include @@ -284,7 +289,10 @@ void main_loop (void) int rc = 1; int flag; #endif - +#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \ + defined(CONFIG_OF_CONTROL) + char *env; +#endif #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) char *s; int bootdelay; @@ -380,6 +388,12 @@ void main_loop (void) else #endif /* CONFIG_BOOTCOUNT_LIMIT */ s = getenv ("bootcmd"); +#ifdef CONFIG_OF_CONTROL + /* Allow the fdt to override the boot command */ + env = fdtdec_get_config_string(gd->fdt_blob, "bootcmd"); + if (env) + s = env; +#endif /* CONFIG_OF_CONTROL */ debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : ""); -- cgit v1.1 From 3b73459ea3421e9f8c6c8c62e1d3fe458ca5bc56 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 25 Oct 2012 16:31:08 +0000 Subject: fdt: Tell the FDT library where the device tree is This change adds a call to set_working_fdt_addr near the end of u-boot initialization which tells the fdt command/library where the device tree is. This makes it possible to use the fdt command to look at the active device tree since otherwise there would be no way to know what address it was at to set things up manually. Signed-off-by: Gabe Black Signed-off-by: Simon Glass --- common/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'common/main.c') diff --git a/common/main.c b/common/main.c index 48bed95..fd70928 100644 --- a/common/main.c +++ b/common/main.c @@ -45,6 +45,10 @@ #include #endif +#ifdef CONFIG_OF_LIBFDT +#include +#endif /* CONFIG_OF_LIBFDT */ + #include #include #include @@ -418,6 +422,10 @@ void main_loop (void) #endif /* CONFIG_MENUKEY */ #endif /* CONFIG_BOOTDELAY */ +#if defined CONFIG_OF_CONTROL + set_working_fdt_addr((void *)gd->fdt_blob); +#endif /* CONFIG_OF_CONTROL */ + /* * Main Loop for Monitor Command Processing */ -- cgit v1.1 From 67e1ea26e89e19a550d86d6408f39d815eedaa7f Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Thu, 25 Oct 2012 16:31:09 +0000 Subject: fdt: Allow device tree to specify secure booting When secure booting is chosen: * The u-boot shell is never invoked during boot--we just do a simple table lookup to find the command. This means we could even remove the shell parsing from u-boot and still be able to boot. * The boot command can't be interruped. * Failure doesn't cause us to fall back to the shell. Signed-off-by: Gabe Black Signed-off-by: Doug Anderson Signed-off-by: Simon Glass --- common/main.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'common/main.c') diff --git a/common/main.c b/common/main.c index fd70928..61c6cac 100644 --- a/common/main.c +++ b/common/main.c @@ -283,6 +283,59 @@ int abortboot(int bootdelay) # endif /* CONFIG_AUTOBOOT_KEYED */ #endif /* CONFIG_BOOTDELAY >= 0 */ +/* + * Runs the given boot command securely. Specifically: + * - Doesn't run the command with the shell (run_command or parse_string_outer), + * since that's a lot of code surface that an attacker might exploit. + * Because of this, we don't do any argument parsing--the secure boot command + * has to be a full-fledged u-boot command. + * - Doesn't check for keypresses before booting, since that could be a + * security hole; also disables Ctrl-C. + * - Doesn't allow the command to return. + * + * Upon any failures, this function will drop into an infinite loop after + * printing the error message to console. + */ + +#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \ + defined(CONFIG_OF_CONTROL) +static void secure_boot_cmd(char *cmd) +{ + cmd_tbl_t *cmdtp; + int rc; + + if (!cmd) { + printf("## Error: Secure boot command not specified\n"); + goto err; + } + + /* Disable Ctrl-C just in case some command is used that checks it. */ + disable_ctrlc(1); + + /* Find the command directly. */ + cmdtp = find_cmd(cmd); + if (!cmdtp) { + printf("## Error: \"%s\" not defined\n", cmd); + goto err; + } + + /* Run the command, forcing no flags and faking argc and argv. */ + rc = (cmdtp->cmd)(cmdtp, 0, 1, &cmd); + + /* Shouldn't ever return from boot command. */ + printf("## Error: \"%s\" returned (code %d)\n", cmd, rc); + +err: + /* + * Not a whole lot to do here. Rebooting won't help much, since we'll + * just end up right back here. Just loop. + */ + hang(); +} + +#endif /* CONFIG_OF_CONTROL */ + + /****************************************************************************/ void main_loop (void) @@ -397,6 +450,15 @@ void main_loop (void) env = fdtdec_get_config_string(gd->fdt_blob, "bootcmd"); if (env) s = env; + + /* + * If the bootsecure option was chosen, use secure_boot_cmd(). + * Always use 'env' in this case, since bootsecure requres that the + * bootcmd was specified in the FDT too. + */ + if (fdtdec_get_config_int(gd->fdt_blob, "bootsecure", 0)) + secure_boot_cmd(env); + #endif /* CONFIG_OF_CONTROL */ debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : ""); -- cgit v1.1 From fcabc24f4fd2fd581036c7a20eee47a204f04f39 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 25 Oct 2012 16:31:11 +0000 Subject: fdt: Set kernaddr if fdt indicates a kernel is present If kernel-offset is specified in the fdt, set an environment variable so that scripts can access the attached kernel. This can be used by a packaging program to tell U-Boot about a kernel that has been downloaded alongside U-Boot. The value in the fdt is the offset of the kernel from the start of the U-Boot image, so we can find it just by adding CONFIG_SYS_TEXT_BASE. It is then fairly easy to put something like this in the environment variables in the board header file: "if test ${kernaddr} != \"\"; then "\ "echo \"Using bundled kernel\"; "\ "bootm ${kernaddr};" \ "fi; "\ /* rest of boot sequence follows here */ Signed-off-by: Simon Glass --- common/main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'common/main.c') diff --git a/common/main.c b/common/main.c index 61c6cac..8052d42 100644 --- a/common/main.c +++ b/common/main.c @@ -333,6 +333,20 @@ err: hang(); } +static void process_fdt_options(const void *blob) +{ + 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) + setenv_addr("kernaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr)); + + /* 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) + setenv_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr)); +} #endif /* CONFIG_OF_CONTROL */ @@ -451,6 +465,8 @@ void main_loop (void) if (env) s = env; + process_fdt_options(gd->fdt_blob); + /* * If the bootsecure option was chosen, use secure_boot_cmd(). * Always use 'env' in this case, since bootsecure requres that the -- cgit v1.1 From f39612d360c02ce97e7ca7a872693f348f7ec8fd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 28 Nov 2012 07:54:58 +0000 Subject: fdt: Correct global_data condition in main We need an extra condition here in case we want to use fdt without the silent console/cmdline editing/post options. It is easier to just remove the #ifdef. Signed-off-by: Simon Glass --- common/main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'common/main.c') diff --git a/common/main.c b/common/main.c index 8052d42..5362781 100644 --- a/common/main.c +++ b/common/main.c @@ -53,9 +53,7 @@ #include #include -#if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING) DECLARE_GLOBAL_DATA_PTR; -#endif /* * Board-specific Platform code can reimplement show_boot_progress () if needed -- cgit v1.1 From 01433d60016a5aa4b53608f816e1e220f0108546 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Dec 2012 14:46:28 +0000 Subject: Add new bootstage step for the main loop Mark when we get to the main loop. Signed-off-by: Simon Glass --- common/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'common/main.c') diff --git a/common/main.c b/common/main.c index 5362781..b145f85 100644 --- a/common/main.c +++ b/common/main.c @@ -376,6 +376,8 @@ void main_loop (void) char bcs_set[16]; #endif /* CONFIG_BOOTCOUNT_LIMIT */ + bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); + #ifdef CONFIG_BOOTCOUNT_LIMIT bootcount = bootcount_load(); bootcount++; -- cgit v1.1