diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 56 | ||||
-rw-r--r-- | common/blspec.c | 6 | ||||
-rw-r--r-- | common/boot.c | 20 | ||||
-rw-r--r-- | common/bootm.c | 6 | ||||
-rw-r--r-- | common/filetype.c | 10 | ||||
-rw-r--r-- | common/hush.c | 7 | ||||
-rw-r--r-- | common/imx-bbu-nand-fcb.c | 30 | ||||
-rw-r--r-- | common/startup.c | 165 | ||||
-rw-r--r-- | common/state/backend_bucket_direct.c | 7 |
9 files changed, 214 insertions, 93 deletions
diff --git a/common/Kconfig b/common/Kconfig index 7832df5c55..8aad5baecd 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -643,6 +643,27 @@ config BOOTM_FORCE_SIGNED_IMAGES are refused to boot. Effectively this means only FIT images can be booted since they are the only supported image type that support signing. +config BOOTM_OPTEE + bool + prompt "support booting OP-TEE" + depends on BOOTM && ARM + help + OP-TEE is a trusted execution environment (TEE). With this option + enabled barebox supports starting optee_os as part of the bootm command. + Instead of the kernel bootm starts the optee_os binary which then starts + the kernel in nonsecure mode. Pass the optee_os binary with the -t option + or in the global.bootm.tee variable. + +config BOOTM_OPTEE_SIZE + hex + default 0x02000000 + prompt "OP-TEE Memory Size" + depends on BOOTM_OPTEE + help + Size to reserve in main memory for OP-TEE. + Can be smaller than the actual size used by OP-TEE, this is used to prevent + barebox from allocating memory in this area. + config BLSPEC depends on FLEXIBLE_BOOTARGS depends on !SHELL_NONE @@ -999,12 +1020,6 @@ config DEFAULT_LOGLEVEL 7 debug-level messages (debug) 8 verbose debug messages (vdebug) -config DEBUG_INFO - bool - prompt "enable debug symbols" - help - Enable build of barebox with -g. - config DEBUG_LL bool depends on HAS_DEBUG_LL @@ -1168,6 +1183,13 @@ config DEBUG_RPI1_UART Say Y here if you want low-level debugging support on RaspberryPi 1 boards. +config DEBUG_AT91_UART + bool "AT91 Debug UART" + depends on ARCH_AT91 + help + Say Y here if you want barebox low-level debugging support + on AT91 based platforms. + config DEBUG_RPI2_3_UART bool "RaspberryPi 2/3 PL011 UART" depends on ARCH_BCM283X @@ -1238,6 +1260,7 @@ config DEBUG_SOCFPGA_UART_CLOCK help Choose UART root clock. + config DEBUG_LAYERSCAPE_UART_PORT int "Layerscape UART port selection" depends on ARCH_LAYERSCAPE @@ -1246,11 +1269,32 @@ config DEBUG_LAYERSCAPE_UART_PORT Select the UART port number used for early debugging here. Port numbers start counting from 1. +config DEBUG_AT91_UART_BASE + hex "AT91 Debug UART Port Selection" if DEBUG_AT91_UART + default 0xfffff200 if SOC_AT91RM9200 || SOC_AT91SAM9260 \ + || SOC_AT91SAM9261 || SOC_AT91SAM9X5 \ + || SOC_AT91SAM9N12 + default 0xffffee00 if SOC_AT91SAM9263 || SOC_AT91SAM9G45 || ARCH_SAMA5D3 + default 0xfc069000 if ARCH_SAMA5D4 + default 0xfffff200 + depends on ARCH_AT91 + help + Specify UART port base address on which barebox low-level + debug messages should be output. + config DEBUG_INITCALLS bool "Trace initcalls" help If enabled this will print initcall traces. + +config PBL_BREAK + bool "Execute software break on pbl start" + depends on ARM + help + If this enabled, barebox will be compiled with BKPT instruction + on early pbl init. This option should be used only with JTAG debugger! + endmenu config HAS_DEBUG_LL diff --git a/common/blspec.c b/common/blspec.c index 41f2a4c534..66e5033e35 100644 --- a/common/blspec.c +++ b/common/blspec.c @@ -63,7 +63,11 @@ static int blspec_boot(struct bootentry *be, int verbose, int dryrun) }; globalvar_set_match("linux.bootargs.dyn.", ""); - globalvar_set_match("bootm.", ""); + globalvar_set_match("bootm.image", ""); + globalvar_set_match("bootm.oftree", ""); + globalvar_set_match("bootm.initrd", ""); + + bootm_data_init_defaults(&data); devicetree = blspec_entry_var_get(entry, "devicetree"); initrd = blspec_entry_var_get(entry, "initrd"); diff --git a/common/boot.c b/common/boot.c index 974eaf5d02..14d4fe9d64 100644 --- a/common/boot.c +++ b/common/boot.c @@ -92,6 +92,8 @@ static int bootscript_boot(struct bootentry *entry, int verbose, int dryrun) return 0; } + globalvar_add_simple("linux.bootargs.dyn.ip", NULL); + globalvar_add_simple("linux.bootargs.dyn.root", NULL); globalvar_set_match("linux.bootargs.dyn.", ""); ret = run_command(bs->scriptpath); @@ -117,12 +119,22 @@ void boot_set_watchdog_timeout(unsigned int timeout) boot_watchdog_timeout = timeout; } -static int init_boot_watchdog_timeout(void) +static char *global_boot_default; +static char *global_user; + +static int init_boot(void) { - return globalvar_add_simple_int("boot.watchdog_timeout", - &boot_watchdog_timeout, "%u"); + global_boot_default = xstrdup("net"); + globalvar_add_simple_string("boot.default", &global_boot_default); + globalvar_add_simple_int("boot.watchdog_timeout", + &boot_watchdog_timeout, "%u"); + globalvar_add_simple("linux.bootargs.base", NULL); + global_user = xstrdup("none"); + globalvar_add_simple_string("user", &global_user); + + return 0; } -late_initcall(init_boot_watchdog_timeout); +late_initcall(init_boot); BAREBOX_MAGICVAR_NAMED(global_watchdog_timeout, global.boot.watchdog_timeout, "Watchdog enable timeout in seconds before booting"); diff --git a/common/bootm.c b/common/bootm.c index 36f6c41bbd..d7232f6afa 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -58,6 +58,7 @@ void bootm_data_init_defaults(struct bootm_data *data) data->initrd_address = UIMAGE_INVALID_ADDRESS; data->os_address = UIMAGE_SOME_ADDRESS; data->oftree_file = getenv_nonempty("global.bootm.oftree"); + data->tee_file = getenv_nonempty("global.bootm.tee"); data->os_file = getenv_nonempty("global.bootm.image"); getenv_ul("global.bootm.image.loadaddr", &data->os_address); getenv_ul("global.bootm.initrd.loadaddr", &data->initrd_address); @@ -553,6 +554,8 @@ int bootm_boot(struct bootm_data *bootm_data) bootm_image_name_and_part(bootm_data->os_file, &data->os_file, &data->os_part); bootm_image_name_and_part(bootm_data->oftree_file, &data->oftree_file, &data->oftree_part); bootm_image_name_and_part(bootm_data->initrd_file, &data->initrd_file, &data->initrd_part); + if (bootm_data->tee_file) + data->tee_file = xstrdup(bootm_data->tee_file); data->verbose = bootm_data->verbose; data->verify = bootm_data->verify; data->force = bootm_data->force; @@ -693,6 +696,7 @@ err_out: free(data->os_file); free(data->oftree_file); free(data->initrd_file); + free(data->tee_file); free(data); return ret; @@ -703,6 +707,7 @@ static int bootm_init(void) globalvar_add_simple("bootm.image", NULL); globalvar_add_simple("bootm.image.loadaddr", NULL); globalvar_add_simple("bootm.oftree", NULL); + globalvar_add_simple("bootm.tee", NULL); globalvar_add_simple_bool("bootm.appendroot", &bootm_appendroot); if (IS_ENABLED(CONFIG_BOOTM_INITRD)) { globalvar_add_simple("bootm.initrd", NULL); @@ -727,6 +732,7 @@ BAREBOX_MAGICVAR_NAMED(global_bootm_image_loadaddr, global.bootm.image.loadaddr, BAREBOX_MAGICVAR_NAMED(global_bootm_initrd, global.bootm.initrd, "bootm default initrd"); BAREBOX_MAGICVAR_NAMED(global_bootm_initrd_loadaddr, global.bootm.initrd.loadaddr, "bootm default initrd loadaddr"); BAREBOX_MAGICVAR_NAMED(global_bootm_oftree, global.bootm.oftree, "bootm default oftree"); +BAREBOX_MAGICVAR_NAMED(global_bootm_tee, global.bootm.tee, "bootm default tee image"); BAREBOX_MAGICVAR_NAMED(global_bootm_verify, global.bootm.verify, "bootm default verify level"); BAREBOX_MAGICVAR_NAMED(global_bootm_verbose, global.bootm.verbose, "bootm default verbosity level (0=quiet)"); BAREBOX_MAGICVAR_NAMED(global_bootm_appendroot, global.bootm.appendroot, "Add root= option to Kernel to mount rootfs from the device the Kernel comes from"); diff --git a/common/filetype.c b/common/filetype.c index e2d707b156..329f5144bf 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -37,7 +37,7 @@ struct filetype_str { }; static const struct filetype_str filetype_str[] = { - [filetype_unknown] = { "unknown", "unkown" }, + [filetype_unknown] = { "unknown", "unknown" }, [filetype_arm_zimage] = { "ARM Linux zImage", "arm-zimage" }, [filetype_lzo_compressed] = { "LZO compressed", "lzo" }, [filetype_lz4_compressed] = { "LZ4 compressed", "lz4" }, @@ -77,6 +77,8 @@ static const struct filetype_str filetype_str[] = { [filetype_imx_image_v2] = { "i.MX image (v2)", "imx-image-v2" }, [filetype_layerscape_image] = { "Layerscape image", "layerscape-PBL" }, [filetype_layerscape_qspi_image] = { "Layerscape QSPI image", "layerscape-qspi-PBL" }, + [filetype_ubootvar] = { "U-Boot environmemnt variable data", + "ubootvar" }, }; const char *file_type_to_string(enum filetype f) @@ -423,6 +425,11 @@ enum filetype cdev_detect_type(const char *name) if (!cdev) return type; + if (cdev->filetype != filetype_unknown) { + type = cdev->filetype; + goto cdev_close; + } + buf = xzalloc(FILE_TYPE_SAFE_BUFSIZE); ret = cdev_read(cdev, buf, FILE_TYPE_SAFE_BUFSIZE, 0, 0); if (ret < 0) @@ -432,6 +439,7 @@ enum filetype cdev_detect_type(const char *name) err_out: free(buf); +cdev_close: cdev_close(cdev); return type; } diff --git a/common/hush.c b/common/hush.c index dab9b04081..68c3eccdfc 100644 --- a/common/hush.c +++ b/common/hush.c @@ -402,7 +402,12 @@ static void b_free(o_string *o) static int b_adduint(o_string *o, unsigned int i) { int r; - char *p = simple_itoa(i); + /* 21 digits plus null terminator, good for 64-bit or smaller + * ints */ + char number[22]; + char *p = number; + + snprintf(number, sizeof(number), "%u", i); /* no escape checking necessary */ do { diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c index a29a1bf91a..6d773b59df 100644 --- a/common/imx-bbu-nand-fcb.c +++ b/common/imx-bbu-nand-fcb.c @@ -606,9 +606,10 @@ static int imx_bbu_write_firmware(struct mtd_info *mtd, unsigned num, void *buf, int ret, i, newbadblock = 0; int num_blocks = imx_bbu_firmware_max_blocks(mtd); int block = imx_bbu_firmware_start_block(mtd, num); + int page = block * mtd->erasesize / mtd->writesize; - pr_info("writing firmware %d to block %d (ofs 0x%08x)\n", - num, block, block * mtd->erasesize); + pr_info("writing firmware to slot %d on pages %d-%d\n", + num, page, page + len / mtd->writesize); for (i = 0; i < num_blocks; i++) { if (mtd_peb_is_bad(mtd, block + i)) @@ -976,6 +977,9 @@ static int imx_bbu_write_fcbs_dbbts(struct mtd_info *mtd, struct fcb_block *fcb) */ memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + pr_info("Writing FCBs/DBBTs with primary/secondary Firmwares at pages %d/%d\n", + fcb->Firmware1_startingPage, fcb->Firmware2_startingPage); + for (i = 0; i < 4; i++) { if (mtd_peb_is_bad(mtd, i)) continue; @@ -1108,7 +1112,7 @@ err: if (need_cleaning) { pr_warn("Firmware at page %d needs cleanup\n", first_page); - return -EUCLEAN; + return 1; } return 0; @@ -1162,13 +1166,14 @@ static void read_firmware_all(struct mtd_info *mtd, struct fcb_block *fcb, void *unused_refresh = 1; *used = first; *data = primary; - return; } else if (secondary && !primary) { *used_refresh = secondary_refresh; *unused_refresh = 1; *used = !first; *data = secondary; } else { + *unused_refresh = secondary_refresh; + if (memcmp(primary, secondary, fcb->PagesInFirmware1 * mtd->writesize)) *unused_refresh = 1; @@ -1178,15 +1183,20 @@ static void read_firmware_all(struct mtd_info *mtd, struct fcb_block *fcb, void free(secondary); } - pr_info("Primary firmware is on pages %d-%d, %svalid, %s\n", fcb->Firmware1_startingPage, + pr_info("Primary firmware is in slot %d on pages %d-%d, %svalid, %s\n", + first, + fcb->Firmware1_startingPage, fcb->Firmware1_startingPage + fcb->PagesInFirmware1, primary ? "" : "in", primary_refresh ? "needs cleanup" : "clean"); - pr_info("Secondary firmware is on pages %d-%d, %svalid, %s\n", fcb->Firmware2_startingPage, + pr_info("Secondary firmware is in slot %d on pages %d-%d, %svalid, %s\n", + !first, + fcb->Firmware2_startingPage, fcb->Firmware2_startingPage + fcb->PagesInFirmware2, secondary ? "" : "in", secondary_refresh ? "needs cleanup" : "clean"); - pr_info("ROM uses slot %d\n", *used); + pr_info("ROM uses slot %d (%s firmware)\n", + *used, primary ? "primary" : secondary ? "secondary" : "no"); } static int imx_bbu_nand_update(struct bbu_handler *handler, struct bbu_data *data) @@ -1331,6 +1341,12 @@ static int imx_bbu_nand_update(struct bbu_handler *handler, struct bbu_data *dat fw = fw_orig; fw_size = fw_orig_len; pr_info("Refreshing existing firmware\n"); + + if (used_refresh) { + fcb->Firmware1_startingPage = imx_bbu_firmware_fcb_start_page(mtd, !used); + fcb->Firmware2_startingPage = imx_bbu_firmware_fcb_start_page(mtd, used); + fcb_create(imx_handler, fcb, mtd); + } } if (num_blocks_fw * mtd->erasesize < fw_size) { diff --git a/common/startup.c b/common/startup.c index 9fac0eabbd..92bf94f849 100644 --- a/common/startup.c +++ b/common/startup.c @@ -152,13 +152,6 @@ static const char * const global_autoboot_abort_keys[] = { "ctrl-c", }; static int global_autoboot_timeout = 3; -static char *global_boot_default; -static char *global_editcmd; -static char *global_linux_bootargs_base; -static char *global_linux_bootargs_console; -static char *global_linux_bootargs_dyn_ip; -static char *global_linux_bootargs_dyn_root; -static char *global_user; static bool test_abort(void) { @@ -188,35 +181,45 @@ static bool test_abort(void) return false; } -static int run_init(void) +#define INITFILE "/env/bin/init" +#define MENUFILE "/env/menu/mainmenu" + +static enum autoboot_state autoboot_state = AUTOBOOT_UNKNOWN; + +/** + * set_autoboot_state - set the autoboot state + * @autoboot: the state to set + * + * This functions sets the autoboot state to the given state. This can be called + * by boards which have its own idea when and how the autoboot shall be aborted. + */ +void set_autoboot_state(enum autoboot_state autoboot) +{ + autoboot_state = autoboot; +} + +/** + * do_autoboot_countdown - print autoboot countdown to console + * + * This prints the autoboot countdown to the console and waits for input. This + * evaluates the global.autoboot_about_key to determine which keys are allowed + * to interrupt booting and also global.autoboot_timeout to determine the timeout + * for the counter. This function can be called multiple times, it is executed + * only the first time. + * + * Returns an enum autoboot_state value containing the user input. + */ +enum autoboot_state do_autoboot_countdown(void) { - DIR *dir; - struct dirent *d; - const char *initfile = "/env/bin/init"; - const char *initdir = "/env/init"; - const char *menufile = "/env/menu/mainmenu"; - struct stat s; unsigned flags = CONSOLE_COUNTDOWN_EXTERN; - unsigned char outkey; int ret; + struct stat s; bool menu_exists; - bool env_bin_init_exists; char *abortkeys = NULL; + unsigned char outkey; - setenv("PATH", "/env/bin"); - - /* Run legacy /env/bin/init if it exists */ - env_bin_init_exists = stat(initfile, &s) == 0; - if (env_bin_init_exists) { - pr_info("running %s...\n", initfile); - run_command(initfile); - return 0; - } - - global_editcmd = xstrdup("sedit"); - global_user = xstrdup("none"); - globalvar_add_simple_string("user", &global_user); - global_boot_default = xstrdup("net"); + if (autoboot_state != AUTOBOOT_UNKNOWN) + return autoboot_state; globalvar_add_simple_enum("autoboot_abort_key", &global_autoboot_abort_key, @@ -224,16 +227,60 @@ static int run_init(void) ARRAY_SIZE(global_autoboot_abort_keys)); globalvar_add_simple_int("autoboot_timeout", &global_autoboot_timeout, "%u"); - globalvar_add_simple_string("boot.default", &global_boot_default); - globalvar_add_simple_string("editcmd", &global_editcmd); - globalvar_add_simple_string("linux.bootargs.base", - &global_linux_bootargs_base); - globalvar_add_simple_string("linux.bootargs.console", - &global_linux_bootargs_console); - globalvar_add_simple_string("linux.bootargs.dyn.ip", - &global_linux_bootargs_dyn_ip); - globalvar_add_simple_string("linux.bootargs.dyn.root", - &global_linux_bootargs_dyn_root); + + menu_exists = stat(MENUFILE, &s) == 0; + + if (menu_exists) { + printf("\nHit m for menu or %s to stop autoboot: ", + global_autoboot_abort_keys[global_autoboot_abort_key]); + abortkeys = "m"; + } else { + printf("\nHit %s to stop autoboot: ", + global_autoboot_abort_keys[global_autoboot_abort_key]); + } + + switch (global_autoboot_abort_key) { + case 0: + flags |= CONSOLE_COUNTDOWN_ANYKEY; + break; + case 1: + flags |= CONSOLE_COUNTDOWN_CTRLC; + break; + default: + break; + } + + ret = console_countdown(global_autoboot_timeout, flags, abortkeys, + &outkey); + + if (ret == 0) + autoboot_state = AUTOBOOT_BOOT; + else if (menu_exists && outkey == 'm') + autoboot_state = AUTOBOOT_MENU; + else + autoboot_state = AUTOBOOT_ABORT; + + return autoboot_state; +} + +static int run_init(void) +{ + DIR *dir; + struct dirent *d; + const char *initdir = "/env/init"; + bool env_bin_init_exists; + enum autoboot_state autoboot; + struct stat s; + + setenv("PATH", "/env/bin"); + + /* Run legacy /env/bin/init if it exists */ + env_bin_init_exists = stat(INITFILE, &s) == 0; + if (env_bin_init_exists) { + pr_info("running %s...\n", INITFILE); + run_command("source " INITFILE); + return 0; + } /* Unblank console cursor */ printf("\e[?25h"); @@ -261,44 +308,18 @@ static int run_init(void) closedir(dir); } - menu_exists = stat(menufile, &s) == 0; + autoboot = do_autoboot_countdown(); - if (menu_exists) { - printf("\nHit m for menu or %s to stop autoboot: ", - global_autoboot_abort_keys[global_autoboot_abort_key]); - abortkeys = "m"; - } else { - printf("\nHit %s to stop autoboot: ", - global_autoboot_abort_keys[global_autoboot_abort_key]); - } - - switch (global_autoboot_abort_key) { - case 0: - flags |= CONSOLE_COUNTDOWN_ANYKEY; - break; - case 1: - flags |= CONSOLE_COUNTDOWN_CTRLC; - break; - default: - break; - } - - ret = console_countdown(global_autoboot_timeout, flags, abortkeys, - &outkey); - - if (ret == 0) + if (autoboot == AUTOBOOT_BOOT) run_command("boot"); console_ctrlc_allow(); - if (menu_exists) { - if (outkey == 'm') - run_command(menufile); + if (autoboot == AUTOBOOT_MENU) + run_command(MENUFILE); - printf("Enter 'exit' to get back to the menu\n"); - run_shell(); - run_command(menufile); - } + run_shell(); + run_command(MENUFILE); return 0; } diff --git a/common/state/backend_bucket_direct.c b/common/state/backend_bucket_direct.c index 95ddb93106..0dbd334db8 100644 --- a/common/state/backend_bucket_direct.c +++ b/common/state/backend_bucket_direct.c @@ -52,7 +52,7 @@ static int state_backend_bucket_direct_read(struct state_backend_storage_bucket struct state_backend_storage_bucket_direct *direct = get_bucket_direct(bucket); struct state_backend_storage_bucket_direct_meta meta; - ssize_t read_len; + uint32_t read_len; void *buf; int ret; @@ -67,6 +67,11 @@ static int state_backend_bucket_direct_read(struct state_backend_storage_bucket } if (meta.magic == direct_magic) { read_len = meta.written_length; + if (read_len > direct->max_size) { + dev_err(direct->dev, "Wrong length in meta data\n"); + return -EINVAL; + + } } else { if (meta.magic != ~0 && !!meta.magic) bucket->wrong_magic = 1; |