diff mbox series

bootloader: support for alternative U-Boot library

Message ID 20190305090450.17655-1-sbabic@denx.de
State Accepted
Headers show
Series bootloader: support for alternative U-Boot library | expand

Commit Message

Stefano Babic March 5, 2019, 9:04 a.m. UTC
Support for U-Boot is done with a libubootenv library generated by the
u-boot-fw-tools package in OE. This library is taken from U-Boot code, but it
must be generaded with the exact U-Boot machine as the bootloader. In
case of mismatch, the environment gets corrupted.

A new library is thought to overcome to these issues and to be more
independent from U-Boot source code. Plan is to have a generic interface
to the environment. Improvements for security are also planned, as
introducing signed environments.

Signed-off-by: Stefano Babic <sbabic@denx.de>
---
 bootloader/Config.in | 22 ++++++++++--
 bootloader/uboot.c   | 81 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/bootloader/Config.in b/bootloader/Config.in
index c71a143..dfcc65e 100644
--- a/bootloader/Config.in
+++ b/bootloader/Config.in
@@ -23,9 +23,6 @@  config UBOOT
 	  Support for U-Boot
 	  https://www.denx.de/wiki/U-Boot
 
-comment "U-Boot support needs libubootenv, libz"
-	depends on !HAVE_LIBUBOOTENV || !HAVE_ZLIB
-
 config BOOTLOADER_NONE
 	bool "Environment in RAM"
 	help
@@ -49,6 +46,25 @@  config UBOOT_FWENV
 	  in the tools directory. It tells where the U-Boot
 	  environment is saved.
 
+config UBOOT_NEWAPI
+	bool "Link to new libubootenv API (LGPL-2.1)"
+	depends on UBOOT
+	help
+	  Use a replacement of tools/env from U-Boot
+	  This is to link to libubootenv
+
+comment "U-Boot support needs libubootenv, libz"
+	depends on !HAVE_LIBUBOOTENV || !HAVE_ZLIB
+
+config UBOOT_DEFAULTENV
+	string "U-Boot Initial Environment file"
+	depends on UBOOT_NEWAPI
+	default "/etc/u-boot-initial-env"
+	help
+	  This is the file with the initial environment delivered
+	  with the bootloader. It is used by SWUpdate if no environment
+	  is found on the storage.
+
 config GRUBENV_PATH
 	string "GRUB Environment block file path"
 	depends on BOOTLOADER_GRUB
diff --git a/bootloader/uboot.c b/bootloader/uboot.c
index ff0b11b..4fb8844 100644
--- a/bootloader/uboot.c
+++ b/bootloader/uboot.c
@@ -20,6 +20,7 @@ 
 #include "util.h"
 #include "bootloader.h"
 
+#if !defined(CONFIG_UBOOT_NEWAPI)
 struct env_opts *fw_env_opts = &(struct env_opts) {
 	.config_file = (char *)CONFIG_UBOOT_FWENV
 };
@@ -123,3 +124,83 @@  int bootloader_apply_list(const char *filename)
 	
 	return ret;
 }
+#else
+#include <libuboot.h>
+#ifndef CONFIG_UBOOT_DEFAULTENV
+#define CONFIG_UBOOT_DEFAULTENV	"/etc/u-boot-initial-env"
+#endif
+
+static int bootloader_initialize(struct uboot_ctx *ctx)
+{
+	if (libuboot_initialize(&ctx, NULL) < 0) {
+		ERROR("Error: environment not initialized");
+		return -ENODEV;
+	}
+	if (libuboot_read_config(ctx, CONFIG_UBOOT_FWENV) < 0) {
+		ERROR("Configuration file %s wrong or corrupted", CONFIG_UBOOT_FWENV);
+		return -EINVAL;
+	}
+	if (libuboot_open(ctx) < 0) {
+		ERROR("Cannot read environment, using default\n");
+		libuboot_load_file(ctx, CONFIG_UBOOT_DEFAULTENV);
+	}
+
+	return 0;
+}
+
+int bootloader_env_set(const char *name, const char *value)
+{
+	int ret;
+	struct uboot_ctx *ctx = NULL;
+
+	ret = bootloader_initialize(ctx);
+	if (!ret) {
+		libuboot_set_env(ctx, name, value);
+		ret = libuboot_env_store(ctx);
+	}
+
+	libuboot_close(ctx);
+	libuboot_exit(ctx);
+
+	return ret;
+}
+
+int bootloader_env_unset(const char *name)
+{
+	return bootloader_env_set(name, "");
+}
+
+
+int bootloader_apply_list(const char *filename)
+{
+	int ret;
+	struct uboot_ctx *ctx = NULL;
+
+	ret = bootloader_initialize(ctx);
+	if (!ret) {
+		libuboot_load_file(ctx, filename);
+		ret = libuboot_env_store(ctx);
+	}
+
+	libuboot_close(ctx);
+	libuboot_exit(ctx);
+
+	return ret;
+}
+
+char *bootloader_env_get(const char *name)
+{
+	int ret;
+	struct uboot_ctx *ctx = NULL;
+	char *value = NULL;
+
+	ret = bootloader_initialize(ctx);
+	if (!ret) {
+		value = libuboot_get_env(ctx, name);
+	}
+	libuboot_close(ctx);
+	libuboot_exit(ctx);
+
+	return value;
+}
+#endif