summaryrefslogtreecommitdiffstats
path: root/common/bootm.c
diff options
context:
space:
mode:
authorJan Luebbe <jlu@pengutronix.de>2016-01-06 18:01:31 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2016-01-26 22:45:42 +0100
commitac55adb3217cf52aec7f26e6b1614b05c9c83605 (patch)
tree884a1abd2421b826544d5322cd8fa9492e753a31 /common/bootm.c
parentebb1160cddbd58831cc8347dba94f208a0cb8500 (diff)
downloadbarebox-ac55adb3217cf52aec7f26e6b1614b05c9c83605.tar.gz
barebox-ac55adb3217cf52aec7f26e6b1614b05c9c83605.tar.xz
bootm: add initial FIT support
This implementation is inspired by U-Boot's FIT support. Instead of using libfdt (which does not exist in barebox), configuration signatures are verified by using a simplified DT parser based on barebox's own code. Currently, only signed configurations with hashed images are supported, as the other variants are less useful for verified boot. Compatible FIT images can be created using U-Boot's mkimage tool. Signed-off-by: Jan Luebbe <jlu@pengutronix.de> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/bootm.c')
-rw-r--r--common/bootm.c53
1 files changed, 50 insertions, 3 deletions
diff --git a/common/bootm.c b/common/bootm.c
index 78a6bb552d..d8acff8dda 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -17,6 +17,7 @@
#include <malloc.h>
#include <memory.h>
#include <libfile.h>
+#include <image-fit.h>
#include <globalvar.h>
#include <init.h>
#include <linux/stat.h>
@@ -92,6 +93,17 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
if (load_address == UIMAGE_INVALID_ADDRESS)
return -EINVAL;
+ if (data->os_fit) {
+ data->os_res = request_sdram_region("kernel",
+ load_address,
+ data->os_fit->kernel_size);
+ if (!data->os_res)
+ return -ENOMEM;
+ memcpy((void *)load_address, data->os_fit->kernel,
+ data->os_fit->kernel_size);
+ return 0;
+ }
+
if (data->os) {
int num;
@@ -121,6 +133,9 @@ bool bootm_has_initrd(struct image_data *data)
if (!IS_ENABLED(CONFIG_CMD_BOOTM_INITRD))
return false;
+ if (data->os_fit && data->os_fit->initrd)
+ return true;
+
if (data->initrd_file)
return true;
@@ -178,6 +193,18 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address)
if (data->initrd_res)
return 0;
+ if (data->os_fit && data->os_fit->initrd) {
+ data->initrd_res = request_sdram_region("initrd",
+ load_address,
+ data->os_fit->initrd_size);
+ if (!data->initrd_res)
+ return -ENOMEM;
+ memcpy((void *)load_address, data->os_fit->initrd,
+ data->os_fit->initrd_size);
+ printf("Loaded initrd from FIT image\n");
+ goto done1;
+ }
+
type = file_name_detect_type(data->initrd_file);
if ((int)type < 0) {
@@ -216,7 +243,7 @@ done:
if (type == filetype_uimage && data->initrd->header.ih_type == IH_TYPE_MULTI)
printf(", multifile image %s", data->initrd_part);
printf("\n");
-
+done1:
printf("initrd is at " PRINTF_CONVERSION_RESOURCE "-" PRINTF_CONVERSION_RESOURCE "\n",
data->initrd_res->start,
data->initrd_res->end);
@@ -289,7 +316,9 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
if (!IS_ENABLED(CONFIG_OFTREE))
return 0;
- if (data->oftree_file) {
+ if (data->os_fit && data->os_fit->oftree) {
+ data->of_root_node = of_unflatten_dtb(data->os_fit->oftree);
+ } else if (data->oftree_file) {
size_t size;
type = file_name_detect_type(data->oftree_file);
@@ -376,6 +405,8 @@ int bootm_get_os_size(struct image_data *data)
if (data->os)
return uimage_get_size(data->os,
simple_strtoul(data->os_part, NULL, 0));
+ if (data->os_fit)
+ return data->os_fit->kernel_size;
if (data->os_file) {
struct stat s;
@@ -495,10 +526,24 @@ int bootm_boot(struct bootm_data *bootm_data)
goto err_out;
}
+ if (IS_ENABLED(CONFIG_FITIMAGE) && os_type == filetype_oftree) {
+ struct fit_handle *fit;
+
+ fit = fit_open(data->os_file, data->os_part, data->verbose, data->verify);
+ if (IS_ERR(fit)) {
+ printf("Loading FIT image %s failed with: %s\n", data->os_file,
+ strerrorp(fit));
+ ret = PTR_ERR(fit);
+ goto err_out;
+ }
+
+ data->os_fit = fit;
+ }
+
if (os_type == filetype_uimage) {
ret = bootm_open_os_uimage(data);
if (ret) {
- printf("Loading OS image failed with %s\n",
+ printf("Loading OS image failed with: %s\n",
strerror(-ret));
goto err_out;
}
@@ -544,6 +589,8 @@ err_out:
uimage_close(data->initrd);
if (data->os)
uimage_close(data->os);
+ if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit)
+ fit_close(data->os_fit);
if (data->of_root_node && data->of_root_node != of_get_root_node())
of_delete_node(data->of_root_node);