summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig56
-rw-r--r--common/blspec.c6
-rw-r--r--common/boot.c20
-rw-r--r--common/bootm.c6
-rw-r--r--common/filetype.c10
-rw-r--r--common/hush.c7
-rw-r--r--common/imx-bbu-nand-fcb.c30
-rw-r--r--common/startup.c165
-rw-r--r--common/state/backend_bucket_direct.c7
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;