summaryrefslogtreecommitdiffstats
path: root/defaultenv
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-02-18 10:25:13 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2014-02-28 08:14:14 +0100
commit7fa10256c3f4b38f9ca899c5367584380c017bea (patch)
treed1c5654947c4d8305d66646aa35656c8611bd16d /defaultenv
parentb850dbad6557c4cd0e03c9b83be88579412cdd3f (diff)
downloadbarebox-7fa10256c3f4b38f9ca899c5367584380c017bea.tar.gz
defaultenv: Allow multiple defaultenvironment overlays
We can compile barebox for multiple boards at once, but currently they all share a single default environment. This patch adds a defaultenv_append() which boards can call to customize the default environment during runtime. Each board now generate default environment snippets using bbenv-y and add them during runtime with defaultenv_append() Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'defaultenv')
-rw-r--r--defaultenv/Makefile23
-rw-r--r--defaultenv/defaultenv.c149
2 files changed, 172 insertions, 0 deletions
diff --git a/defaultenv/Makefile b/defaultenv/Makefile
new file mode 100644
index 0000000..d449e02
--- /dev/null
+++ b/defaultenv/Makefile
@@ -0,0 +1,23 @@
+bbenv-$(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW) += defaultenv-2-base
+bbenv-$(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_MENU) += defaultenv-2-menu
+bbenv-$(CONFIG_DEFAULT_ENVIRONMENT_GENERIC) += defaultenv-1
+obj-$(CONFIG_DEFAULT_ENVIRONMENT) += defaultenv.o
+extra-y += barebox_default_env barebox_default_env.h barebox_default_env$(DEFAULT_COMPRESSION_SUFFIX)
+
+$(obj)/defaultenv.o: $(obj)/barebox_default_env.h
+
+#
+# Generate a barebox envfs image.
+#
+quiet_cmd_env_default = ENV $@
+cmd_env_default = ($(srctree)/scripts/genenv $(srctree) $(objtree) $@ $(CONFIG_DEFAULT_ENVIRONMENT_PATH))
+
+$(obj)/barebox_default_env: FORCE
+ $(call cmd,env_default)
+
+quiet_cmd_env_h = ENVH $@
+cmd_env_h = cat $< | (cd $(obj) && $(objtree)/scripts/bin2c "__aligned(4) default_environment") > $@; \
+ echo "static const int default_environment_uncompress_size=`stat -c%s $(obj)/barebox_default_env`;" >> $@
+
+$(obj)/barebox_default_env.h: $(obj)/barebox_default_env$(DEFAULT_COMPRESSION_SUFFIX) FORCE
+ $(call if_changed,env_h)
diff --git a/defaultenv/defaultenv.c b/defaultenv/defaultenv.c
new file mode 100644
index 0000000..3f517b4
--- /dev/null
+++ b/defaultenv/defaultenv.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2014 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <envfs.h>
+#include <filetype.h>
+#include <uncompress.h>
+#include <malloc.h>
+#include <init.h>
+#include <asm/unaligned.h>
+#include "barebox_default_env.h"
+
+static LIST_HEAD(defaultenv_list);
+
+struct defaultenv {
+ struct list_head list;
+ const char *name;
+ void *buf;
+ size_t size;
+};
+
+static void defaultenv_add_base(void)
+{
+ static int base_added;
+
+ if (base_added)
+ return;
+
+ base_added = 1;
+
+ if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW))
+ defaultenv_append_directory(defaultenv_2_base);
+ if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_MENU))
+ defaultenv_append_directory(defaultenv_2_menu);
+ if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC))
+ defaultenv_append_directory(defaultenv_1);
+
+ /*
+ * The traditional environment given with CONFIG_DEFAULT_ENVIRONMENT_PATH.
+ * Once all users are converted to bbenv-y this can go.
+ */
+ defaultenv_append((void *)default_environment,
+ default_environment_size, "defaultenv");
+}
+
+/*
+ * defaultenv_append - append a envfs buffer to the default environment
+ * @buf: The buffer containing the binary environment. If it is
+ * not a plain buffer it is assumed to be a compressed buffer.
+ * @size: The length of the buffer
+ *
+ * This adds an overlay to the default environment. New files will be created,
+ * existing files will be overwritten with the overlay.
+ */
+void defaultenv_append(void *buf, unsigned int size, const char *name)
+{
+ struct defaultenv *df;
+
+ defaultenv_add_base();
+
+ df = xzalloc(sizeof(*df));
+ df->buf = buf;
+ df->size = size;
+ df->name = name;
+
+ list_add_tail(&df->list, &defaultenv_list);
+}
+
+static int defaultenv_load_one(struct defaultenv *df, const char *dir,
+ unsigned flags)
+{
+ void *freep = NULL;
+ void *buf;
+ enum filetype ft = file_detect_type(df->buf, df->size);
+ uint32_t size;
+ int ret;
+
+ pr_debug("loading %s\n", df->name);
+
+ if (!IS_ENABLED(CONFIG_DEFAULT_COMPRESSION_NONE) &&
+ ft != filetype_barebox_env) {
+ size = get_unaligned_le32(df->buf + df->size - 4);
+ freep = malloc(size);
+ if (!freep)
+ return -ENOMEM;
+
+ ret = uncompress(df->buf, df->size,
+ NULL, NULL,
+ freep, NULL, uncompress_err_stdout);
+ if (ret) {
+ free(freep);
+ pr_err("Failed to uncompress: %s\n", strerror(-ret));
+ return ret;
+ }
+
+ buf = freep;
+ } else {
+ buf = df->buf;
+ size = df->size;
+ }
+
+ ret = envfs_load_from_buf(buf, size, dir, flags);
+
+ free(freep);
+
+ if (ret)
+ pr_err("Failed to load defaultenv: %s\n", strerror(-ret));
+
+ return ret;
+}
+
+/*
+ * defaultenv_load - load the default environment
+ * @dir: The directory the default environment should be loaded to.
+ *
+ * This loads all environment snippets previously registered with
+ * defaultenv_append to the directory given with @dir.
+ *
+ * Return: 0 for success, negative error code otherwise.
+ */
+int defaultenv_load(const char *dir, unsigned flags)
+{
+ struct defaultenv *df;
+ int ret;
+
+ defaultenv_add_base();
+
+ list_for_each_entry(df, &defaultenv_list, list) {
+ ret = defaultenv_load_one(df, dir, flags);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}