summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2022-08-11 13:43:03 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2022-08-11 13:43:03 +0200
commitad4fa274907bbc78ebabb015b4351d5f9226f081 (patch)
tree3eb033a3d6bedb50459ea0181e5180e1531d00e8 /common
parent3fcf4400a7b051bdbe9fc175b88336519099ff22 (diff)
parent3a0f44a7839d475c58720c4091d5e008215cd166 (diff)
downloadbarebox-ad4fa274907bbc78ebabb015b4351d5f9226f081.tar.gz
barebox-ad4fa274907bbc78ebabb015b4351d5f9226f081.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig17
-rw-r--r--common/blspec.c167
-rw-r--r--common/boot.c11
-rw-r--r--common/booti.c7
-rw-r--r--common/bootm.c7
-rw-r--r--common/image-fit.c34
6 files changed, 150 insertions, 93 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 60f52a10e1..43dd92b08a 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -639,6 +639,21 @@ config BOOTM_FITIMAGE_SIGNATURE
Additionally the barebox device tree needs a /signature node with the
public key with which the image has been signed.
+config BOOTM_FITIMAGE_PUBKEY_ENV
+ bool "Specify path to public key in environment"
+ depends on BOOTM_FITIMAGE_SIGNATURE
+ help
+ If this option is enabled the path to the public key for verifying
+ FIT images signature is taken from environment which allows for
+ better integration with build systems.
+
+ The environment variable has the same name as the corresponding
+ Kconfig variable:
+
+ CONFIG_BOOTM_FITIMAGE_PUBKEY
+
+if BOOTM_FITIMAGE_SIGNATURE && !BOOTM_FITIMAGE_PUBKEY_ENV
+
config BOOTM_FITIMAGE_PUBKEY
string "Path to dtsi containing pubkey"
default "../fit/pubkey.dtsi"
@@ -648,6 +663,8 @@ config BOOTM_FITIMAGE_PUBKEY
snippet can then be included in a device tree with
"#include CONFIG_BOOTM_FITIMAGE_PUBKEY".
+endif
+
config BOOTM_FORCE_SIGNED_IMAGES
bool
prompt "Force booting of signed images"
diff --git a/common/blspec.c b/common/blspec.c
index 158fd1e9a2..9bb25ee721 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -15,6 +15,7 @@
#include <libbb.h>
#include <init.h>
#include <bootm.h>
+#include <glob.h>
#include <net.h>
#include <fs.h>
#include <of.h>
@@ -513,6 +514,55 @@ static bool entry_is_match_machine_id(struct blspec_entry *entry)
return ret;
}
+int blspec_scan_file(struct bootentries *bootentries, const char *root,
+ const char *configname)
+{
+ char *devname = NULL, *hwdevname = NULL;
+ struct blspec_entry *entry;
+
+ if (blspec_have_entry(bootentries, configname))
+ return -EEXIST;
+
+ entry = blspec_entry_open(bootentries, configname);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
+
+ root = root ?: get_mounted_path(configname);
+ entry->rootpath = xstrdup(root);
+ entry->configpath = xstrdup(configname);
+ entry->cdev = get_cdev_by_mountpath(root);
+
+ if (!entry_is_of_compatible(entry)) {
+ blspec_entry_free(&entry->entry);
+ return -ENODEV;
+ }
+
+ if (!entry_is_match_machine_id(entry)) {
+ blspec_entry_free(&entry->entry);
+ return -ENODEV;
+ }
+
+ if (entry->cdev && entry->cdev->dev) {
+ devname = xstrdup(dev_name(entry->cdev->dev));
+ if (entry->cdev->dev->parent)
+ hwdevname = xstrdup(dev_name(entry->cdev->dev->parent));
+ }
+
+ entry->entry.title = xasprintf("%s (%s)", blspec_entry_var_get(entry, "title"),
+ configname);
+ entry->entry.description = basprintf("blspec entry, device: %s hwdevice: %s",
+ devname ? devname : "none",
+ hwdevname ? hwdevname : "none");
+ free(devname);
+ free(hwdevname);
+
+ entry->entry.me.type = MENU_ENTRY_NORMAL;
+ entry->entry.release = blspec_entry_free;
+
+ bootentries_add_entry(bootentries, &entry->entry);
+ return 1;
+}
+
/*
* blspec_scan_directory - scan over a directory
*
@@ -522,115 +572,40 @@ static bool entry_is_match_machine_id(struct blspec_entry *entry)
*/
int blspec_scan_directory(struct bootentries *bootentries, const char *root)
{
- struct blspec_entry *entry;
- DIR *dir;
- struct dirent *d;
+ glob_t globb;
char *abspath;
int ret, found = 0;
const char *dirname = "loader/entries";
- char *nfspath = NULL;
-
- nfspath = parse_nfs_url(root);
- if (!IS_ERR(nfspath))
- root = nfspath;
+ int i;
pr_debug("%s: %s %s\n", __func__, root, dirname);
- abspath = basprintf("%s/%s", root, dirname);
+ abspath = basprintf("%s/%s/*.conf", root, dirname);
- dir = opendir(abspath);
- if (!dir) {
+ ret = glob(abspath, 0, NULL, &globb);
+ if (ret) {
pr_debug("%s: %s: %s\n", __func__, abspath, strerror(errno));
ret = -errno;
goto err_out;
}
- while ((d = readdir(dir))) {
- char *configname;
+ for (i = 0; i < globb.gl_pathc; i++) {
+ const char *configname = globb.gl_pathv[i];
struct stat s;
- char *dot;
- char *devname = NULL, *hwdevname = NULL;
-
- if (*d->d_name == '.')
- continue;
-
- configname = basprintf("%s/%s", abspath, d->d_name);
-
- dot = strrchr(configname, '.');
- if (!dot) {
- free(configname);
- continue;
- }
-
- if (strcmp(dot, ".conf")) {
- free(configname);
- continue;
- }
ret = stat(configname, &s);
- if (ret) {
- free(configname);
- continue;
- }
-
- if (!S_ISREG(s.st_mode)) {
- free(configname);
- continue;
- }
-
- if (blspec_have_entry(bootentries, configname)) {
- free(configname);
- continue;
- }
-
- entry = blspec_entry_open(bootentries, configname);
- if (IS_ERR(entry)) {
- free(configname);
- continue;
- }
-
- entry->rootpath = xstrdup(root);
- entry->configpath = configname;
- entry->cdev = get_cdev_by_mountpath(root);
-
- if (!entry_is_of_compatible(entry)) {
- blspec_entry_free(&entry->entry);
- continue;
- }
-
- if (!entry_is_match_machine_id(entry)) {
- blspec_entry_free(&entry->entry);
+ if (ret || !S_ISREG(s.st_mode))
continue;
- }
-
- found++;
-
- if (entry->cdev && entry->cdev->dev) {
- devname = xstrdup(dev_name(entry->cdev->dev));
- if (entry->cdev->dev->parent)
- hwdevname = xstrdup(dev_name(entry->cdev->dev->parent));
- }
-
- entry->entry.title = xasprintf("%s (%s)", blspec_entry_var_get(entry, "title"),
- configname);
- entry->entry.description = basprintf("blspec entry, device: %s hwdevice: %s",
- devname ? devname : "none",
- hwdevname ? hwdevname : "none");
- free(devname);
- free(hwdevname);
-
- entry->entry.me.type = MENU_ENTRY_NORMAL;
- entry->entry.release = blspec_entry_free;
- bootentries_add_entry(bootentries, &entry->entry);
+ ret = blspec_scan_file(bootentries, root, configname);
+ if (ret > 0)
+ found += ret;
}
ret = found;
- closedir(dir);
+ globfree(&globb);
err_out:
- if (!IS_ERR(nfspath))
- free(nfspath);
free(abspath);
return ret;
@@ -839,6 +814,7 @@ int blspec_scan_devicename(struct bootentries *bootentries, const char *devname)
static int blspec_bootentry_provider(struct bootentries *bootentries,
const char *name)
{
+ struct stat s;
int ret, found = 0;
ret = blspec_scan_devicename(bootentries, name);
@@ -846,9 +822,24 @@ static int blspec_bootentry_provider(struct bootentries *bootentries,
found += ret;
if (*name == '/' || !strncmp(name, "nfs://", 6)) {
- ret = blspec_scan_directory(bootentries, name);
+ char *nfspath = parse_nfs_url(name);
+
+ if (!IS_ERR(nfspath))
+ name = nfspath;
+
+ ret = stat(name, &s);
+ if (ret)
+ return found;
+
+ if (S_ISDIR(s.st_mode))
+ ret = blspec_scan_directory(bootentries, name);
+ else if (S_ISREG(s.st_mode) && strends(name, ".conf"))
+ ret = blspec_scan_file(bootentries, NULL, name);
if (ret > 0)
found += ret;
+
+ if (!IS_ERR(nfspath))
+ free(nfspath);
}
return found;
diff --git a/common/boot.c b/common/boot.c
index 8220b8d3fb..9c6fc30442 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -272,6 +272,7 @@ int bootentry_register_provider(int (*fn)(struct bootentries *bootentries, const
* name can be:
* - a name of a boot script under /env/boot
* - a full path of a boot script
+ * - a full path of a bootloader spec entry
* - a device name
* - a cdev name
* - a full path of a directory containing bootloader spec entries
@@ -313,10 +314,12 @@ int bootentry_create_from_name(struct bootentries *bootentries,
/*
* bootsources_menu - show a menu from an array of names
*/
-void bootsources_menu(struct bootentries *bootentries, int timeout)
+void bootsources_menu(struct bootentries *bootentries,
+ unsigned default_entry, int timeout)
{
struct bootentry *entry;
struct menu_entry *back_entry;
+ int i = 1;
if (!IS_ENABLED(CONFIG_MENU)) {
pr_warn("no menu support available\n");
@@ -328,6 +331,9 @@ void bootsources_menu(struct bootentries *bootentries, int timeout)
entry->me.display = xstrdup(entry->title);
entry->me.action = bootsource_action;
menu_add_entry(bootentries->menu, &entry->me);
+
+ if (i++ == default_entry)
+ bootentries->menu->selected = &entry->me;
}
back_entry = xzalloc(sizeof(*back_entry));
@@ -336,6 +342,9 @@ void bootsources_menu(struct bootentries *bootentries, int timeout)
back_entry->non_re_ent = 1;
menu_add_entry(bootentries->menu, back_entry);
+ if (i == default_entry)
+ bootentries->menu->selected = back_entry;
+
if (timeout >= 0)
bootentries->menu->auto_select = timeout;
diff --git a/common/booti.c b/common/booti.c
index dde1605fe1..302d7440ab 100644
--- a/common/booti.c
+++ b/common/booti.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: 2018 Sascha Hauer <s.hauer@pengutronix.de>
+#define pr_fmt(fmt) "booti: " fmt
+
#include <common.h>
#include <memory.h>
#include <bootm.h>
@@ -40,6 +42,11 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
image_size = le64_to_cpup(kernel_header + 16);
kernel = get_kernel_address(data->os_address, text_offset);
+
+ print_hex_dump_bytes("header ", DUMP_PREFIX_OFFSET,
+ kernel_header, 80);
+ pr_debug("Kernel to be loaded to %lx+%lx\n", kernel, image_size);
+
if (kernel == UIMAGE_INVALID_ADDRESS)
return ERR_PTR(-ENOENT);
diff --git a/common/bootm.c b/common/bootm.c
index 712e6ebe49..c0f7bca6ce 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -461,7 +461,7 @@ int bootm_load_devicetree(struct image_data *data, void *fdt,
of_print_cmdline(data->of_root_node);
if (bootm_verbose(data) > 1)
- of_print_nodes(data->of_root_node, 0);
+ of_print_nodes(data->of_root_node, 0, ~0);
return 0;
}
@@ -725,7 +725,10 @@ int bootm_boot(struct bootm_data *bootm_data)
} else {
rootarg = path_get_linux_rootarg(data->os_file);
}
- if (!IS_ERR(rootarg)) {
+
+ if (IS_ERR(rootarg)) {
+ pr_err("Failed to append kernel cmdline parameter 'root='\n");
+ } else {
pr_info("Adding \"%s\" to Kernel commandline\n", rootarg);
globalvar_add_simple("linux.bootargs.bootm.appendroot",
rootarg);
diff --git a/common/image-fit.c b/common/image-fit.c
index a410632d70..3e6e7fbd6d 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -21,6 +21,7 @@
#include <linux/err.h>
#include <stringlist.h>
#include <rsa.h>
+#include <uncompress.h>
#include <image-fit.h>
#define FDT_MAX_DEPTH 32
@@ -559,6 +560,11 @@ int fit_get_image_address(struct fit_handle *handle, void *configuration,
return ret;
}
+static void fit_uncompress_error_fn(char *x)
+{
+ pr_err("%s\n", x);
+}
+
/**
* fit_open_image - Open an image in a FIT image
* @handle: The FIT image handle
@@ -581,7 +587,8 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
unsigned long *outsize)
{
struct device_node *image;
- const char *unit = name, *type = NULL, *desc= "(no description)";
+ const char *unit = name, *type = NULL, *compression = NULL,
+ *desc= "(no description)";
const void *data;
int data_len;
int ret = 0;
@@ -613,6 +620,29 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
if (ret < 0)
return ret;
+ of_property_read_string(image, "compression", &compression);
+ if (compression && strcmp(compression, "none") != 0) {
+ void *uc_data;
+
+ if (!IS_ENABLED(CONFIG_UNCOMPRESS)) {
+ pr_err("image has compression = \"%s\", but support not compiled in\n",
+ compression);
+ return -ENOSYS;
+ }
+
+ data_len = uncompress_buf_to_buf(data, data_len, &uc_data,
+ fit_uncompress_error_fn);
+ if (data_len < 0) {
+ pr_err("data couldn't be decompressed\n");
+ return data_len;
+ }
+
+ data = uc_data;
+
+ /* associate buffer with FIT, so it's not leaked */
+ __of_new_property(image, "uncompressed-data", uc_data, data_len);
+ }
+
*outdata = data;
*outsize = data_len;
@@ -641,7 +671,7 @@ static int fit_config_verify_signature(struct fit_handle *handle, struct device_
for_each_child_of_node(conf_node, sig_node) {
if (handle->verbose)
- of_print_nodes(sig_node, 0);
+ of_print_nodes(sig_node, 0, ~0);
ret = fit_verify_signature(sig_node, handle->fit);
if (ret < 0)
return ret;