summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2020-08-12 15:25:15 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-08-14 15:21:30 +0200
commit8666aae1db002d500ca1a9ec2cfdd7155ab0494b (patch)
treebb5763f45c244d28b7fb7af87ad367773865bb36
parent2a71a57e7932a2439530087864cd39f2f2f084aa (diff)
downloadbarebox-8666aae1db002d500ca1a9ec2cfdd7155ab0494b.tar.gz
barebox-8666aae1db002d500ca1a9ec2cfdd7155ab0494b.tar.xz
FIT: Parse `load` and `entry` addresses.
According to the U-Boot documentation for the FIT file format, the load and entry have to be allways defined for a "kernel" or "standalone". But Barebox ignored the parameters. That changes with this patch. For backward compatibility the default values for load or entry are still used if they are not given by the FIT file. Signed-off-by: Christian Mauderer <christian.mauderer@embedded-brains.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--common/bootm.c29
-rw-r--r--common/image-fit.c91
-rw-r--r--include/image-fit.h3
3 files changed, 107 insertions, 16 deletions
diff --git a/common/bootm.c b/common/bootm.c
index bea73fac36..7f22ca5ced 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->os_entry = 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");
@@ -638,6 +639,7 @@ int bootm_boot(struct bootm_data *bootm_data)
if (IS_ENABLED(CONFIG_FITIMAGE) && os_type == filetype_oftree) {
struct fit_handle *fit;
+ static const char *kernel_img = "kernel";
fit = fit_open(data->os_file, data->verbose, data->verify);
if (IS_ERR(fit)) {
@@ -658,10 +660,33 @@ int bootm_boot(struct bootm_data *bootm_data)
goto err_out;
}
- ret = fit_open_image(data->os_fit, data->fit_config, "kernel",
+ ret = fit_open_image(data->os_fit, data->fit_config, kernel_img,
&data->fit_kernel, &data->fit_kernel_size);
if (ret)
goto err_out;
+ if (data->os_address == UIMAGE_SOME_ADDRESS) {
+ ret = fit_get_image_address(data->os_fit,
+ data->fit_config,
+ kernel_img,
+ "load", &data->os_address);
+ if (!ret)
+ printf("Load address from FIT '%s': 0x%lx\n",
+ kernel_img, data->os_address);
+ /* Note: Error case uses default value. */
+ }
+ if (data->os_entry == UIMAGE_SOME_ADDRESS) {
+ unsigned long entry;
+ ret = fit_get_image_address(data->os_fit,
+ data->fit_config,
+ kernel_img,
+ "entry", &entry);
+ if (!ret) {
+ data->os_entry = entry - data->os_address;
+ printf("Entry address from FIT '%s': 0x%lx\n",
+ kernel_img, entry);
+ }
+ /* Note: Error case uses default value. */
+ }
}
if (os_type == filetype_uimage) {
@@ -719,6 +744,8 @@ int bootm_boot(struct bootm_data *bootm_data)
if (data->os_address == UIMAGE_SOME_ADDRESS)
data->os_address = UIMAGE_INVALID_ADDRESS;
+ if (data->os_entry == UIMAGE_SOME_ADDRESS)
+ data->os_entry = 0;
handler = bootm_find_handler(os_type, data);
if (!handler) {
diff --git a/common/image-fit.c b/common/image-fit.c
index 2681d62a9a..658f09b04d 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -517,6 +517,77 @@ int fit_has_image(struct fit_handle *handle, void *configuration,
return 1;
}
+static int fit_get_address(struct device_node *image, const char *property,
+ unsigned long *addr)
+{
+ const __be32 *cell;
+ int len = 0;
+
+ cell = of_get_property(image, property, &len);
+ if (!cell)
+ return -EINVAL;
+ if (len > sizeof(*addr))
+ return -ENOTSUPP;
+
+ *addr = (unsigned long)of_read_number(cell, len / sizeof(*cell));
+ return 0;
+}
+
+static int
+fit_get_image(struct fit_handle *handle, void *configuration,
+ const char **unit, struct device_node **image)
+{
+ struct device_node *conf_node = configuration;
+
+ if (conf_node) {
+ if (of_property_read_string(conf_node, *unit, unit)) {
+ pr_err("No image named '%s'\n", *unit);
+ return -ENOENT;
+ }
+ }
+
+ *image = of_get_child_by_name(handle->images, *unit);
+ if (!*image)
+ return -ENOENT;
+
+ return 0;
+}
+
+/**
+ * fit_get_image_address - Get an address from an image in a FIT image
+ * @handle: The FIT image handle
+ * @name: The name of the image to open
+ * @property: The name of the address to get (for example "load" or "entry")
+ * @address: The address given by the image
+ *
+ * Try to parse the @property in the image @name as an address. @configuration
+ * holds the cookie returned from fit_open_configuration() if the image is
+ * opened as part of a configuration, or NULL if the image is opened without a
+ * configuration. If it exists the value will be returned in @address. Otherwise
+ * @address won't be changed.
+ *
+ * Return: 0 for success, negative error code otherwise
+ */
+int fit_get_image_address(struct fit_handle *handle, void *configuration,
+ const char *name, const char *property,
+ unsigned long *address)
+{
+ struct device_node *image;
+ const char *unit = name;
+ int ret;
+
+ if (!address || !property || !name)
+ return -EINVAL;
+
+ ret = fit_get_image(handle, configuration, &unit, &image);
+ if (ret)
+ return ret;
+
+ ret = fit_get_address(image, property, address);
+
+ return ret;
+}
+
/**
* fit_open_image - Open an image in a FIT image
* @handle: The FIT image handle
@@ -539,24 +610,14 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
unsigned long *outsize)
{
struct device_node *image;
- const char *unit, *type = NULL, *desc= "(no description)";
+ const char *unit = name, *type = NULL, *desc= "(no description)";
const void *data;
int data_len;
int ret = 0;
- struct device_node *conf_node = configuration;
-
- if (conf_node) {
- if (of_property_read_string(conf_node, name, &unit)) {
- pr_err("No image named '%s'\n", name);
- return -ENOENT;
- }
- } else {
- unit = name;
- }
- image = of_get_child_by_name(handle->images, unit);
- if (!image)
- return -ENOENT;
+ ret = fit_get_image(handle, configuration, &unit, &image);
+ if (ret)
+ return ret;
of_property_read_string(image, "description", &desc);
pr_info("image '%s': '%s'\n", unit, desc);
@@ -573,7 +634,7 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
return -EINVAL;
}
- if (conf_node)
+ if (configuration)
ret = fit_verify_hash(handle, image, data, data_len);
else
ret = fit_image_verify_signature(handle, image, data, data_len);
diff --git a/include/image-fit.h b/include/image-fit.h
index 27c9e83519..f21545988e 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -32,6 +32,9 @@ int fit_has_image(struct fit_handle *handle, void *configuration,
int fit_open_image(struct fit_handle *handle, void *configuration,
const char *name, const void **outdata,
unsigned long *outsize);
+int fit_get_image_address(struct fit_handle *handle, void *configuration,
+ const char *name, const char *property,
+ unsigned long *address);
void fit_close(struct fit_handle *handle);